瀏覽代碼

Live photo improvements (#2676)

* coding

---------

Signed-off-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com>
Co-authored-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com>
Marino Faggiana 1 年之前
父節點
當前提交
0d407891cc

+ 34 - 16
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -1021,30 +1021,48 @@ extension NCManageDatabase {
         }
     }
 
+    func isMetadataLivePhoto(metadata: tableMetadata) -> tableMetadata? {
+
+        guard metadata.livePhoto, NCKeychain().livePhoto, metadata.livePhotoFile.isEmpty else { return nil }
+
+        return getMetadataLivePhoto(metadata: metadata)
+    }
+
     func getMetadataLivePhoto(metadata: tableMetadata) -> tableMetadata? {
 
+        guard metadata.livePhoto, NCKeychain().livePhoto else { return nil }
         var classFile = metadata.classFile
         var fileName = (metadata.fileNameView as NSString).deletingPathExtension
 
-        if !metadata.livePhoto || !NCKeychain().livePhoto {
-            return nil
-        }
+        if !metadata.livePhotoFile.isEmpty {
+
+            do {
+                let realm = try Realm()
+                realm.refresh()
+                guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView == %@", metadata.account, metadata.serverUrl, metadata.livePhotoFile)).first else { return nil }
+                return tableMetadata.init(value: result)
+            } catch let error as NSError {
+                NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+            }
 
-        if classFile == NKCommon.TypeClassFile.image.rawValue {
-            classFile = NKCommon.TypeClassFile.video.rawValue
-            fileName = fileName + ".mov"
         } else {
-            classFile = NKCommon.TypeClassFile.image.rawValue
-            fileName = fileName + ".jpg"
-        }
 
-        do {
-            let realm = try Realm()
-            realm.refresh()
-            guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@ AND ocId != %@ AND classFile == %@", metadata.account, metadata.serverUrl, fileName, metadata.ocId, classFile)).first else { return nil }
-            return tableMetadata.init(value: result)
-        } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+            if classFile == NKCommon.TypeClassFile.image.rawValue {
+                classFile = NKCommon.TypeClassFile.video.rawValue
+                fileName = fileName + ".mov"
+            } else {
+                classFile = NKCommon.TypeClassFile.image.rawValue
+                fileName = fileName + ".jpg"
+            }
+
+            do {
+                let realm = try Realm()
+                realm.refresh()
+                guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@ AND ocId != %@ AND classFile == %@", metadata.account, metadata.serverUrl, fileName, metadata.ocId, classFile)).first else { return nil }
+                return tableMetadata.init(value: result)
+            } catch let error as NSError {
+                NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+            }
         }
 
         return nil

+ 20 - 16
iOSClient/Media/NCMedia.swift

@@ -39,6 +39,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     internal let utilityFileSystem = NCUtilityFileSystem()
     internal let utility = NCUtility()
 
+    internal var metadatas: [tableMetadata] = []
     internal var isEditMode = false
     internal var selectOcId: [String] = []
     internal var selectIndexPath: [IndexPath] = []
@@ -122,6 +123,9 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
         NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterUploadedFile), object: nil)
 
+        if let metadatas = NCImageCache.shared.initialMetadatas() {
+            self.metadatas = metadatas
+        }
         timerSearchNewMedia?.invalidate()
         timerSearchNewMedia = Timer.scheduledTimer(timeInterval: timeIntervalSearchNewMedia, target: self, selector: #selector(searchNewMediaTimer), userInfo: nil, repeats: false)
 
@@ -161,7 +165,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
         guard let userInfo = notification.userInfo as NSDictionary?,
               let error = userInfo["error"] as? NKError else { return }
 
-        NCImageCache.shared.getMediaMetadatas(account: appDelegate.account, predicate: getPredicate())
+        self.metadatas = NCImageCache.shared.getMediaMetadatas(account: appDelegate.account, predicate: getPredicate())
 
         if error != .success {
             NCContentPresenter().showError(error: error)
@@ -294,7 +298,7 @@ extension NCMedia: UICollectionViewDelegate {
 
     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 
-        let metadata = NCImageCache.shared.metadatas[indexPath.row]
+        let metadata = self.metadatas[indexPath.row]
         if isEditMode {
             if let index = selectOcId.firstIndex(of: metadata.ocId) {
                 selectOcId.remove(at: index)
@@ -310,14 +314,14 @@ extension NCMedia: UICollectionViewDelegate {
             // ACTIVE SERVERURL
             appDelegate.activeServerUrl = metadata.serverUrl
             let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as? NCGridMediaCell
-            NCViewer().view(viewController: self, metadata: metadata, metadatas: NCImageCache.shared.metadatas, imageIcon: cell?.imageItem.image)
+            NCViewer().view(viewController: self, metadata: metadata, metadatas: self.metadatas, imageIcon: cell?.imageItem.image)
         }
     }
 
     func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
 
         guard let cell = collectionView.cellForItem(at: indexPath) as? NCGridMediaCell else { return nil }
-        let metadata = NCImageCache.shared.metadatas[indexPath.row]
+        let metadata = self.metadatas[indexPath.row]
         let identifier = indexPath as NSCopying
         let image = cell.imageItem.image
 
@@ -353,13 +357,13 @@ extension NCMedia: UICollectionViewDataSource {
     }
 
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        emptyDataSet?.numberOfItemsInSection(NCImageCache.shared.metadatas.count, section: section)
-        return NCImageCache.shared.metadatas.count
+        emptyDataSet?.numberOfItemsInSection(self.metadatas.count, section: section)
+        return self.metadatas.count
     }
 
     func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
-        if !collectionView.indexPathsForVisibleItems.contains(indexPath) && indexPath.row < NCImageCache.shared.metadatas.count {
-            let metadata = NCImageCache.shared.metadatas[indexPath.row]
+        if !collectionView.indexPathsForVisibleItems.contains(indexPath) && indexPath.row < self.metadatas.count {
+            let metadata = self.metadatas[indexPath.row]
             for case let operation as NCMediaDownloadThumbnaill in appDelegate.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId {
                 operation.cancel()
             }
@@ -370,9 +374,9 @@ extension NCMedia: UICollectionViewDataSource {
 
         guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as? NCGridMediaCell else { return UICollectionViewCell() }
 
-        if indexPath.section < collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section) && indexPath.row < NCImageCache.shared.metadatas.count {
+        if indexPath.section < collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section) && indexPath.row < self.metadatas.count {
 
-            let metadata = NCImageCache.shared.metadatas[indexPath.row]
+            let metadata = self.metadatas[indexPath.row]
 
             self.cellHeigth = cell.frame.size.height
 
@@ -401,7 +405,7 @@ extension NCMedia: UICollectionViewDataSource {
 
             if metadata.isAudioOrVideo {
                 cell.imageStatus.image = cacheImages.cellPlayImage
-            } else if metadata.livePhoto && NCImageCache.shared.livePhoto {
+            } else if metadata.livePhoto && NCImageCache.shared.isLivePhotoEnable {
                 cell.imageStatus.image = cacheImages.cellLivePhotoImage
             } else {
                 cell.imageStatus.image = nil
@@ -459,12 +463,12 @@ extension NCMedia {
         guard !appDelegate.account.isEmpty else { return }
 
         DispatchQueue.global().async {
-            NCImageCache.shared.getMediaMetadatas(account: self.appDelegate.account, predicate: self.getPredicate())
+            self.metadatas = NCImageCache.shared.getMediaMetadatas(account: self.appDelegate.account, predicate: self.getPredicate())
             DispatchQueue.main.sync {
                 self.reloadDataThenPerform {
                     self.updateMediaControlVisibility()
                     self.mediaCommandTitle()
-                    completion(NCImageCache.shared.metadatas)
+                    completion(self.metadatas)
                 }
             }
         }
@@ -472,7 +476,7 @@ extension NCMedia {
 
     func updateMediaControlVisibility() {
 
-        if NCImageCache.shared.metadatas.isEmpty {
+        if self.metadatas.isEmpty {
             if !self.showOnlyImages && !self.showOnlyVideos {
                 self.mediaCommandView?.toggleEmptyView(isEmpty: true)
                 self.mediaCommandView?.isHidden = false
@@ -581,7 +585,7 @@ extension NCMedia {
         if let visibleCells = self.collectionView?.indexPathsForVisibleItems.sorted(by: { $0.row < $1.row }).compactMap({ self.collectionView?.cellForItem(at: $0) }) {
             if let cell = visibleCells.first as? NCGridMediaCell {
                 if cell.date != nil {
-                    if cell.date != NCImageCache.shared.metadatas.first?.date as Date? {
+                    if cell.date != self.metadatas.first?.date as Date? {
                         lessDate = Calendar.current.date(byAdding: .second, value: 1, to: cell.date!)!
                         limit = 0
                     }
@@ -615,7 +619,7 @@ extension NCMedia {
                             self.reloadDataSourceWithCompletion { _ in }
                         }
                     }
-                } else if error == .success, files.isEmpty, NCImageCache.shared.metadatas.isEmpty {
+                } else if error == .success, files.isEmpty, self.metadatas.isEmpty {
                     self.searchOldMedia()
                 } else if error != .success {
                     NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Media search new media error code \(error.errorCode) " + error.errorDescription)

+ 1 - 1
iOSClient/Menu/NCMedia+Menu.swift

@@ -40,7 +40,7 @@ extension NCMedia {
         defer { presentMenu(with: actions) }
 
         if !isEditMode {
-            if !NCImageCache.shared.metadatas.isEmpty {
+            if !self.metadatas.isEmpty {
                 actions.append(
                     NCMenuAction(
                         title: NSLocalizedString("_select_", comment: ""),

+ 25 - 16
iOSClient/NCImageCache.swift

@@ -47,8 +47,11 @@ import NextcloudKit
         return ThumbnailLRUCache(countLimit: limit)
     }()
     private var ocIdEtag: [String: String] = [:]
-    public var metadatas: [tableMetadata] = []
-    public var livePhoto: Bool = false
+    private var metadatas: [tableMetadata]?
+    private var livePhoto: Bool = false
+    var isLivePhotoEnable: Bool {
+        return livePhoto
+    }
 
     override private init() {}
 
@@ -58,10 +61,10 @@ import NextcloudKit
         self.account = account
 
         ocIdEtag.removeAll()
-        metadatas.removeAll()
-        getMediaMetadatas(account: account)
+        self.metadatas = []
+        self.metadatas = getMediaMetadatas(account: account)
 
-        guard !metadatas.isEmpty else { return }
+        guard let metadatas = self.metadatas, !metadatas.isEmpty else { return }
         let ext = ".preview.ico"
         let manager = FileManager.default
         let resourceKeys = Set<URLResourceKey>([.nameKey, .pathKey, .fileSizeKey, .creationDateKey])
@@ -117,6 +120,12 @@ import NextcloudKit
         NextcloudKit.shared.nkCommonInstance.writeLog("--------- ThumbnailLRUCache image process ---------")
     }
 
+    func initialMetadatas() -> [tableMetadata]? {
+        let metadatas = self.metadatas
+        self.metadatas = nil
+        return metadatas
+    }
+
     func getMediaImage(ocId: String) -> ImageType? {
         return cache.value(forKey: ocId)
     }
@@ -127,35 +136,35 @@ import NextcloudKit
 
     @objc func clearMediaCache() {
 
-        ocIdEtag.removeAll()
-        metadatas.removeAll()
+        self.ocIdEtag.removeAll()
+        self.metadatas?.removeAll()
+        self.metadatas = nil
         cache.removeAllValues()
     }
 
-    func getMediaMetadatas(account: String, predicate: NSPredicate? = nil) {
+    func getMediaMetadatas(account: String, predicate: NSPredicate? = nil) -> [tableMetadata] {
 
-        guard let account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) else { return }
+        guard let account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) else { return [] }
         let startServerUrl = NCUtilityFileSystem().getHomeServer(urlBase: account.urlBase, userId: account.userId) + account.mediaPath
 
         let predicateDefault = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (classFile == %@ OR classFile == %@) AND NOT (session CONTAINS[c] 'upload')", account.account, startServerUrl, NKCommon.TypeClassFile.image.rawValue, NKCommon.TypeClassFile.video.rawValue)
 
         livePhoto = NCKeychain().livePhoto
 
-        let newMetadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate ?? predicateDefault, livePhoto: livePhoto)
-        if metadatas != newMetadatas {
-            metadatas = newMetadatas
-        }
+        var metadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate ?? predicateDefault, livePhoto: livePhoto)
 
         switch NCKeychain().mediaSortDate {
         case "date":
-            metadatas = self.metadatas.sorted(by: {($0.date as Date) > ($1.date as Date)})
+            metadatas = metadatas.sorted(by: {($0.date as Date) > ($1.date as Date)})
         case "creationDate":
-            metadatas = self.metadatas.sorted(by: {($0.creationDate as Date) > ($1.creationDate as Date)})
+            metadatas = metadatas.sorted(by: {($0.creationDate as Date) > ($1.creationDate as Date)})
         case "uploadDate":
-            metadatas = self.metadatas.sorted(by: {($0.uploadDate as Date) > ($1.uploadDate as Date)})
+            metadatas = metadatas.sorted(by: {($0.uploadDate as Date) > ($1.uploadDate as Date)})
         default:
             break
         }
+
+        return metadatas
     }
 
     // MARK: -

+ 20 - 11
iOSClient/Networking/NCNetworking.swift

@@ -1376,23 +1376,22 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
             for metadata in metadatas {
 
+                let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
                 NCManageDatabase.shared.deleteVideo(metadata: metadata)
                 NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
                 utilityFileSystem.removeFile(atPath: utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId))
 
-                if let metadataLivePhoto = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
-                    NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadataLivePhoto.ocId))
-                    utilityFileSystem.removeFile(atPath: utilityFileSystem.getDirectoryProviderStorageOcId(metadataLivePhoto.ocId))
+                if let metadataLive {
+                    NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadataLive.ocId))
+                    utilityFileSystem.removeFile(atPath: utilityFileSystem.getDirectoryProviderStorageOcId(metadataLive.ocId))
                 }
             }
             return NKError()
         }
 
-        let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
-
         if metadata.isDirectoryE2EE {
 #if !EXTENSION
-            if let metadataLive = metadataLive {
+            if let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata) {
                 let error = await NCNetworkingE2EEDelete().delete(metadata: metadataLive)
                 if error == .success {
                     return await NCNetworkingE2EEDelete().delete(metadata: metadata)
@@ -1406,7 +1405,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
             return NKError()
 #endif
         } else {
-            if let metadataLive = metadataLive {
+            if let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata) {
                 let error = await deleteMetadataPlain(metadataLive)
                 if error == .success {
                     return await deleteMetadataPlain(metadata)
@@ -1442,6 +1441,16 @@ class NCNetworking: NSObject, NKCommonDelegate {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
             NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
 
+            if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+                do {
+                    try FileManager.default.removeItem(atPath: utilityFileSystem.getDirectoryProviderStorageOcId(metadataLive.ocId))
+                } catch { }
+
+                NCManageDatabase.shared.deleteVideo(metadata: metadataLive)
+                NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadataLive.ocId))
+                NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadataLive.ocId))
+            }
+
             if metadata.directory {
                 NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: utilityFileSystem.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName), account: metadata.account)
             }
@@ -1454,7 +1463,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     func favoriteMetadata(_ metadata: tableMetadata, completion: @escaping (_ error: NKError) -> Void) {
 
-        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata) {
             favoriteMetadataPlain(metadataLive) { error in
                 if error == .success {
                     self.favoriteMetadataPlain(metadata, completion: completion)
@@ -1508,7 +1517,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath, viewController: UIViewController?, completion: @escaping (_ error: NKError) -> Void) {
 
-        let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
+        let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata)
         let fileNameNew = fileNameNew.trimmingCharacters(in: .whitespacesAndNewlines)
         let fileNameNewLive = (fileNameNew as NSString).deletingPathExtension + ".mov"
 
@@ -1615,7 +1624,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
-        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata) {
             let error = await moveMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
             if error == .success {
                 return await moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
@@ -1651,7 +1660,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
-        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.isMetadataLivePhoto(metadata: metadata) {
             let error = await copyMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
             if error == .success {
                 return await copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)