소스 검색

Image cache update (#2654)

Co-authored-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com>
Marino Faggiana 1 년 전
부모
커밋
c9dca10420
4개의 변경된 파일84개의 추가작업 그리고 51개의 파일을 삭제
  1. 31 13
      iOSClient/Media/NCMedia.swift
  2. 26 8
      iOSClient/Menu/NCMedia+Menu.swift
  3. 24 26
      iOSClient/NCImageCache.swift
  4. 3 4
      iOSClient/Supporting Files/en.lproj/Localizable.strings

+ 31 - 13
iOSClient/Media/NCMedia.swift

@@ -43,8 +43,8 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     internal var selectOcId: [String] = []
     internal var selectIndexPath: [IndexPath] = []
 
-    internal var filterClassTypeImage = false
-    internal var filterClassTypeVideo = false
+    internal var showOnlyImages = false
+    internal var showOnlyVideos = false
 
     private let maxImageGrid: CGFloat = 7
     private var cellHeigth: CGFloat = 0
@@ -104,6 +104,8 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
         cacheImages.cellLivePhotoImage = utility.loadImage(named: "livephoto", color: .white)
         cacheImages.cellPlayImage = utility.loadImage(named: "play.fill", color: .white)
+
+        if let activeAccount = NCManageDatabase.shared.getActiveAccount() { self.mediaPath = activeAccount.mediaPath }
     }
 
     override func viewWillAppear(_ animated: Bool) {
@@ -159,7 +161,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
               let error = userInfo["error"] as? NKError else { return }
         let onlyLocalCache: Bool = userInfo["onlyLocalCache"] as? Bool ?? false
 
-        NCImageCache.shared.getMediaMetadatas(account: appDelegate.account, filterClassTypeImage: filterClassTypeImage, filterClassTypeVideo: filterClassTypeVideo)
+        NCImageCache.shared.getMediaMetadatas(account: appDelegate.account, predicate: getPredicate())
 
         if error == .success, let indexPath = userInfo["indexPath"] as? [IndexPath], !indexPath.isEmpty, !onlyLocalCache {
             collectionView?.performBatchUpdates({
@@ -272,8 +274,8 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
         guard let serverUrl = serverUrl else { return }
         let home = utilityFileSystem.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId)
-        let path = serverUrl.replacingOccurrences(of: home, with: "")
-        NCManageDatabase.shared.setAccountMediaPath(path, account: appDelegate.account)
+        mediaPath = serverUrl.replacingOccurrences(of: home, with: "")
+        NCManageDatabase.shared.setAccountMediaPath(mediaPath, account: appDelegate.account)
         reloadDataSourceWithCompletion { _ in
             self.searchNewMedia()
         }
@@ -394,14 +396,14 @@ extension NCMedia: UICollectionViewDataSource {
                 cell.imageStatus.image = nil
             }
 
-            if let image = NCImageCache.shared.getMediaImage(ocId: metadata.ocId) {
+            if let cachedImage = NCImageCache.shared.getMediaImage(ocId: metadata.ocId), case let .actual(image) = cachedImage {
                 cell.imageItem.backgroundColor = nil
                 cell.imageItem.image = image
             } else if FileManager().fileExists(atPath: utilityFileSystem.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) {
                 if let image = UIImage(contentsOfFile: utilityFileSystem.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) {
                     cell.imageItem.backgroundColor = nil
                     cell.imageItem.image = image
-                    NCImageCache.shared.setMediaImage(ocId: metadata.ocId, image: image)
+                    NCImageCache.shared.setMediaImage(ocId: metadata.ocId, image: .actual(image))
                 }
             } else {
                 if metadata.hasPreview && metadata.status == NCGlobal.shared.metadataStatusNormal && (!utilityFileSystem.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
@@ -445,11 +447,26 @@ extension NCMedia: UICollectionViewDelegateFlowLayout {
 
 extension NCMedia {
 
+    func getPredicate(_ predicatedefault: Bool = false) -> NSPredicate {
+
+        let startServerUrl = NCUtilityFileSystem().getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) + mediaPath
+        let showAll = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (classFile == %@ OR classFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NKCommon.TypeClassFile.image.rawValue, NKCommon.TypeClassFile.video.rawValue)
+
+        if predicatedefault { return showAll }
+        if showOnlyImages {
+            return NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND classFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NKCommon.TypeClassFile.image.rawValue)
+        } else if showOnlyVideos {
+            return NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND classFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NKCommon.TypeClassFile.video.rawValue)
+        } else {
+           return showAll
+        }
+    }
+
     @objc func reloadDataSourceWithCompletion(_ completion: @escaping (_ metadatas: [tableMetadata]) -> Void) {
         guard !appDelegate.account.isEmpty else { return }
 
         DispatchQueue.global().async {
-            NCImageCache.shared.getMediaMetadatas(account: self.appDelegate.account, filterClassTypeImage: self.filterClassTypeImage, filterClassTypeVideo: self.filterClassTypeVideo)
+            NCImageCache.shared.getMediaMetadatas(account: self.appDelegate.account, predicate: self.getPredicate())
             DispatchQueue.main.sync {
                 self.reloadDataThenPerform {
                     self.updateMediaControlVisibility()
@@ -463,7 +480,7 @@ extension NCMedia {
     func updateMediaControlVisibility() {
 
         if NCImageCache.shared.metadatas.isEmpty {
-            if !self.filterClassTypeImage && !self.filterClassTypeVideo {
+            if !self.showOnlyImages && !self.showOnlyVideos {
                 self.mediaCommandView?.toggleEmptyView(isEmpty: true)
                 self.mediaCommandView?.isHidden = false
             } else {
@@ -491,7 +508,8 @@ extension NCMedia {
         }
 
         var lessDate = Date()
-        if let predicate = NCImageCache.shared.predicateDefault, let metadata = NCManageDatabase.shared.getMetadata(predicate: predicate, sorted: "date", ascending: true) {
+        let predicate = getPredicate()
+        if let metadata = NCManageDatabase.shared.getMetadata(predicate: predicate, sorted: "date", ascending: true) {
             lessDate = metadata.date as Date
         }
 
@@ -516,7 +534,7 @@ extension NCMedia {
                 if !files.isEmpty {
                     NCManageDatabase.shared.convertFilesToMetadatas(files, useMetadataFolder: false) { _, _, metadatas in
                         let predicateDate = NSPredicate(format: "date > %@ AND date < %@", greaterDate as NSDate, lessDate as NSDate)
-                        let predicateResult = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateDate, NCImageCache.shared.predicateDefault!])
+                        let predicateResult = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateDate, self.getPredicate(true)])
                         let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: predicateResult)
                         let metadatasChanged = NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult, addCompareLivePhoto: false)
                         if metadatasChanged.metadatasUpdate.isEmpty {
@@ -597,7 +615,7 @@ extension NCMedia {
                 if error == .success, account == self.appDelegate.account, !files.isEmpty {
                     NCManageDatabase.shared.convertFilesToMetadatas(files, useMetadataFolder: false) { _, _, metadatas in
                         let predicate = NSPredicate(format: "date > %@ AND date < %@", greaterDate as NSDate, lessDate as NSDate)
-                        let predicateResult = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, NCImageCache.shared.predicate!])
+                        let predicateResult = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, self.getPredicate(true)])
                         let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: predicateResult)
                         let updateMetadatas = NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult, addCompareLivePhoto: false)
                         if !updateMetadatas.metadatasUpdate.isEmpty || !updateMetadatas.metadatasDelete.isEmpty {
@@ -856,7 +874,7 @@ class NCMediaDownloadThumbnaill: ConcurrentOperation {
                         self.collectionView?.reloadData()
                     }
                 }
-                NCImageCache.shared.setMediaImage(ocId: self.metadata.ocId, image: image)
+                NCImageCache.shared.setMediaImage(ocId: self.metadata.ocId, image: .actual(image))
             }
             self.finish()
         }

+ 26 - 8
iOSClient/Menu/NCMedia+Menu.swift

@@ -52,15 +52,17 @@ extension NCMedia {
                 )
             }
 
+            actions.append(.seperator(order: 0))
+
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_media_viewimage_hide_", comment: ""),
+                    title: NSLocalizedString("_media_viewimage_show_", comment: ""),
                     icon: utility.loadImage(named: "photo"),
-                    selected: filterClassTypeImage,
+                    selected: showOnlyImages,
                     on: true,
                     action: { _ in
-                        self.filterClassTypeImage = !self.filterClassTypeImage
-                        self.filterClassTypeVideo = false
+                        self.showOnlyImages = true
+                        self.showOnlyVideos = false
                         self.reloadDataSourceWithCompletion { _ in }
                     }
                 )
@@ -68,18 +70,34 @@ extension NCMedia {
 
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_media_viewvideo_hide_", comment: ""),
+                    title: NSLocalizedString("_media_viewvideo_show_", comment: ""),
                     icon: utility.loadImage(named: "video"),
-                    selected: filterClassTypeVideo,
+                    selected: showOnlyVideos,
                     on: true,
                     action: { _ in
-                        self.filterClassTypeVideo = !self.filterClassTypeVideo
-                        self.filterClassTypeImage = false
+                        self.showOnlyImages = false
+                        self.showOnlyVideos = true
                         self.reloadDataSourceWithCompletion { _ in }
                     }
                 )
             )
 
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_media_show_all_", comment: ""),
+                    icon: utility.loadImage(named: "photo.on.rectangle.angled"),
+                    selected: !showOnlyImages && !showOnlyVideos,
+                    on: true,
+                    action: { _ in
+                        self.showOnlyImages = false
+                        self.showOnlyVideos = false
+                        self.reloadDataSourceWithCompletion { _ in }
+                    }
+                )
+            )
+
+            actions.append(.seperator(order: 0))
+
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_select_media_folder_", comment: ""),

+ 24 - 26
iOSClient/NCImageCache.swift

@@ -34,16 +34,22 @@ import NextcloudKit
     // MARK: -
 
     private let limit: Int = 1000
-    private typealias ThumbnailLRUCache = LRUCache<String, UIImage>
+
+    enum ImageType {
+        case placeholder
+        case actual(_ image: UIImage)
+    }
+
+    private typealias ThumbnailLRUCache = LRUCache<String, ImageType>
     private lazy var cache: ThumbnailLRUCache = {
         return ThumbnailLRUCache(countLimit: limit)
     }()
     private var ocIdEtag: [String: String] = [:]
     public var metadatas: [tableMetadata] = []
-    public var predicateDefault: NSPredicate?
-    public var predicate: NSPredicate?
     public var livePhoto: Bool = false
 
+    override private init() {}
+
     func createMediaCache(account: String) {
 
         ocIdEtag.removeAll()
@@ -71,11 +77,11 @@ import NextcloudKit
                 let fileName = fileURL.lastPathComponent
                 let ocId = fileURL.deletingLastPathComponent().lastPathComponent
                 guard let resourceValues = try? fileURL.resourceValues(forKeys: resourceKeys),
-                        let size = resourceValues.fileSize,
-                        size > 0,
-                        let date = resourceValues.creationDate,
-                        let etag = ocIdEtag[ocId],
-                        fileName == etag + ext else { continue }
+                      let size = resourceValues.fileSize,
+                      size > 0,
+                      let date = resourceValues.creationDate,
+                      let etag = ocIdEtag[ocId],
+                      fileName == etag + ext else { continue }
                 files.append(FileInfo(path: fileURL, ocId: ocId, date: date))
             }
         }
@@ -93,7 +99,7 @@ import NextcloudKit
             if counter > limit { break }
             autoreleasepool {
                 if let image = UIImage(contentsOfFile: file.path.path) {
-                    cache.setValue(image, forKey: file.ocId)
+                    cache.setValue(.actual(image), forKey: file.ocId)
                 }
             }
         }
@@ -106,13 +112,11 @@ import NextcloudKit
         NextcloudKit.shared.nkCommonInstance.writeLog("--------- ThumbnailLRUCache image process ---------")
     }
 
-    func getMediaImage(ocId: String) -> UIImage? {
-
+    func getMediaImage(ocId: String) -> ImageType? {
         return cache.value(forKey: ocId)
     }
 
-    func setMediaImage(ocId: String, image: UIImage) {
-
+    func setMediaImage(ocId: String, image: ImageType) {
         cache.setValue(image, forKey: ocId)
     }
 
@@ -123,25 +127,19 @@ import NextcloudKit
         cache.removeAllValues()
     }
 
-    func getMediaMetadatas(account: String, filterClassTypeImage: Bool = false, filterClassTypeVideo: Bool = false) {
+    func getMediaMetadatas(account: String, predicate: NSPredicate? = nil) {
 
         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
 
-        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)
-
-        if filterClassTypeImage {
-            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND classFile == %@ AND NOT (session CONTAINS[c] 'upload')", account.account, startServerUrl, NKCommon.TypeClassFile.video.rawValue)
-        } else if filterClassTypeVideo {
-            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND classFile == %@ AND NOT (session CONTAINS[c] 'upload')", account.account, startServerUrl, NKCommon.TypeClassFile.image.rawValue)
-        } else {
-            predicate = predicateDefault
-        }
-
-        guard let predicate = predicate else { return }
+        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
-        metadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate, livePhoto: livePhoto)
+
+        let newMetadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate ?? predicateDefault, livePhoto: livePhoto)
+        if metadatas != newMetadatas {
+            metadatas = newMetadatas
+        }
 
         switch NCKeychain().mediaSortDate {
         case "date":

+ 3 - 4
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -587,10 +587,9 @@
 "_status_uploading_"            = "Uploading";
 "_status_upload_error_"         = "Error, waiting for upload";
 "_select_media_folder_"         = "Select the \"Media\" folder";
-"_media_viewimage_show_"        = "Show images";
-"_media_viewimage_hide_"        = "Hide images";
-"_media_viewvideo_show_"        = "Show video";
-"_media_viewvideo_hide_"        = "Hide video";
+"_media_viewimage_show_"        = "Show only images";
+"_media_viewvideo_show_"        = "Show only video";
+"_media_show_all_"              = "Show both";
 "_media_by_created_date_"       = "Sort by created date";
 "_media_by_upload_date_"        = "Sort by upload date";
 "_media_by_modified_date_"      = "Sort by modified date";