Watch: snooze finished threads, name the files a file approval would edit, Settle on finished notifications, an instant launch from the saved feed, plain Loading states, and no more cancelled errors
Gateway: an approval push for a file change says which files it would edit
This commit is contained in:
1 parent
4dc4e57dac
commit
edc4b88990
35 files changed
+1162
-144
No files matched your search
@@ -0,0 +1,49 @@
|
||||
// The last good feed, and the last detail of each thread opened, saved as JSON in the app's caches
|
||||
// folder. Launch shows them at once while the first refresh runs. Signing out clears them, and demo
|
||||
// mode never reads or writes them.
|
||||
|
||||
import Foundation
|
||||
|
||||
struct FeedCache: Sendable {
|
||||
let directory: URL
|
||||
|
||||
static let standard = FeedCache(directory: .cachesDirectory.appending(path: "WristCode", directoryHint: .isDirectory))
|
||||
|
||||
func feed() -> Feed? {
|
||||
read(Feed.self, "feed.json")
|
||||
}
|
||||
|
||||
func save(_ feed: Feed) {
|
||||
write(feed, "feed.json")
|
||||
}
|
||||
|
||||
func thread(hostId: String, threadId: String) -> ThreadDetail? {
|
||||
read(ThreadDetail.self, Self.threadFile(hostId, threadId))
|
||||
}
|
||||
|
||||
func save(_ detail: ThreadDetail) {
|
||||
write(detail, Self.threadFile(detail.item.hostId, detail.item.threadId))
|
||||
}
|
||||
|
||||
/// Deletes everything saved, as when the watch unpairs.
|
||||
func clear() {
|
||||
try? FileManager.default.removeItem(at: directory)
|
||||
}
|
||||
|
||||
/// `thread-<hostId>-<threadId>.json`, with the ids percent-encoded so any id is a safe file name.
|
||||
private static func threadFile(_ hostId: String, _ threadId: String) -> String {
|
||||
let safe = { (id: String) in id.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? id }
|
||||
return "thread-\(safe(hostId))-\(safe(threadId)).json"
|
||||
}
|
||||
|
||||
private func read<Value: Decodable>(_ type: Value.Type, _ name: String) -> Value? {
|
||||
guard let data = try? Data(contentsOf: directory.appending(path: name)) else { return nil }
|
||||
return try? JSON.decoder().decode(type, from: data)
|
||||
}
|
||||
|
||||
private func write(_ value: some Encodable, _ name: String) {
|
||||
guard let data = try? JSON.encoder().encode(value) else { return }
|
||||
try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
||||
try? data.write(to: directory.appending(path: name), options: .atomic)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user