init: init proj

This commit is contained in:
2026-02-26 22:15:35 +08:00
commit 7ef5348f65
43 changed files with 3085 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
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
}
}