Sources/Orgstar/CaptureIntent.swift
50 lines · 2259 bytes
4 symbols in this file
1import AppIntents
2import AppKit
3import OrgApp
4import OrgCore
5
6/// Shortcuts' "Capture to Orgstar": files text with a capture template without the capture
7/// window. Prompts in the template take their defaults.
8struct CaptureIntent: AppIntent {
9 static let title: LocalizedStringResource = "Capture to Orgstar"
10 static let description = IntentDescription("Files text with one of your capture templates.")
11
12 @Parameter(title: "Text")
13 var text: String
14
15 @Parameter(title: "Template Key", description: "A template's key in capture.toml; the first template when empty.")
16 var template: String?
17
18 /// The app's models, once its window is up.
19 @MainActor static var environment: (workspace: WorkspaceModel, session: DocumentSession, clock: ClockModel, commands: AppCommands)?
20
21 struct Failure: Error, CustomLocalizedStringResourceConvertible {
22 let message: String
23 var localizedStringResource: LocalizedStringResource { "\(message)" }
24 }
25
26 @MainActor
27 func perform() async throws -> some IntentResult & ReturnsValue<String> & ProvidesDialog {
28 // Launched for the intent, the window sets the models up shortly.
29 for _ in 0..<50 where Self.environment == nil { try? await Task.sleep(for: .milliseconds(100)) }
30 guard let (workspace, session, clock, commands) = Self.environment else { throw Failure(message: "Orgstar isn't ready") }
31 let placed = session.capture(
32 text, templateKey: template, templates: CaptureTemplates.load().templates, workspace: workspace, clock: clock,
33 clipboard: NSPasteboard.general.string(forType: .string) ?? "", userName: NSFullUserName()
34 )
35 switch placed {
36 case .failure(let error):
37 throw Failure(message: error.message)
38 case .success(let chosen):
39 let message = "Captured to \(CaptureView.target(chosen))"
40 commands.show(message)
41 return .result(value: message, dialog: "\(message)")
42 }
43 }
44}
45
46struct OrgstarShortcuts: AppShortcutsProvider {
47 static var appShortcuts: [AppShortcut] {
48 AppShortcut(intent: CaptureIntent(), phrases: ["Capture to \(.applicationName)"], shortTitle: "Capture", systemImageName: "tray.and.arrow.down")
49 }
50}