mirror of
https://github.com/tappollo/WWDC.git
synced 2026-04-29 04:15:12 +08:00
Refactored context menu actions, doing updates in background for performance
This commit is contained in:
@@ -39,38 +39,55 @@ public class SessionProgress: Object {
|
||||
extension Session {
|
||||
|
||||
public func setCurrentPosition(_ position: Double, _ duration: Double) {
|
||||
guard Thread.isMainThread else { return }
|
||||
guard let realm = self.realm else { return }
|
||||
|
||||
guard !duration.isNaN, !duration.isZero, !duration.isInfinite else { return }
|
||||
guard !position.isNaN, !position.isZero, !position.isInfinite else { return }
|
||||
|
||||
do {
|
||||
try self.realm?.write {
|
||||
var progress: SessionProgress
|
||||
|
||||
if let p = progresses.first {
|
||||
progress = p
|
||||
} else {
|
||||
progress = SessionProgress()
|
||||
progresses.append(progress)
|
||||
}
|
||||
|
||||
progress.currentPosition = position
|
||||
progress.relativePosition = position / duration
|
||||
progress.updatedAt = Date()
|
||||
let mustCommit: Bool
|
||||
|
||||
if !realm.isInWriteTransaction {
|
||||
realm.beginWrite()
|
||||
mustCommit = true
|
||||
} else {
|
||||
mustCommit = false
|
||||
}
|
||||
|
||||
var progress: SessionProgress
|
||||
|
||||
if let p = progresses.first {
|
||||
progress = p
|
||||
} else {
|
||||
progress = SessionProgress()
|
||||
progresses.append(progress)
|
||||
}
|
||||
|
||||
progress.currentPosition = position
|
||||
progress.relativePosition = position / duration
|
||||
progress.updatedAt = Date()
|
||||
|
||||
if mustCommit { try realm.commitWrite() }
|
||||
} catch {
|
||||
NSLog("Error updating session progress: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
public func resetProgress() {
|
||||
|
||||
guard Thread.isMainThread else { return }
|
||||
|
||||
guard let realm = self.realm else { return }
|
||||
do {
|
||||
try self.realm?.write {
|
||||
progresses.removeAll()
|
||||
let mustCommit: Bool
|
||||
|
||||
if !realm.isInWriteTransaction {
|
||||
realm.beginWrite()
|
||||
mustCommit = true
|
||||
} else {
|
||||
mustCommit = false
|
||||
}
|
||||
|
||||
progresses.removeAll()
|
||||
|
||||
if mustCommit { try realm.commitWrite() }
|
||||
} catch {
|
||||
NSLog("Error updating session progress: \(error)")
|
||||
}
|
||||
|
||||
@@ -16,68 +16,70 @@ import EventKit
|
||||
extension AppCoordinator: SessionsTableViewControllerDelegate {
|
||||
|
||||
func sessionTableViewContextMenuActionWatch(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
if viewModel.sessionInstance.isCurrentlyLive {
|
||||
continue
|
||||
} else {
|
||||
viewModel.session.setCurrentPosition(1, 1)
|
||||
backgroundUpdate(objects: viewModels.map({ $0.session })) { session in
|
||||
if let instance = session.instances.first {
|
||||
guard !instance.isCurrentlyLive else { return }
|
||||
|
||||
guard instance.type == .session || instance.type == .video else { return }
|
||||
}
|
||||
|
||||
session.setCurrentPosition(1, 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func sessionTableViewContextMenuActionUnWatch(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
viewModel.session.resetProgress()
|
||||
backgroundUpdate(objects: viewModels.map({ $0.session })) { session in
|
||||
session.resetProgress()
|
||||
}
|
||||
}
|
||||
|
||||
func sessionTableViewContextMenuActionFavorite(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
if !viewModel.isFavorite {
|
||||
storage.createFavorite(for: viewModel.session)
|
||||
}
|
||||
backgroundUpdate(objects: viewModels.map({ $0.session })) { session in
|
||||
session.favorites.append(Favorite())
|
||||
}
|
||||
}
|
||||
|
||||
func sessionTableViewContextMenuActionRemoveFavorite(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
if viewModel.isFavorite {
|
||||
storage.removeFavorite(for: viewModel.session)
|
||||
}
|
||||
backgroundUpdate(objects: viewModels.map({ $0.session })) { session in
|
||||
session.favorites.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
func sessionTableViewContextMenuActionDownload(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
guard let videoAsset = viewModel.session.assets.filter({ $0.assetType == .hdVideo }).first else { continue }
|
||||
viewModels.forEach { viewModel in
|
||||
guard let videoAsset = viewModel.session.assets.filter({ $0.assetType == .hdVideo }).first else { return }
|
||||
|
||||
DownloadManager.shared.download(videoAsset)
|
||||
}
|
||||
}
|
||||
|
||||
func sessionTableViewContextMenuActionCancelDownload(viewModels: [SessionViewModel]) {
|
||||
|
||||
for viewModel in viewModels {
|
||||
|
||||
if let videoAsset = viewModel.session.assets.filter({ $0.assetType == .hdVideo }).first {
|
||||
if !DownloadManager.shared.isDownloading(videoAsset.remoteURL) {
|
||||
continue
|
||||
}
|
||||
viewModels.forEach { viewModel in
|
||||
guard let videoAsset = viewModel.session.assets.filter({ $0.assetType == .hdVideo }).first else { return }
|
||||
|
||||
guard DownloadManager.shared.isDownloading(videoAsset.remoteURL) else { return }
|
||||
|
||||
DownloadManager.shared.deleteDownload(for: videoAsset)
|
||||
DownloadManager.shared.deleteDownload(for: videoAsset)
|
||||
}
|
||||
}
|
||||
|
||||
private func backgroundUpdate<T: ThreadConfined>(objects inputObjects: [T], updateBlock: @escaping (T) -> Void) {
|
||||
let safeReferences = inputObjects.map({ ThreadSafeReference(to: $0) })
|
||||
let config = storage.realmConfig
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
do {
|
||||
let realm = try Realm(configuration: config)
|
||||
let objects = safeReferences.flatMap({ realm.resolve($0) })
|
||||
|
||||
try realm.write {
|
||||
objects.forEach(updateBlock)
|
||||
}
|
||||
} catch {
|
||||
NSApp.presentError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user