1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import Foundation
struct GetLocationsResponse: Codable, Sendable {
var locations: [LocationItem]?
}
/// One place in the explore index.
///
/// `h3Index` is the densest cell in the group and what the location feed is
/// asked for; `h3Cells` is every cell whose galleries fold into this place.
/// Both `h3Cells` and `thumbs` are absent in the `pins` shape, which carries
/// only what a map plots.
struct LocationItem: Codable, Sendable, Identifiable {
let name: String
let h3Index: String
let galleryCount: Int
var h3Cells: [String]?
/// Up to four recent covers, newest first, for an index tile's mosaic.
var thumbs: [String]?
var id: String {
h3Index
}
init(name: String, h3Index: String, galleryCount: Int, h3Cells: [String]? = nil, thumbs: [String]? = nil) {
self.name = name
self.h3Index = h3Index
self.galleryCount = galleryCount
self.h3Cells = h3Cells
self.thumbs = thumbs
}
}
struct GetCamerasResponse: Codable, Sendable {
var cameras: [CameraItem]?
}
/// One camera in the explore index, with up to four recent photos for its tile.
struct CameraItem: Codable, Sendable, Identifiable {
let camera: String
let photoCount: Int
var thumbs: [String]?
var id: String {
camera
}
init(camera: String, photoCount: Int, thumbs: [String]? = nil) {
self.camera = camera
self.photoCount = photoCount
self.thumbs = thumbs
}
}
extension XRPCClient {
/// The top thirty places by gallery count, each with a few thumbnails — or,
/// with `pins`, every place with nothing but a name, a cell and a count.
/// The full shape is about a kilobyte a place, so a map of all of them
/// asks for the lean one.
func getLocations(pins: Bool = false, auth: AuthContext? = nil) async throws -> GetLocationsResponse {
try await query(
"social.grain.gallery.getLocations",
params: pins ? ["pins": "true"] : [:],
auth: auth,
as: GetLocationsResponse.self
)
}
/// The top thirty cameras by photo count, each with a few thumbnails.
func getCameras(auth: AuthContext? = nil) async throws -> GetCamerasResponse {
try await query("social.grain.gallery.getCameras", auth: auth, as: GetCamerasResponse.self)
}
}