All checks were successful
CI / build-and-deploy (push) Successful in 24s
Expose Marks to Siri, Spotlight, and Shortcuts via App Intents: - BookmarkEntity (AppEntity + IndexedEntity, keyed on the Linkding server id) with a server-backed EntityStringQuery for live lookup - Intents: Add, Open (OpenIntent), Search, ShowUnread, and an AI Summarize intent backed by ClaudeService; AppShortcutsProvider with spoken phrases; Siri snippet views and dialog - SearchMarksIntent conforms to the system.search App Schema (@AppIntent(schema:), ShowInAppSearchResultsIntent) so it is executable by conversational Siri / Apple Intelligence - IntentRouter bridges intents (run in the app process) to the SwiftUI scene for open/search navigation; widgets refreshed after adds - Link AppIntents.framework so the metadata processor extracts shortcut phrases and validates the assistant schema Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
1.6 KiB
Swift
54 lines
1.6 KiB
Swift
import SwiftUI
|
|
|
|
/// Compact card Siri shows after saving / opening a bookmark.
|
|
struct BookmarkSnippetView: View {
|
|
let entity: BookmarkEntity
|
|
|
|
var body: some View {
|
|
HStack(spacing: 12) {
|
|
Image(systemName: "bookmark.fill")
|
|
.font(.title2)
|
|
.foregroundStyle(.tint)
|
|
VStack(alignment: .leading, spacing: 3) {
|
|
Text(entity.title)
|
|
.font(.headline)
|
|
.lineLimit(2)
|
|
Text(entity.host)
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
if !entity.tags.isEmpty {
|
|
Text(entity.tags.map { "#\($0)" }.joined(separator: " "))
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
.lineLimit(1)
|
|
}
|
|
}
|
|
Spacer(minLength: 0)
|
|
}
|
|
.padding()
|
|
}
|
|
}
|
|
|
|
/// Card Siri shows for an AI summary result.
|
|
struct SummarySnippetView: View {
|
|
let title: String
|
|
let host: String
|
|
let summary: String
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack(spacing: 8) {
|
|
Image(systemName: "sparkles").foregroundStyle(.tint)
|
|
Text(title).font(.headline).lineLimit(2)
|
|
}
|
|
Text(host)
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
Text(summary)
|
|
.font(.body)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
}
|
|
.padding()
|
|
}
|
|
}
|