From d5a9dad769c9e88dc64e4c485eea62923088be51 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Mon, 10 Aug 2026 17:41:32 +0200 Subject: [PATCH] Answer "signed out" vs "never ran" in one read; make SnapshotTheme constructible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signing out deletes the cached events — keeping them would leak the previous user's calendar to anything reading the container — so an absent cache alone cannot distinguish "signed out" from "Calendarr has never run on this machine". Those need different messages, so read() now falls back to the session record and reports .loggedOut when one exists and says so. Every consumer would otherwise have to reimplement that two-step, and any that forgot would tell a signed-out user to go install an app they already have. SnapshotTheme only had the compiler's internal memberwise initializer, so no consumer outside the package could actually build one. --- Sources/CalendarrCore/Snapshot/SnapshotModels.swift | 6 ++++++ Sources/CalendarrCore/Snapshot/SnapshotStore.swift | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Sources/CalendarrCore/Snapshot/SnapshotModels.swift b/Sources/CalendarrCore/Snapshot/SnapshotModels.swift index 476c1e6..47762cc 100644 --- a/Sources/CalendarrCore/Snapshot/SnapshotModels.swift +++ b/Sources/CalendarrCore/Snapshot/SnapshotModels.swift @@ -79,6 +79,12 @@ public struct SnapshotTheme: Sendable, Hashable { public let line: String public let primary: String public let accent: String + + public init(today: String, text: String, background: String, + line: String, primary: String, accent: String) { + self.today = today; self.text = text; self.background = background + self.line = line; self.primary = primary; self.accent = accent + } } // MARK: - Snapshot diff --git a/Sources/CalendarrCore/Snapshot/SnapshotStore.swift b/Sources/CalendarrCore/Snapshot/SnapshotStore.swift index a9eb339..9c59763 100644 --- a/Sources/CalendarrCore/Snapshot/SnapshotStore.swift +++ b/Sources/CalendarrCore/Snapshot/SnapshotStore.swift @@ -59,7 +59,17 @@ public struct SnapshotStore: Sendable { } let url = container.appendingPathComponent(Self.cacheFilename) - guard FileManager.default.fileExists(atPath: url.path) else { return .neverWritten } + guard FileManager.default.fileExists(atPath: url.path) else { + // No cache. Signing out deletes the events — keeping them would leak + // the previous user's calendar — so the session file is what tells + // "signed out" apart from "never ran here". Answering that in one + // call keeps every consumer from reimplementing the distinction. + if let session = SharedSessionStore(appGroupID: appGroupID).read(), + !session.isLoggedIn { + return .loggedOut(writtenAt: session.writtenAt) + } + return .neverWritten + } let data: Data do { data = try Data(contentsOf: url) }