Skip to main content

Add AlbumInfo and PreviewImage

ID
eaa34f3
date
2023-06-08 07:18:40+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
7be2ee1
message
Add AlbumInfo and PreviewImage
changed files
4 files, 97 additions, 65 deletions

Changed files

BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (23190) → BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (23614)

diff --git a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
index 0084083..4d642b8 100644
--- a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
+++ b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
@@ -16,6 +16,7 @@
 		94D7510E2A31A798005859E7 /* BlinkReviewerUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94D7510D2A31A798005859E7 /* BlinkReviewerUITestsLaunchTests.swift */; };
 		94D7511C2A31A7B1005859E7 /* ThumbnailItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94D7511B2A31A7B1005859E7 /* ThumbnailItem.swift */; };
 		94D7511E2A31B243005859E7 /* PreviewImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94D7511D2A31B243005859E7 /* PreviewImage.swift */; };
+		94D751202A31B53E005859E7 /* AlbumInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94D7511F2A31B53E005859E7 /* AlbumInfo.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -49,6 +50,7 @@
 		94D7510D2A31A798005859E7 /* BlinkReviewerUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlinkReviewerUITestsLaunchTests.swift; sourceTree = "<group>"; };
 		94D7511B2A31A7B1005859E7 /* ThumbnailItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailItem.swift; sourceTree = "<group>"; };
 		94D7511D2A31B243005859E7 /* PreviewImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewImage.swift; sourceTree = "<group>"; };
+		94D7511F2A31B53E005859E7 /* AlbumInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumInfo.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -139,6 +141,7 @@
 			children = (
 				94D7511B2A31A7B1005859E7 /* ThumbnailItem.swift */,
 				94D7511D2A31B243005859E7 /* PreviewImage.swift */,
+				94D7511F2A31B53E005859E7 /* AlbumInfo.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -277,6 +280,7 @@
 				94D750F22A31A796005859E7 /* ContentView.swift in Sources */,
 				94D7511E2A31B243005859E7 /* PreviewImage.swift in Sources */,
 				94D750F02A31A796005859E7 /* BlinkReviewerApp.swift in Sources */,
+				94D751202A31B53E005859E7 /* AlbumInfo.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

BlinkReviewer/BlinkReviewer/ContentView.swift (1679) → BlinkReviewer/BlinkReviewer/ContentView.swift (1516)

diff --git a/BlinkReviewer/BlinkReviewer/ContentView.swift b/BlinkReviewer/BlinkReviewer/ContentView.swift
index 39dcb8c..2525587 100644
--- a/BlinkReviewer/BlinkReviewer/ContentView.swift
+++ b/BlinkReviewer/BlinkReviewer/ContentView.swift
@@ -30,6 +30,7 @@ struct ContentView: View {
         return photos
     }
     
+    @State private var selectedAssetIndex: Int = 0
     @State private var selectedAsset: PHAsset? = nil
     
     var body: some View {
@@ -51,17 +52,9 @@ struct ContentView: View {
             }
             Divider()
             
-            if let thisSelectedAsset = selectedAsset {
-                PreviewImage(asset: thisSelectedAsset)
-            }
-        }.onAppear {
-            selectedAsset = allPhotos[0]
+            PreviewImage(asset: allPhotos[selectedAssetIndex])
+            
+            Spacer()
         }
     }
 }
-
-//struct ContentView_Previews: PreviewProvider {
-//    static var previews: some View {
-//        ContentView()
-//    }
-//}

BlinkReviewer/BlinkReviewer/Views/AlbumInfo.swift (0) → BlinkReviewer/BlinkReviewer/Views/AlbumInfo.swift (1107)

diff --git a/BlinkReviewer/BlinkReviewer/Views/AlbumInfo.swift b/BlinkReviewer/BlinkReviewer/Views/AlbumInfo.swift
new file mode 100644
index 0000000..d758343
--- /dev/null
+++ b/BlinkReviewer/BlinkReviewer/Views/AlbumInfo.swift
@@ -0,0 +1,42 @@
+//
+//  AlbumInfo.swift
+//  BlinkReviewer
+//
+//  Created by Alex Chan on 08/06/2023.
+//
+
+import SwiftUI
+import Photos
+
+extension PHAsset {
+    func albums() -> [PHAssetCollection] {
+        var result: [PHAssetCollection] = []
+        
+        PHAssetCollection
+            .fetchAssetCollectionsContaining(self, with: .album, options: nil)
+            .enumerateObjects({ (collection, index, stop) in
+                result.append(collection)
+            })
+        
+        return result
+    }
+}
+
+struct AlbumInfo: View {
+    var asset: PHAsset
+    
+    var body: some View {
+        HStack {
+            ForEach(asset.albums(), id: \.localIdentifier) { album in
+                if let title = album.localizedTitle {
+                    Text("\(Image(systemName: "rectangle.stack")) \(title)")
+                        .fontWeight(.bold)
+                        .font(.title2)
+                        .padding(5)
+                        .background(Color(red: 1.0, green: 1.0, blue: 1.0, opacity: 0.9))
+                        .cornerRadius(10.0)
+                }
+            }
+        }.padding()
+    }
+}

BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift (2633) → BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift (2218)

diff --git a/BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift b/BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift
index 9eabcf8..1f87230 100644
--- a/BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/PreviewImage.swift
@@ -9,76 +9,69 @@ import Photos
 import SwiftUI
 
 extension PHAsset {
-    /// Create an NSImage at the given size.
-    func getImage(forWidth width: Double, forHeight height: Double) -> NSImage {
-    // This implementation is based on code in a Stack Overflow answer
-    // by Francois Nadeau: https://stackoverflow.com/a/48755517/1558022
-    //
-    // I've added more comments and error-handling logic.
+    func getImage() -> NSImage {
+        // This implementation is based on code in a Stack Overflow answer
+        // by Francois Nadeau: https://stackoverflow.com/a/48755517/1558022
 
-    let options = PHImageRequestOptions()
-    options.isSynchronous = true
+        let options = PHImageRequestOptions()
+        options.isSynchronous = true
 
-    // If i don't set this value, then sometimes I get an error like
-    // this in the `info` variable:
-    //
-    //      Error Domain=PHPhotosErrorDomain Code=3164 "(null)"
-    //
-    // This means that the asset is in the cloud, and by default Photos
-    // isn't allowed to download assets here.  Apple's documentation
-    // suggests adding this option as the fix.
-    //
-    // See https://developer.apple.com/documentation/photokit/phphotoserror/phphotoserrornetworkaccessrequired
-    options.isNetworkAccessAllowed = true
+        // If i don't set this value, then sometimes I get an error like
+        // this in the `info` variable:
+        //
+        //      Error Domain=PHPhotosErrorDomain Code=3164 "(null)"
+        //
+        // This means that the asset is in the cloud, and by default Photos
+        // isn't allowed to download assets here.  Apple's documentation
+        // suggests adding this option as the fix.
+        //
+        // See https://developer.apple.com/documentation/photokit/phphotoserror/phphotoserrornetworkaccessrequired
+        options.isNetworkAccessAllowed = true
 
-    var image = NSImage()
+        var image = NSImage()
 
-    PHImageManager.default()
-      .requestImage(
-        for: self,
-        targetSize: CGSize(width: width, height: height),
-        contentMode: .aspectFit,
-        options: options,
-        resultHandler: { (result, info) -> Void in
-
-          // If we fail to get a result, print a message to the user that
-          // includes the value of `info`.  For information about interpreting
-          // these keys, see Apple's documentation:
-          // https://developer.apple.com/documentation/photokit/phimagemanager/image_result_info_keys
-          switch (result, info) {
-          case let (result?, _):
-            image = result
-          case let (.none, info?):
-            fputs("Unable to create image:\n", stderr)
-            fputs("\(info)\n", stderr)
-            exit(1)
-          case (.none, .none):
-            fputs("Unable to create image:\n", stderr)
-            fputs("(unknown error)\n", stderr)
-            exit(1)
-          }
-        })
+        PHImageManager.default()
+            .requestImage(
+                for: self,
+                targetSize: PHImageManagerMaximumSize,
+                contentMode: .aspectFit,
+                options: options,
+                resultHandler: { (result, info) -> Void in
+                    image = result!
+                }
+            )
 
-    return image
-  }
+        return image
+    }
 }
 
 struct PreviewImage: View {
     var asset: PHAsset
     
     var body: some View {
-        VStack {
-            GeometryReader { geometry in
+        ZStack {
+            VStack {
                 HStack {
                     Spacer()
-                    
-                    Image(nsImage: asset.getImage(forWidth: geometry.size.width, forHeight: geometry.size.height))
+                        
+                    Image(nsImage: asset.getImage())
                         .resizable()
                         .aspectRatio(contentMode: .fit)
-                    
+                        .overlay(alignment: Alignment(horizontal: .center, vertical: .top)) {
+                            AlbumInfo(asset: asset)
+                        }
+                        
                     Spacer()
                 }
-            }
-        }.padding()
+            }.padding()
+            
+//            VStack {
+//                Text(asset.localIdentifier)
+//                    .background(.white)
+//                
+//                Spacer()
+//            }
+        }
+        
     }
 }