App/Sources/Intents/OpenIntents.swift
72 lines · 2499 bytes
1import Answers
2import AppIntents
3import Library
4
5/// Opens a Library page; used when a page is tapped in Spotlight. Not marked `.system.open`: that schema
6/// needs iOS 27, and a second, iOS 27-only OpenIntent for the same entity is rejected at build time.
7struct OpenLibraryPageIntent: OpenIntent {
8 static let title: LocalizedStringResource = "Open Library Page"
9 static let supportedModes: IntentModes = .foreground(.immediate)
10
11 @Parameter(title: "Page")
12 var target: LibraryPageEntity
13
14 @MainActor
15 func perform() async throws -> some IntentResult {
16 Router.shared.libraryPage = target.page
17 return .result()
18 }
19}
20
21/// Turns the Sky tab to an object; pages with no place in the sky (deep sky, missions) open instead.
22struct ShowInSkyIntent: AppIntent {
23 static let title: LocalizedStringResource = "Show in Sky"
24 static let description = IntentDescription("Turns the Sky tab to the Moon, a planet, a constellation or a bright star.")
25 static let supportedModes: IntentModes = .foreground(.immediate)
26
27 @Parameter(title: "Object", requestValueDialog: "Which object?")
28 var target: LibraryPageEntity
29
30 @MainActor
31 func perform() async throws -> some IntentResult {
32 if let t = target.page.skyTarget {
33 Router.shared.tab = "sky"
34 Router.shared.skyTarget = t
35 } else {
36 Router.shared.libraryPage = target.page
37 }
38 return .result()
39 }
40}
41
42struct SearchLibraryIntent: AppIntent {
43 static let title: LocalizedStringResource = "Search the Library"
44 static let description = IntentDescription("Opens the Library with results for a search.")
45 static let supportedModes: IntentModes = .foreground(.immediate)
46
47 @Parameter(title: "Search", requestValueDialog: "What would you like to look for?")
48 var query: String
49
50 @MainActor
51 func perform() async throws -> some IntentResult {
52 Router.shared.tab = "library"
53 Router.shared.libraryQuery = query
54 return .result()
55 }
56}
57
58/// "Search Moonrise for Cassini" in Siri's own words, without a fixed phrase.
59@available(iOS 27, *)
60@AppIntent(schema: .system.searchInApp)
61struct SearchLibrarySchemaIntent {
62 static let searchScopes: [StringSearchScope] = [.general]
63
64 var criteria: StringSearchCriteria
65
66 @MainActor
67 func perform() async throws -> some IntentResult {
68 Router.shared.tab = "library"
69 Router.shared.libraryQuery = criteria.term
70 return .result()
71 }
72}