39 lines
1.6 KiB
Swift
39 lines
1.6 KiB
Swift
|
|
import Foundation
|
||
|
|
|
||
|
|
/// Persists the last-known playback status per host so the player shows cached
|
||
|
|
/// values immediately on a cold launch — the first live poll can take several
|
||
|
|
/// seconds over a flapping link (the dead-LAN endpoint costs a ConnectTimeout),
|
||
|
|
/// and "Nothing playing" for that window is worse than a slightly-stale state.
|
||
|
|
public enum PlayerStatusCache {
|
||
|
|
public struct Entry: Codable, Sendable, Equatable {
|
||
|
|
public var status: PlaybackStatus
|
||
|
|
public var capturedAt: Date
|
||
|
|
public init(status: PlaybackStatus, capturedAt: Date) {
|
||
|
|
self.status = status; self.capturedAt = capturedAt
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static func url() -> URL {
|
||
|
|
FileManager.default.homeDirectoryForCurrentUser
|
||
|
|
.appendingPathComponent(".local/state/tv-anarchy/player-status.json")
|
||
|
|
}
|
||
|
|
|
||
|
|
public static func load() -> [String: Entry] {
|
||
|
|
guard let data = try? Data(contentsOf: url()) else { return [:] }
|
||
|
|
let dec = JSONDecoder()
|
||
|
|
dec.dateDecodingStrategy = .iso8601
|
||
|
|
return (try? dec.decode([String: Entry].self, from: data)) ?? [:]
|
||
|
|
}
|
||
|
|
|
||
|
|
public static func save(_ map: [String: Entry]) {
|
||
|
|
let u = url()
|
||
|
|
try? FileManager.default.createDirectory(at: u.deletingLastPathComponent(),
|
||
|
|
withIntermediateDirectories: true)
|
||
|
|
let enc = JSONEncoder()
|
||
|
|
enc.dateEncodingStrategy = .iso8601
|
||
|
|
enc.outputFormatting = [.withoutEscapingSlashes]
|
||
|
|
guard let data = try? enc.encode(map) else { return }
|
||
|
|
try? data.write(to: u, options: .atomic)
|
||
|
|
}
|
||
|
|
}
|