Refactored context menu actions, doing updates in background for performance

This commit is contained in:
Guilherme Rambo
2017-06-12 00:09:03 -03:00
parent 88fc23f671
commit a687278d57
2 changed files with 74 additions and 55 deletions

View File

@@ -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)")
}

View File

@@ -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)
}
}
}
}