70 lines
1.9 KiB
Swift
70 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
@Observable
|
|
final class WatchProgressStore {
|
|
static let shared = WatchProgressStore()
|
|
|
|
private let defaults = UserDefaults.standard
|
|
private let progressKey = "ddys_watch_progress"
|
|
|
|
private var progressMap: [String: WatchProgress] {
|
|
get {
|
|
guard let data = defaults.data(forKey: progressKey),
|
|
let map = try? JSONDecoder().decode([String: WatchProgress].self, from: data) else {
|
|
return [:]
|
|
}
|
|
return map
|
|
}
|
|
set {
|
|
if let data = try? JSONEncoder().encode(newValue) {
|
|
defaults.set(data, forKey: progressKey)
|
|
}
|
|
}
|
|
}
|
|
|
|
private init() {}
|
|
|
|
func getProgress(for contentId: String, episodeId: Int = 0) -> WatchProgress? {
|
|
let key = "\(contentId)_\(episodeId)"
|
|
return progressMap[key]
|
|
}
|
|
|
|
func saveProgress(contentId: String, episodeId: Int = 0, currentTime: Double, duration: Double) {
|
|
let key = "\(contentId)_\(episodeId)"
|
|
let progress = WatchProgress(
|
|
contentId: contentId,
|
|
episodeId: episodeId,
|
|
currentTime: currentTime,
|
|
duration: duration,
|
|
lastWatched: Date()
|
|
)
|
|
var map = progressMap
|
|
map[key] = progress
|
|
progressMap = map
|
|
}
|
|
|
|
func clearAll() {
|
|
defaults.removeObject(forKey: progressKey)
|
|
}
|
|
|
|
func recentlyWatched(limit: Int = 20) -> [WatchProgress] {
|
|
progressMap.values
|
|
.sorted { $0.lastWatched > $1.lastWatched }
|
|
.prefix(limit)
|
|
.map { $0 }
|
|
}
|
|
}
|
|
|
|
struct WatchProgress: Codable {
|
|
let contentId: String
|
|
let episodeId: Int
|
|
let currentTime: Double
|
|
let duration: Double
|
|
let lastWatched: Date
|
|
|
|
var percentage: Double {
|
|
guard duration > 0 else { return 0 }
|
|
return currentTime / duration
|
|
}
|
|
}
|