krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

v3.1.7: Shared/SystemStatusWidgetSnapshot.swift · raw

 1import Foundation
 2#if canImport(WidgetKit)
 3import WidgetKit
 4#endif
 5
 6enum SystemStatusWidgetConfiguration {
 7    static let kind = "SystemStatusWidget"
 8}
 9
10struct SystemStatusWidgetSnapshot: Codable, Sendable {
11    let services: [ServiceEntry]
12    let hasDisruption: Bool
13    let overallStatusText: String
14    let bannerSummary: String
15    let updatedAt: Date
16
17    struct ServiceEntry: Codable, Sendable, Identifiable {
18        let id: String
19        let name: String
20        let status: String
21        let requiresAttention: Bool
22    }
23
24    static let unavailable = SystemStatusWidgetSnapshot(
25        services: [],
26        hasDisruption: false,
27        overallStatusText: "Unavailable",
28        bannerSummary: "",
29        updatedAt: .now
30    )
31}
32
33enum SystemStatusWidgetSnapshotStore {
34    private static let snapshotKey = "systemStatus.widgetSnapshot"
35
36    static func load(
37        accountID: String? = ActiveAccountContextStore.load(),
38        defaults: UserDefaults? = sharedDefaults()
39    ) -> SystemStatusWidgetSnapshot? {
40        guard let defaults,
41              let data = defaults.data(forKey: scopedKey(for: accountID)) else {
42            return nil
43        }
44        return try? JSONDecoder().decode(SystemStatusWidgetSnapshot.self, from: data)
45    }
46
47    static func save(
48        _ snapshot: SystemStatusWidgetSnapshot,
49        accountID: String? = ActiveAccountContextStore.load(),
50        defaults: UserDefaults? = sharedDefaults()
51    ) {
52        guard let defaults,
53              let data = try? JSONEncoder().encode(snapshot) else {
54            return
55        }
56        defaults.set(data, forKey: scopedKey(for: accountID))
57        reloadWidgetTimelines()
58    }
59
60    static func clear(
61        accountID: String? = ActiveAccountContextStore.load(),
62        defaults: UserDefaults? = sharedDefaults()
63    ) {
64        defaults?.removeObject(forKey: scopedKey(for: accountID))
65        reloadWidgetTimelines()
66    }
67
68    private static func sharedDefaults() -> UserDefaults? {
69        UserDefaults(suiteName: HutchAppGroup.identifier)
70    }
71
72    private static func scopedKey(for accountID: String?) -> String {
73        guard let accountID, !accountID.isEmpty else { return snapshotKey }
74        return "\(snapshotKey).\(accountID)"
75    }
76
77    private static func reloadWidgetTimelines() {
78        #if canImport(WidgetKit)
79        WidgetCenter.shared.reloadTimelines(ofKind: SystemStatusWidgetConfiguration.kind)
80        #endif
81    }
82}