yattee/Model/Watch.swift

111 lines
3.0 KiB
Swift
Raw Permalink Normal View History

import CoreData
import CoreMedia
import Defaults
import Foundation
@objc(Watch)
final class Watch: NSManagedObject, Identifiable {
@Default(.watchedThreshold) private var watchedThreshold
@Default(.saveHistory) private var saveHistory
2023-05-23 16:00:33 +00:00
@Default(.showWatchingProgress) private var showWatchingProgress
}
extension Watch {
@nonobjc class func fetchRequest() -> NSFetchRequest<Watch> {
NSFetchRequest<Watch>(entityName: "Watch")
}
2023-04-22 15:59:28 +00:00
@nonobjc class func markAsWatched(videoID: String, account: Account, duration: Double, watchedAt: Date? = nil, context: NSManagedObjectContext) {
let watchFetchRequest = Watch.fetchRequest()
watchFetchRequest.predicate = NSPredicate(format: "videoID = %@", videoID as String)
let results = try? context.fetch(watchFetchRequest)
context.perform {
let watch: Watch?
if results?.isEmpty ?? true {
watch = Watch(context: context)
watch?.videoID = videoID
2022-12-09 00:15:19 +00:00
watch?.appName = account.app?.rawValue
watch?.instanceURL = account.url
} else {
watch = results?.first
}
2022-09-28 14:27:01 +00:00
guard let watch else { return }
watch.videoDuration = duration
watch.stoppedAt = duration
2023-04-22 15:59:28 +00:00
watch.watchedAt = watchedAt ?? .init()
try? context.save()
}
}
@NSManaged var videoID: String
@NSManaged var videoDuration: Double
@NSManaged var watchedAt: Date?
@NSManaged var stoppedAt: Double
2022-12-09 00:15:19 +00:00
@NSManaged var appName: String?
@NSManaged var instanceURL: URL?
2023-04-22 20:13:59 +00:00
var app: VideosApp? {
2022-12-09 00:15:19 +00:00
guard let appName else { return nil }
return .init(rawValue: appName)
}
var progress: Double {
guard videoDuration.isFinite, !videoDuration.isZero else {
2022-12-15 21:39:42 +00:00
return 100
}
let progress = (stoppedAt / videoDuration) * 100
if progress >= Double(watchedThreshold) {
return 100
}
return min(max(progress, 0), 100)
}
var finished: Bool {
guard videoDuration.isFinite, !videoDuration.isZero else {
return true
}
return progress >= Double(watchedThreshold)
}
var watchedAtString: String? {
2022-09-28 14:27:01 +00:00
guard let watchedAt else {
return nil
}
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
return formatter.localizedString(for: watchedAt, relativeTo: Date())
}
var timeToRestart: CMTime? {
finished ? nil : saveHistory ? .secondsInDefaultTimescale(stoppedAt) : nil
}
var video: Video {
2022-12-09 19:33:01 +00:00
let url = URL(string: videoID)
2022-12-10 00:23:13 +00:00
if !Video.VideoID.isValid(videoID) {
2022-12-09 19:33:01 +00:00
if let url {
return .local(url)
}
2022-11-10 17:11:28 +00:00
}
2022-12-16 20:01:01 +00:00
return Video(app: app ?? AccountsModel.shared.current?.app ?? .local, instanceURL: instanceURL, videoID: videoID)
}
2023-05-23 16:00:33 +00:00
var isShowingProgress: Bool {
saveHistory && showWatchingProgress && (finished || progress > 0)
}
}