2021-12-26 21:14:46 +00:00
|
|
|
import CoreData
|
|
|
|
import CoreMedia
|
2022-01-02 19:39:19 +00:00
|
|
|
import Defaults
|
2021-12-26 21:14:46 +00:00
|
|
|
import Foundation
|
2022-12-09 00:15:19 +00:00
|
|
|
import Siesta
|
2022-11-10 17:11:28 +00:00
|
|
|
import SwiftyJSON
|
2021-12-26 21:14:46 +00:00
|
|
|
|
|
|
|
extension PlayerModel {
|
|
|
|
func historyVideo(_ id: String) -> Video? {
|
|
|
|
historyVideos.first { $0.videoID == id }
|
|
|
|
}
|
|
|
|
|
2023-05-25 12:28:29 +00:00
|
|
|
func loadHistoryVideoDetails(_ watch: Watch, onCompletion: @escaping () -> Void = {}) {
|
2022-12-09 00:15:19 +00:00
|
|
|
guard historyVideo(watch.videoID).isNil else {
|
2023-05-25 12:28:29 +00:00
|
|
|
onCompletion()
|
2021-12-26 21:14:46 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-12-09 00:15:19 +00:00
|
|
|
if !Video.VideoID.isValid(watch.videoID), let url = URL(string: watch.videoID) {
|
2022-11-10 17:11:28 +00:00
|
|
|
historyVideos.append(.local(url))
|
2023-05-25 12:28:29 +00:00
|
|
|
onCompletion()
|
2022-11-10 17:11:28 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-12-10 00:23:13 +00:00
|
|
|
if let video = VideosCacheModel.shared.retrieveVideo(watch.video.cacheKey) {
|
|
|
|
historyVideos.append(video)
|
2023-05-25 12:28:29 +00:00
|
|
|
onCompletion()
|
2022-12-10 00:23:13 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-12-09 19:33:01 +00:00
|
|
|
guard let api = playerAPI(watch.video) else { return }
|
|
|
|
|
|
|
|
api.video(watch.videoID)
|
|
|
|
.load()
|
2022-11-10 21:51:34 +00:00
|
|
|
.onSuccess { [weak self] response in
|
|
|
|
guard let self else { return }
|
2022-11-10 17:11:28 +00:00
|
|
|
|
2022-11-10 21:51:34 +00:00
|
|
|
if let video: Video = response.typedContent() {
|
2022-12-10 00:23:13 +00:00
|
|
|
VideosCacheModel.shared.storeVideo(video)
|
2022-11-10 21:51:34 +00:00
|
|
|
self.historyVideos.append(video)
|
2023-05-25 12:28:29 +00:00
|
|
|
onCompletion()
|
2022-11-10 21:51:34 +00:00
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
}
|
2022-11-10 21:51:34 +00:00
|
|
|
.onCompletion { _ in
|
2022-12-09 00:15:19 +00:00
|
|
|
self.logger.info("LOADED history details: \(watch.videoID)")
|
2022-11-10 17:11:28 +00:00
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func updateWatch(finished: Bool = false) {
|
2022-12-09 00:15:19 +00:00
|
|
|
guard let currentVideo, saveHistory else { return }
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-12-09 00:15:19 +00:00
|
|
|
let id = currentVideo.videoID
|
2022-02-16 20:23:11 +00:00
|
|
|
let time = backend.currentTime
|
|
|
|
let seconds = time?.seconds ?? 0
|
2022-12-15 21:39:42 +00:00
|
|
|
let duration = playerTime.duration.seconds
|
|
|
|
if seconds < 3 {
|
|
|
|
return
|
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
|
|
|
|
let watchFetchRequest = Watch.fetchRequest()
|
|
|
|
watchFetchRequest.predicate = NSPredicate(format: "videoID = %@", id as String)
|
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
let results = try? backgroundContext.fetch(watchFetchRequest)
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
backgroundContext.perform { [weak self] in
|
2022-12-04 11:07:06 +00:00
|
|
|
guard let self, finished || self.backend.isPlaying else {
|
2021-12-26 21:14:46 +00:00
|
|
|
return
|
|
|
|
}
|
2022-01-02 19:39:19 +00:00
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
let watch: Watch!
|
|
|
|
|
2023-05-25 17:03:59 +00:00
|
|
|
let duration = self.activeBackend == .mpv ? self.playerTime.duration.seconds : self.avPlayerBackend.playerItemDuration?.seconds ?? 0
|
2022-12-12 23:38:26 +00:00
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
if results?.isEmpty ?? true {
|
|
|
|
watch = Watch(context: self.backgroundContext)
|
|
|
|
watch.videoID = id
|
2022-12-09 00:15:19 +00:00
|
|
|
watch.appName = currentVideo.app.rawValue
|
|
|
|
watch.instanceURL = currentVideo.instanceURL
|
2022-06-07 22:15:15 +00:00
|
|
|
} else {
|
|
|
|
watch = results?.first
|
2022-01-02 19:39:19 +00:00
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-12-04 11:07:06 +00:00
|
|
|
if duration.isFinite, duration > 0 {
|
|
|
|
watch.videoDuration = duration
|
2022-06-07 22:15:15 +00:00
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-12-04 11:07:06 +00:00
|
|
|
if watch.finished {
|
|
|
|
if !finished, self.resetWatchedStatusOnPlaying, seconds.isFinite, seconds > 0 {
|
|
|
|
watch.stoppedAt = seconds
|
|
|
|
}
|
|
|
|
} else if seconds.isFinite, seconds > 0 {
|
2022-06-07 22:15:15 +00:00
|
|
|
watch.stoppedAt = seconds
|
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
watch.watchedAt = Date()
|
2021-12-26 21:14:46 +00:00
|
|
|
|
2022-06-07 22:15:15 +00:00
|
|
|
try? self.backgroundContext.save()
|
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
}
|
|
|
|
|
2022-11-15 11:22:27 +00:00
|
|
|
func removeHistory() {
|
|
|
|
removeAllWatches()
|
2022-12-10 20:08:03 +00:00
|
|
|
BookmarksCacheModel.shared.clear()
|
2022-11-15 11:22:27 +00:00
|
|
|
}
|
|
|
|
|
2021-12-26 21:14:46 +00:00
|
|
|
func removeWatch(_ watch: Watch) {
|
2022-12-15 22:51:49 +00:00
|
|
|
context.perform { [weak self] in
|
|
|
|
guard let self else { return }
|
|
|
|
self.context.delete(watch)
|
|
|
|
|
|
|
|
try? self.context.save()
|
2022-12-16 21:22:59 +00:00
|
|
|
|
|
|
|
FeedModel.shared.calculateUnwatchedFeed()
|
2023-05-25 12:28:29 +00:00
|
|
|
WatchModel.shared.watchesChanged()
|
2022-12-15 22:51:49 +00:00
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func removeAllWatches() {
|
|
|
|
let watchesFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Watch")
|
|
|
|
let deleteRequest = NSBatchDeleteRequest(fetchRequest: watchesFetchRequest)
|
2023-05-25 12:28:29 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
try context.executeAndMergeChanges(deleteRequest)
|
|
|
|
try context.save()
|
|
|
|
} catch let error as NSError {
|
|
|
|
logger.info(.init(stringLiteral: error.localizedDescription))
|
|
|
|
}
|
2021-12-26 21:14:46 +00:00
|
|
|
}
|
|
|
|
}
|