Skip to main content

Add some more comments, move things around

ID
fc9e76c
date
2023-06-16 06:41:41+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
1feb066
message
Add some more comments, move things around
changed files
2 files, 82 additions, 62 deletions

Changed files

BlinkReviewer/Blink.xcodeproj/project.pbxproj (34735) → BlinkReviewer/Blink.xcodeproj/project.pbxproj (34735)

diff --git a/BlinkReviewer/Blink.xcodeproj/project.pbxproj b/BlinkReviewer/Blink.xcodeproj/project.pbxproj
index d4af973..3c053f4 100644
--- a/BlinkReviewer/Blink.xcodeproj/project.pbxproj
+++ b/BlinkReviewer/Blink.xcodeproj/project.pbxproj
@@ -600,7 +600,7 @@
 				CODE_SIGN_ENTITLEMENTS = Blink/Blink.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				DEVELOPMENT_ASSET_PATHS = "\"Blink/Preview Content\"";
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -627,7 +627,7 @@
 				CODE_SIGN_ENTITLEMENTS = Blink/Blink.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				DEVELOPMENT_ASSET_PATHS = "\"Blink/Preview Content\"";
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -652,7 +652,7 @@
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				GENERATE_INFOPLIST_FILE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 13.3;
 				MARKETING_VERSION = 1.0;
@@ -670,7 +670,7 @@
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				GENERATE_INFOPLIST_FILE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 13.3;
 				MARKETING_VERSION = 1.0;
@@ -687,7 +687,7 @@
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				GENERATE_INFOPLIST_FILE = YES;
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = net.alexwlchan.BlinkReviewerUITests;
@@ -703,7 +703,7 @@
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 48;
+				CURRENT_PROJECT_VERSION = 51;
 				GENERATE_INFOPLIST_FILE = YES;
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = net.alexwlchan.BlinkReviewerUITests;

BlinkReviewer/Blink/Photos/PhotosLibrary.swift (15968) → BlinkReviewer/Blink/Photos/PhotosLibrary.swift (16753)

diff --git a/BlinkReviewer/Blink/Photos/PhotosLibrary.swift b/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
index 5dd9502..9eda73d 100644
--- a/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
+++ b/BlinkReviewer/Blink/Photos/PhotosLibrary.swift
@@ -119,7 +119,17 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
         // ahead and populate all the initial data structures.
         if !self.isPhotoLibraryAuthorized && PHPhotoLibrary.authorizationStatus() == .authorized {
             getInitialData()
-            self.isPhotoLibraryAuthorized = PHPhotoLibrary.authorizationStatus() == .authorized
+            
+            // This is wrapped in an async dispatch to fix a warning from Xcode:
+            //
+            //     Publishing changes from background threads is not allowed; make sure
+            //     to publish values from the main thread (via operators like receive(on:))
+            //     on model updates.
+            //
+            DispatchQueue.main.async {
+                self.isPhotoLibraryAuthorized = PHPhotoLibrary.authorizationStatus() == .authorized
+            }
+            
             return
         }
         
@@ -186,6 +196,10 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
         }
     }
     
+    /// Retrieve an asset at a particular position.
+    ///
+    /// Just a convenience wrapper around PHFetchResult.object(at: Int).
+    ///
     func asset(at index: Int) -> PHAsset {
         assets.object(at: index)
     }
@@ -240,6 +254,67 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
         return nil
     }
     
+    /// Set the review state of an asset.
+    ///
+    /// This will record the change in the Photos Library and update any internal
+    /// data structures.
+    /// 
+    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)
+        }
+    }
+    
+    /// Returns true if this asset is a favorite, false otherwise.
     func isFavorite(localIdentifier: String) -> Bool {
         self.favoriteAssetIdentifiers.contains(localIdentifier)
     }
@@ -319,61 +394,6 @@ 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> {