Push some setState stuff into PhotosLibrary for snappier UI
- ID
fd49963- date
2023-06-15 13:35:55+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
3bba5d9- message
Push some setState stuff into PhotosLibrary for snappier UI- changed files
3 files, 83 additions, 42 deletions
Changed files
BlinkReviewer/Blink.xcodeproj/project.pbxproj (34154) → BlinkReviewer/Blink.xcodeproj/project.pbxproj (34154)
diff --git a/BlinkReviewer/Blink.xcodeproj/project.pbxproj b/BlinkReviewer/Blink.xcodeproj/project.pbxproj
index 8b267a5..82cfc5a 100644
--- a/BlinkReviewer/Blink.xcodeproj/project.pbxproj
+++ b/BlinkReviewer/Blink.xcodeproj/project.pbxproj
@@ -588,7 +588,7 @@
CODE_SIGN_ENTITLEMENTS = Blink/Blink.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
DEVELOPMENT_ASSET_PATHS = "\"Blink/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -615,7 +615,7 @@
CODE_SIGN_ENTITLEMENTS = Blink/Blink.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
DEVELOPMENT_ASSET_PATHS = "\"Blink/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -640,7 +640,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 13.3;
MARKETING_VERSION = 1.0;
@@ -658,7 +658,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 13.3;
MARKETING_VERSION = 1.0;
@@ -675,7 +675,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = net.alexwlchan.BlinkReviewerUITests;
@@ -691,7 +691,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 30;
+ CURRENT_PROJECT_VERSION = 42;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = net.alexwlchan.BlinkReviewerUITests;
BlinkReviewer/Blink/Photos/PhotosLibrary.swift (12709) → BlinkReviewer/Blink/Photos/PhotosLibrary.swift (14943)
diff --git a/BlinkReviewer/Blink/Photos/PhotosLibrary.swift b/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
index fece0a4..0d69662 100644
--- a/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
+++ b/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
@@ -308,6 +308,61 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
self.assetIdentifiers = assetIdentifiers
self.favoriteAssetIdentifiers = favoriteAssetIdentifiers
}
+
+ func setState(ofAsset asset: PHAsset, to newState: ReviewState) -> Void {
+ let existingState = self.state(of: asset)
+
+ try! PHPhotoLibrary.shared().performChangesAndWait {
+ // The first condition is a combination of two:
+ //
+ // -- the photo is already approved and you hit the "approve" hotkey,
+ // -- so un-approve it
+ // state == .Approved && e.characters == "1"
+ //
+ // -- the photo is already approved and you selected a different review
+ // -- state, so unapprove it
+ // state == .Approved && e.characters != "1"
+ //
+ // We can optimise it into a single case, but it does make sense!
+ //
+ // Similar logic applies for all three conditions.
+ if existingState == .Approved {
+ asset.remove(fromAlbum: self.approved)
+ } else if newState == .Approved {
+ asset.add(toAlbum: self.approved)
+ }
+
+ if existingState == .Rejected {
+ asset.remove(fromAlbum: self.rejected)
+ } else if newState == .Rejected {
+ asset.add(toAlbum: self.rejected)
+ }
+
+ if existingState == .NeedsAction {
+ asset.remove(fromAlbum: self.needsAction)
+ } else if newState == .NeedsAction {
+ asset.add(toAlbum: self.needsAction)
+ }
+ }
+
+ if existingState == .Approved {
+ self.approvedAssetIdentifiers.remove(asset.localIdentifier)
+ } else if newState == .Approved {
+ self.approvedAssetIdentifiers.insert(asset.localIdentifier)
+ }
+
+ if existingState == .Rejected {
+ self.rejectedAssetIdentifiers.remove(asset.localIdentifier)
+ } else if newState == .Rejected {
+ self.rejectedAssetIdentifiers.insert(asset.localIdentifier)
+ }
+
+ if existingState == .NeedsAction {
+ self.needsActionAssetIdentifiers.remove(asset.localIdentifier)
+ } else if newState == .NeedsAction {
+ self.needsActionAssetIdentifiers.insert(asset.localIdentifier)
+ }
+ }
}
func getSetOfIdentifiers(fetchResult: PHFetchResult<PHAsset>) -> Set<String> {
BlinkReviewer/Blink/Views/PhotoReviewer.swift (14002) → BlinkReviewer/Blink/Views/PhotoReviewer.swift (13085)
diff --git a/BlinkReviewer/Blink/Views/PhotoReviewer.swift b/BlinkReviewer/Blink/Views/PhotoReviewer.swift
index ecc434f..8d972a4 100644
--- a/BlinkReviewer/Blink/Views/PhotoReviewer.swift
+++ b/BlinkReviewer/Blink/Views/PhotoReviewer.swift
@@ -224,49 +224,35 @@ struct PhotoReviewer: View {
return nil
case let e where e.characters == "1" || e.characters == "2" || e.characters == "3":
- print("time to review!")
- let state = photosLibrary.state(of: focusedAsset)
+ let oldState = photosLibrary.state(of: focusedAsset)
- let approved = getAlbum(withName: "Approved")
- let rejected = getAlbum(withName: "Rejected")
- let needsAction = getAlbum(withName: "Needs Action")
+ let newState: ReviewState =
+ e.characters == "1" ? .Approved :
+ e.characters == "2" ? .Rejected : .NeedsAction
- try! PHPhotoLibrary.shared().performChangesAndWait {
- // The first condition is a combination of two:
- //
- // -- the photo is already approved and you hit the "approve" hotkey,
- // -- so un-approve it
- // state == .Approved && e.characters == "1"
- //
- // -- the photo is already approved and you selected a different review
- // -- state, so unapprove it
- // state == .Approved && e.characters != "1"
- //
- // We can optimise it into a single case, but it does make sense!
- //
- // Similar logic applies for all three conditions.
- if state == .Approved {
- focusedAsset.remove(fromAlbum: approved)
- } else if e.characters == "1" {
- focusedAsset.add(toAlbum: approved)
- }
-
- if state == .Rejected {
- focusedAsset.remove(fromAlbum: rejected)
- } else if e.characters == "2" {
- focusedAsset.add(toAlbum: rejected)
- }
-
- if state == .NeedsAction {
- focusedAsset.remove(fromAlbum: needsAction)
- } else if e.characters == "3" {
- focusedAsset.add(toAlbum: needsAction)
- }
+ photosLibrary.setState(ofAsset: focusedAsset, to: newState)
+
+ if focusedAssetIndex < photosLibrary.assets.count - 1 {
+ focusedAssetIndex += 1
}
+
+ return nil
+
+ case let e where e.characters == "2":
+ photosLibrary.setState(ofAsset: focusedAsset, to: .Rejected)
if focusedAssetIndex < photosLibrary.assets.count - 1 {
focusedAssetIndex += 1
}
+
+ return nil
+
+ case let e where e.characters == "3":
+ photosLibrary.setState(ofAsset: focusedAsset, to: .NeedsAction)
+
+ if focusedAssetIndex < photosLibrary.assets.count - 1 {
+ focusedAssetIndex += 1
+ }
return nil
case let e where e.characters == "c":