Gallery: fix sync dot colors — match phone photos against NAS directory
Phase 1 was only checking the Kisani manifest for sync status. Phone photos uploaded by other tools had no manifest entry, showed as orange (phone-only) even though they were already on the NAS. Now Phase 1 falls back to a filename lookup against the full NAS directory listing: manifest match → green (.synced), NAS directory match → green (.synced), no match → orange (.phone). Phase 3 skips filenames already resolved in Phase 1. Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -175,22 +175,31 @@ final class GalleryViewModel: ObservableObject {
|
||||
) -> [GalleryItem] {
|
||||
var byID = [String: ManifestEntry](minimumCapacity: manifest.count)
|
||||
var byName = [String: ManifestEntry](minimumCapacity: manifest.count)
|
||||
var manifestFilenames = Set<String>(minimumCapacity: manifest.count)
|
||||
// allNASFilenames tracks every filename already represented so Phase 3 skips duplicates
|
||||
var allNASFilenames = Set<String>(minimumCapacity: manifest.count + nasDirectory.count)
|
||||
for entry in manifest {
|
||||
if !entry.localIdentifier.isEmpty { byID[entry.localIdentifier] = entry }
|
||||
let key = entry.filename.lowercased()
|
||||
if byName[key] == nil { byName[key] = entry }
|
||||
manifestFilenames.insert(key)
|
||||
allNASFilenames.insert(key)
|
||||
}
|
||||
// Build NAS directory lookup for filename-based sync matching in Phase 1
|
||||
var nasByName = [String: NASItem](minimumCapacity: nasDirectory.count)
|
||||
for item in nasDirectory {
|
||||
let lower = item.name.lowercased()
|
||||
if nasByName[lower] == nil { nasByName[lower] = item }
|
||||
}
|
||||
|
||||
var result: [GalleryItem] = []
|
||||
result.reserveCapacity(phone.count + manifest.count + nasDirectory.count / 4)
|
||||
var coveredFilenames = Set<String>()
|
||||
|
||||
// Phase 1: Phone assets — matched to manifest = synced, otherwise phone-only
|
||||
// Phase 1: Phone assets
|
||||
// Priority: manifest match (Kisani upload) → NAS directory match (other tool) → phone-only
|
||||
for (localID, filename, date, duration, isVideo) in phone {
|
||||
let key = filename.lowercased()
|
||||
if let entry = byID[localID] ?? byName[key] {
|
||||
// Kisani manifest match → green dot (.synced)
|
||||
coveredFilenames.insert(entry.filename.lowercased())
|
||||
result.append(GalleryItem(
|
||||
id: "synced_\(localID)",
|
||||
@@ -201,7 +210,20 @@ final class GalleryViewModel: ObservableObject {
|
||||
mediaType: isVideo ? .video : .photo,
|
||||
source: .synced(localIdentifier: localID, nasPath: entry.remotePath)
|
||||
))
|
||||
} else if let nasItem = nasByName[key] {
|
||||
// Filename match in NAS directory (uploaded by other tool) → green dot (.synced)
|
||||
allNASFilenames.insert(key) // mark covered so Phase 3 skips it
|
||||
result.append(GalleryItem(
|
||||
id: "synced_\(localID)",
|
||||
filename: filename,
|
||||
creationDate: date,
|
||||
duration: duration,
|
||||
fileSize: nasItem.size > 0 ? nasItem.size : nil,
|
||||
mediaType: isVideo ? .video : .photo,
|
||||
source: .synced(localIdentifier: localID, nasPath: nasItem.path)
|
||||
))
|
||||
} else {
|
||||
// Not on NAS → orange dot (.phone)
|
||||
result.append(GalleryItem(
|
||||
id: "phone_\(localID)",
|
||||
filename: filename,
|
||||
@@ -231,14 +253,15 @@ final class GalleryViewModel: ObservableObject {
|
||||
))
|
||||
}
|
||||
|
||||
// Phase 3: NAS directory items not tracked by the manifest (uploaded by other tools)
|
||||
// Phase 3: NAS directory items not already shown (uploaded by other tools, not on phone)
|
||||
for item in nasDirectory {
|
||||
let lower = item.name.lowercased()
|
||||
guard !manifestFilenames.contains(lower) else { continue }
|
||||
guard !allNASFilenames.contains(lower) else { continue }
|
||||
let ext = (item.name as NSString).pathExtension.lowercased()
|
||||
let mediaType: GalleryItem.MediaType =
|
||||
videoExts.contains(ext) ? .video : imageExts.contains(ext) ? .photo : .unknown
|
||||
guard mediaType != .unknown else { continue }
|
||||
allNASFilenames.insert(lower)
|
||||
result.append(GalleryItem(
|
||||
id: "nas_dir_\(item.path)",
|
||||
filename: item.name,
|
||||
|
||||
Reference in New Issue
Block a user