Files
Calendarr/ios/CalendarrWatch/WatchSnapshotModel.swift
T
ScarriffleandClaude Opus 5 6e981e7aea chore(repo): iOS-App als ios/ ins Hauptrepo uebernehmen
Calendarr-IOS wird mit vollstaendiger Historie als Unterverzeichnis
ios/ eingebunden. Damit liegen Server, Web, Android und iOS in einem
gemeinsamen Repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 09:20:12 +02:00

53 lines
1.7 KiB
Swift

import Foundation
import WidgetKit
import CalendarrCore
/// What the watch views read. Holds the last received snapshot, the calendar
/// list, and this watch's filter.
@MainActor
@Observable
final class WatchSnapshotModel {
private(set) var result: SnapshotReadResult = .neverWritten
private(set) var calendars: [SnapshotCalendar] = []
private(set) var hiddenKeys: Set<String> = WatchFilterStore.load()
private let store = SnapshotStore()
private var changeToken: SnapshotChangeNotifier.ObservationToken?
init() {
reload()
// The receiver writes through SnapshotStore, which broadcasts. Listening
// here means the UI does not have to be notified separately.
changeToken = SnapshotChangeNotifier.observe { [weak self] in
Task { @MainActor in self?.reload() }
}
}
func reload() {
result = store.read()
calendars = store.readCalendars()
}
/// The snapshot with this watch's filter applied, or nil when there is
/// nothing usable to show.
var visible: CalendarrSnapshot? {
result.snapshot?.filtered(excludingCalendarKeys: hiddenKeys)
}
var language: String { result.snapshot?.language ?? "system" }
func isHidden(_ key: String) -> Bool { hiddenKeys.contains(key) }
/// The display name for an event's calendar. Events carry only a
/// `calendarKey`; the names travel separately, in the calendar list.
func calendarName(for key: String) -> String? {
calendars.first { $0.id == key }?.name
}
func setHidden(_ key: String, _ hidden: Bool) {
if hidden { hiddenKeys.insert(key) } else { hiddenKeys.remove(key) }
WatchFilterStore.save(hiddenKeys)
WidgetCenter.shared.reloadAllTimelines()
}
}