get indexes working again
- ID
ac53bc6- date
2023-06-09 18:42:27+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
44bdc1f- message
get indexes working again- changed files
Changed files
BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift (3493) → BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift (2759)
diff --git a/BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift b/BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift
index 359a26f..fd84cb1 100644
--- a/BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift
+++ b/BlinkReviewer/BlinkReviewer/Photos/PhotosLibrary.swift
@@ -26,7 +26,7 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
override init() {
super.init()
PHPhotoLibrary.shared().register(self)
- updateStatus()
+ updateStatus(isChange: false)
}
func updateAsset(atIndex index: Int) {
@@ -36,50 +36,28 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
func photoLibraryDidChange(_ changeInstance: PHChange) {
print("calling photoLibraryDidChange")
print(changeInstance.description)
- updateStatus()
+ updateStatus(isChange: true)
}
- private func updateStatus() {
+ private func updateStatus(isChange: Bool) {
DispatchQueue.main.async {
- let start = DispatchTime.now()
- var elapsed = start
-
- func printElapsed(_ label: String) -> Void {
- let now = DispatchTime.now()
-
- let totalInterval = Double(now.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000_000
- let elapsedInterval = Double(now.uptimeNanoseconds - elapsed.uptimeNanoseconds) / 1_000_000_000
-
- elapsed = DispatchTime.now()
-
- print("Time to \(label):\n \(elapsedInterval) seconds (\(totalInterval) total)")
- }
-
-// self.assets = getAllPhotos()
-
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
- options.fetchLimit = 300
self.assets2 = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: options)
-
- print("self.approvedAssets = \(self.approvedAssets.count)")
+
self.approvedAssets = PHAsset.fetchAssets(in: self.approved, options: nil)
- print("self.approvedAssets = \(self.approvedAssets.count)")
self.rejectedAssets = PHAsset.fetchAssets(in: self.rejected, options: nil)
self.needsActionAssets = PHAsset.fetchAssets(in: self.needsAction, options: nil)
self.isPhotoLibraryAuthorized = PHPhotoLibrary.authorizationStatus() == .authorized
-
- print("self.isPhotoLibraryAuthorized = \(self.isPhotoLibraryAuthorized)")
- print("self.assets2.count = \(self.assets2.count)")
-
- printElapsed("get photos library data")
}
}
func state(for asset: PHAsset) -> ReviewState? {
- print("evaluating state for \(asset.localIdentifier)")
+ if asset.localIdentifier == "CBF9AD6F-F885-4538-9012-3DC5EEEBACBE/L0/001" {
+ print("evaluating state for \(asset.localIdentifier)")
+ }
if self.rejectedAssets.contains(asset) {
return .Rejected
@@ -90,6 +68,10 @@ class PhotosLibrary: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
}
if self.approvedAssets.contains(asset) {
+ if asset.localIdentifier == "CBF9AD6F-F885-4538-9012-3DC5EEEBACBE/L0/001" {
+ print(" -> state is approved!")
+ }
+
return .Approved
}
BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (6230) → BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (6900)
diff --git a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
index e29a7e3..69bbd10 100644
--- a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
@@ -15,6 +15,7 @@ struct PhotoReviewer: View {
@State var selectedAssetIndex: Int = -1
@State var showStatistics: Bool = false
+ @State var showDebug: Bool = true
var body: some View {
if photosLibrary.isPhotoLibraryAuthorized {
@@ -38,7 +39,7 @@ struct PhotoReviewer: View {
selectedAssetIndex = photosLibrary.assets2.count - 1
fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - selectedAssetIndex)
-
+
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
handleKeyEvent(event)
return event
@@ -47,18 +48,28 @@ struct PhotoReviewer: View {
fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - newIndex)
})
- if showStatistics {
- HStack {
+ HStack {
+ Spacer()
+
+ VStack {
Spacer()
- VStack {
- Spacer()
-
+ if showStatistics {
Statistics().environmentObject(photosLibrary)
}
- .padding()
- }.padding()
- }
+
+ if showDebug {
+ Text("\(fullSizeImage.asset?.localIdentifier ?? "(none)")")
+ .font(.title)
+ .padding(10)
+ .foregroundColor(.white)
+ .background(.black.opacity(0.7))
+ .cornerRadius(7.0)
+ .shadow(radius: 2.0)
+ }
+ }
+ .padding()
+ }.padding()
}
} else {
Text("Waiting for Photos Library authorization…")
@@ -66,7 +77,7 @@ struct PhotoReviewer: View {
}
private func handleKeyEvent(_ event: NSEvent) {
- let asset = photosLibrary.assets2.object(at: selectedAssetIndex)
+ let asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - selectedAssetIndex)
switch event.keyCode {
case 123: // Left arrow key
@@ -80,16 +91,12 @@ struct PhotoReviewer: View {
}
case 18, 19, 20: // "1", "2", "3"
+ let state = photosLibrary.state(for: asset)
+
let approved = getAlbum(withName: "Approved")
let rejected = getAlbum(withName: "Rejected")
let needsAction = getAlbum(withName: "Needs Action")
- let albums = asset.albums()
-
- let isApproved = albums.contains(approved)
- let isRejected = albums.contains(rejected)
- let isNeedsAction = albums.contains(needsAction)
-
try! PHPhotoLibrary.shared().performChangesAndWait {
// Strictly speaking, the first condition is a combination of two:
//
@@ -99,19 +106,21 @@ struct PhotoReviewer: View {
// which case setting the new status means removing approved.
//
// Similar logic applies for all three conditions.
- if isApproved {
- asset.remove(fromAlbum: approved)
+ if state == .Approved {
+ print("removing asset \(asset.localIdentifier) from approved")
+ asset.remove(fromAlbum: approved)
} else if event.keyCode == 18 {
+ print("adding asset \(asset.localIdentifier) to approved")
asset.add(toAlbum: approved)
}
- if isRejected {
+ if state == .Rejected {
asset.remove(fromAlbum: rejected)
} else if event.keyCode == 19 {
asset.add(toAlbum: rejected)
}
- if isNeedsAction {
+ if state == .NeedsAction {
asset.remove(fromAlbum: needsAction)
} else if event.keyCode == 20 {
asset.add(toAlbum: needsAction)
@@ -157,6 +166,9 @@ struct PhotoReviewer: View {
case 1: // "s"
showStatistics.toggle()
+ case 2: // "d"
+ showDebug.toggle()
+
default:
print(event)
break
BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift (2433) → BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift (2678)
diff --git a/BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift b/BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift
index 195cf40..df1559d 100644
--- a/BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/ThumbnailImage.swift
@@ -27,47 +27,50 @@ struct ThumbnailImage: View {
}
var body: some View {
- Image(nsImage: thumbnail.image)
- .resizable()
- .saturation(state == .Rejected ? 0.0 : 1.0)
- // Note: it's taken several attempts to get this working correctly;
- // it behaves differently in the running app to the SwiftUI preview.
- //
- // Expected properties:
- //
- // - Thumbnails are square
- // - Thumbnails are expanded to fill the square, but they prefer
- // to crop rather than stretch the image
- //
- .scaledToFill()
- .frame(width: size, height: size, alignment: .center)
- .clipped()
- .overlay(
- // https://www.appcoda.com/swiftui-border/
- RoundedRectangle(cornerRadius: cornerRadius)
- .stroke(
- state?.color() ?? .gray.opacity(0.7),
- lineWidth: state != nil ? 3.0 : 1.0
- )
- )
- .cornerRadius(cornerRadius)
- .overlay(alignment: Alignment(horizontal: .leading, vertical: .bottom)) {
- if (isFavorite) {
- Image(systemName: "heart.fill")
- .foregroundColor(.white)
- .padding(2)
- .shadow(radius: 2.0)
- }
- }
- .overlay(alignment: Alignment(horizontal: .leading, vertical: .top)) {
- if let thisState = state {
- thisState.icon()
- .foregroundStyle(.white, thisState.color())
- .symbolRenderingMode(.palette)
- .padding(2)
- .font(.title2)
- .shadow(radius: 2.0)
+ VStack {
+ Text("\(Date())").foregroundColor(.white)
+ Image(nsImage: thumbnail.image)
+ .resizable()
+ .saturation(state == .Rejected ? 0.0 : 1.0)
+ // Note: it's taken several attempts to get this working correctly;
+ // it behaves differently in the running app to the SwiftUI preview.
+ //
+ // Expected properties:
+ //
+ // - Thumbnails are square
+ // - Thumbnails are expanded to fill the square, but they prefer
+ // to crop rather than stretch the image
+ //
+ .scaledToFill()
+ .frame(width: size, height: size, alignment: .center)
+ .clipped()
+ .overlay(
+ // https://www.appcoda.com/swiftui-border/
+ RoundedRectangle(cornerRadius: cornerRadius)
+ .stroke(
+ state?.color() ?? .gray.opacity(0.7),
+ lineWidth: state != nil ? 3.0 : 1.0
+ )
+ )
+ .cornerRadius(cornerRadius)
+ .overlay(alignment: Alignment(horizontal: .leading, vertical: .bottom)) {
+ if (isFavorite) {
+ Image(systemName: "heart.fill")
+ .foregroundColor(.white)
+ .padding(2)
+ .shadow(radius: 2.0)
+ }
}
+ .overlay(alignment: Alignment(horizontal: .leading, vertical: .top)) {
+ if let thisState = state {
+ thisState.icon()
+ .foregroundStyle(.white, thisState.color())
+ .symbolRenderingMode(.palette)
+ .padding(2)
+ .font(.title2)
+ .shadow(radius: 2.0)
+ }
}
+ }
}
}