Pārlūkot izejas kodu

Merge branch 'develop' into secureFileDrop

Marino Faggiana 2 gadi atpakaļ
vecāks
revīzija
767c8ff38b
100 mainītis faili ar 282 papildinājumiem un 295 dzēšanām
  1. 2 2
      Nextcloud.xcodeproj/project.pbxproj
  2. 4 6
      Share/NCShareExtension+DataSource.swift
  3. 1 14
      iOSClient/Data/NCDataSource.swift
  4. 85 1
      iOSClient/Data/NCManageDatabase+Metadata.swift
  5. 10 9
      iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
  6. 10 1
      iOSClient/Main/Create cloud/NCUploadAssets.swift
  7. 1 1
      iOSClient/Media/NCMedia.swift
  8. 41 48
      iOSClient/Menu/NCCollectionViewCommon+Menu.swift
  9. 57 134
      iOSClient/Menu/NCContextMenu.swift
  10. 39 40
      iOSClient/Menu/NCViewer+Menu.swift
  11. 4 7
      iOSClient/Networking/NCNetworking.swift
  12. 4 4
      iOSClient/Networking/NCNetworkingProcessUpload.swift
  13. 1 1
      iOSClient/Networking/NCOperationQueue.swift
  14. 1 12
      iOSClient/Networking/NCService.swift
  15. 10 1
      iOSClient/Scan document/NCUploadScanDocument.swift
  16. 12 14
      iOSClient/Select/NCSelect.swift
  17. BIN
      iOSClient/Supporting Files/af.lproj/Localizable.strings
  18. BIN
      iOSClient/Supporting Files/an.lproj/Localizable.strings
  19. BIN
      iOSClient/Supporting Files/ar.lproj/Localizable.strings
  20. BIN
      iOSClient/Supporting Files/ast.lproj/Localizable.strings
  21. BIN
      iOSClient/Supporting Files/az.lproj/Localizable.strings
  22. BIN
      iOSClient/Supporting Files/be.lproj/Localizable.strings
  23. BIN
      iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings
  24. BIN
      iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings
  25. BIN
      iOSClient/Supporting Files/br.lproj/Localizable.strings
  26. BIN
      iOSClient/Supporting Files/bs.lproj/Localizable.strings
  27. BIN
      iOSClient/Supporting Files/ca.lproj/Localizable.strings
  28. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings
  29. BIN
      iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings
  30. BIN
      iOSClient/Supporting Files/da.lproj/Localizable.strings
  31. BIN
      iOSClient/Supporting Files/de.lproj/Localizable.strings
  32. BIN
      iOSClient/Supporting Files/el.lproj/Localizable.strings
  33. BIN
      iOSClient/Supporting Files/en-GB.lproj/Localizable.strings
  34. BIN
      iOSClient/Supporting Files/eo.lproj/Localizable.strings
  35. BIN
      iOSClient/Supporting Files/es-419.lproj/Localizable.strings
  36. BIN
      iOSClient/Supporting Files/es-AR.lproj/Localizable.strings
  37. BIN
      iOSClient/Supporting Files/es-CL.lproj/Localizable.strings
  38. BIN
      iOSClient/Supporting Files/es-CO.lproj/Localizable.strings
  39. BIN
      iOSClient/Supporting Files/es-CR.lproj/Localizable.strings
  40. BIN
      iOSClient/Supporting Files/es-DO.lproj/Localizable.strings
  41. BIN
      iOSClient/Supporting Files/es-EC.lproj/Localizable.strings
  42. BIN
      iOSClient/Supporting Files/es-GT.lproj/Localizable.strings
  43. BIN
      iOSClient/Supporting Files/es-HN.lproj/Localizable.strings
  44. BIN
      iOSClient/Supporting Files/es-MX.lproj/Localizable.strings
  45. BIN
      iOSClient/Supporting Files/es-NI.lproj/Localizable.strings
  46. BIN
      iOSClient/Supporting Files/es-PA.lproj/Localizable.strings
  47. BIN
      iOSClient/Supporting Files/es-PE.lproj/Localizable.strings
  48. BIN
      iOSClient/Supporting Files/es-PR.lproj/Localizable.strings
  49. BIN
      iOSClient/Supporting Files/es-PY.lproj/Localizable.strings
  50. BIN
      iOSClient/Supporting Files/es-SV.lproj/Localizable.strings
  51. BIN
      iOSClient/Supporting Files/es-UY.lproj/Localizable.strings
  52. BIN
      iOSClient/Supporting Files/es.lproj/Localizable.strings
  53. BIN
      iOSClient/Supporting Files/et_EE.lproj/Localizable.strings
  54. BIN
      iOSClient/Supporting Files/eu.lproj/Localizable.strings
  55. BIN
      iOSClient/Supporting Files/fa.lproj/Localizable.strings
  56. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings
  57. BIN
      iOSClient/Supporting Files/fo.lproj/Localizable.strings
  58. BIN
      iOSClient/Supporting Files/fr.lproj/Localizable.strings
  59. BIN
      iOSClient/Supporting Files/gd.lproj/Localizable.strings
  60. BIN
      iOSClient/Supporting Files/gl.lproj/Localizable.strings
  61. BIN
      iOSClient/Supporting Files/he.lproj/Localizable.strings
  62. BIN
      iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings
  63. BIN
      iOSClient/Supporting Files/hr.lproj/Localizable.strings
  64. BIN
      iOSClient/Supporting Files/hsb.lproj/Localizable.strings
  65. BIN
      iOSClient/Supporting Files/hu.lproj/Localizable.strings
  66. BIN
      iOSClient/Supporting Files/hy.lproj/Localizable.strings
  67. BIN
      iOSClient/Supporting Files/ia.lproj/Localizable.strings
  68. BIN
      iOSClient/Supporting Files/id.lproj/Localizable.strings
  69. BIN
      iOSClient/Supporting Files/ig.lproj/Localizable.strings
  70. BIN
      iOSClient/Supporting Files/is.lproj/Localizable.strings
  71. BIN
      iOSClient/Supporting Files/it.lproj/InfoPlist.strings
  72. BIN
      iOSClient/Supporting Files/it.lproj/Localizable.strings
  73. BIN
      iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings
  74. BIN
      iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings
  75. BIN
      iOSClient/Supporting Files/ka.lproj/Localizable.strings
  76. BIN
      iOSClient/Supporting Files/kab.lproj/Localizable.strings
  77. BIN
      iOSClient/Supporting Files/km.lproj/Localizable.strings
  78. BIN
      iOSClient/Supporting Files/kn.lproj/Localizable.strings
  79. BIN
      iOSClient/Supporting Files/ko.lproj/Localizable.strings
  80. BIN
      iOSClient/Supporting Files/la.lproj/Localizable.strings
  81. BIN
      iOSClient/Supporting Files/lb.lproj/Localizable.strings
  82. BIN
      iOSClient/Supporting Files/lo.lproj/Localizable.strings
  83. BIN
      iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings
  84. BIN
      iOSClient/Supporting Files/lv.lproj/Localizable.strings
  85. BIN
      iOSClient/Supporting Files/mk.lproj/Localizable.strings
  86. BIN
      iOSClient/Supporting Files/mn.lproj/Localizable.strings
  87. BIN
      iOSClient/Supporting Files/mr.lproj/Localizable.strings
  88. BIN
      iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings
  89. BIN
      iOSClient/Supporting Files/my.lproj/Localizable.strings
  90. BIN
      iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings
  91. BIN
      iOSClient/Supporting Files/ne.lproj/Localizable.strings
  92. BIN
      iOSClient/Supporting Files/nl.lproj/Localizable.strings
  93. BIN
      iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings
  94. BIN
      iOSClient/Supporting Files/oc.lproj/Localizable.strings
  95. BIN
      iOSClient/Supporting Files/pl.lproj/Localizable.strings
  96. BIN
      iOSClient/Supporting Files/ps.lproj/Localizable.strings
  97. BIN
      iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings
  98. BIN
      iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings
  99. BIN
      iOSClient/Supporting Files/ro.lproj/Localizable.strings
  100. BIN
      iOSClient/Supporting Files/ru.lproj/Localizable.strings

+ 2 - 2
Nextcloud.xcodeproj/project.pbxproj

@@ -3762,7 +3762,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 5;
+				CURRENT_PROJECT_VERSION = 7;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
@@ -3825,7 +3825,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 5;
+				CURRENT_PROJECT_VERSION = 7;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;

+ 4 - 6
Share/NCShareExtension+DataSource.swift

@@ -114,16 +114,14 @@ extension NCShareExtension: UICollectionViewDataSource {
             isMounted = metadata.permissions.contains(NCGlobal.shared.permissionMounted) && !metadataFolder.permissions.contains(NCGlobal.shared.permissionMounted)
         }
 
-        let tableShare = dataSource.metadatasForSection[indexPath.section].metadataShare[metadata.ocId]
-
         if metadata.e2eEncrypted {
             cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
         } else if isShare {
             cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-        } else if tableShare != nil && tableShare?.shareType != 3 {
-            cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-        } else if tableShare != nil && tableShare?.shareType == 3 {
-            cell.imageItem.image = NCBrandColor.cacheImages.folderPublic
+        } else if !metadata.shareType.isEmpty {
+            metadata.shareType.contains(3) ?
+            (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
+            (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
         } else if metadata.mountType == "group" {
             cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
         } else if isMounted {

+ 1 - 14
iOSClient/Data/NCDataSource.swift

@@ -35,7 +35,6 @@ class NCDataSource: NSObject {
     private var sectionsValue: [String] = []
     private var providers: [NKSearchProvider]?
     private var searchResults: [NKSearchResult]?
-    private var shares: [tableShare] = []
     private var localFiles: [tableLocalFile] = []
 
     private var ascending: Bool = true
@@ -55,7 +54,6 @@ class NCDataSource: NSObject {
             !NCGlobal.shared.includeHiddenFiles.contains($0.fileNameView)
         })
         self.directory = directory
-        self.shares = NCManageDatabase.shared.getTableShares(account: account)
         self.localFiles = NCManageDatabase.shared.getTableLocalFile(account: account)
         self.sort = sort ?? "none"
         self.ascending = ascending ?? false
@@ -80,7 +78,6 @@ class NCDataSource: NSObject {
         self.sectionsValue.removeAll()
         self.providers = nil
         self.searchResults = nil
-        self.shares.removeAll()
         self.localFiles.removeAll()
     }
 
@@ -178,7 +175,6 @@ class NCDataSource: NSObject {
         let metadatas = self.metadatas.filter({ getSectionValue(metadata: $0) == sectionValue})
         let metadataForSection = NCMetadataForSection.init(sectionValue: sectionValue,
                                                             metadatas: metadatas,
-                                                            shares: self.shares,
                                                             localFiles: self.localFiles,
                                                             lastSearchResult: searchResult,
                                                             sort: self.sort,
@@ -423,7 +419,6 @@ class NCMetadataForSection: NSObject {
 
     var sectionValue: String
     var metadatas: [tableMetadata]
-    var shares: [tableShare]
     var localFiles: [tableLocalFile]
     var lastSearchResult: NKSearchResult?
     var unifiedSearchInProgress: Bool = false
@@ -443,15 +438,13 @@ class NCMetadataForSection: NSObject {
     public var numDirectory: Int = 0
     public var numFile: Int = 0
     public var totalSize: Int64 = 0
-    public let metadataShare  = ThreadSafeDictionary<String,tableShare>()
     public var metadataOffLine: [String] = []
     public var directories: [tableDirectory]?
 
-    init(sectionValue: String, metadatas: [tableMetadata], shares: [tableShare], localFiles: [tableLocalFile], lastSearchResult: NKSearchResult?, sort: String, ascending: Bool, directoryOnTop: Bool, favoriteOnTop: Bool, filterLivePhoto: Bool) {
+    init(sectionValue: String, metadatas: [tableMetadata], localFiles: [tableLocalFile], lastSearchResult: NKSearchResult?, sort: String, ascending: Bool, directoryOnTop: Bool, favoriteOnTop: Bool, filterLivePhoto: Bool) {
 
         self.sectionValue = sectionValue
         self.metadatas = metadatas
-        self.shares = shares
         self.localFiles = localFiles
         self.lastSearchResult = lastSearchResult
         self.sort = sort
@@ -474,7 +467,6 @@ class NCMetadataForSection: NSObject {
         metadatasFavoriteFile.removeAll()
         metadatasDirectory.removeAll()
         metadatasFile.removeAll()
-        metadataShare.removeAll()
         metadataOffLine.removeAll()
 
         numDirectory = 0
@@ -538,11 +530,6 @@ class NCMetadataForSection: NSObject {
                 continue
             }
 
-            // share
-            if let share = self.shares.filter({ $0.serverUrl == metadata.serverUrl && $0.fileName == metadata.fileName }).first {
-                metadataShare[metadata.ocId] = share
-            }
-
             // Organized the metadata
             if metadata.favorite && favoriteOnTop {
                 if metadata.directory {

+ 85 - 1
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -111,8 +111,88 @@ extension tableMetadata {
 
     var fileNoExtension: String { (fileNameView as NSString).deletingPathExtension }
 
+    var isRenameable: Bool {
+        if lock || isViewOnly {
+            return false
+        }
+        if !isDirectoryE2EE && e2eEncrypted {
+            return false
+        }
+        return true
+    }
+    
     var isPrintable: Bool {
-        classFile == NKCommon.typeClassFile.image.rawValue || ["application/pdf", "com.adobe.pdf"].contains(contentType) || contentType.hasPrefix("text/")
+        if classFile == NKCommon.typeClassFile.image.rawValue {
+            return true
+        }
+        if isViewOnly {
+            return false
+        }
+        if ["application/pdf", "com.adobe.pdf"].contains(contentType) || contentType.hasPrefix("text/") {
+            return true
+        }
+        return false
+    }
+
+    var isSaveInCameraRoll: Bool {
+        return (classFile == NKCommon.typeClassFile.image.rawValue && contentType != "image/svg+xml") || classFile == NKCommon.typeClassFile.video.rawValue
+    }
+
+    var isViewOnly: Bool {
+        sharePermissionsCollaborationServices == NCGlobal.shared.permissionReadShare && classFile == NKCommon.typeClassFile.document.rawValue
+    }
+
+    var isSaveAsScan: Bool {
+        classFile == NKCommon.typeClassFile.image.rawValue && contentType != "image/svg+xml"
+    }
+
+    var isCopyableInPasteboard: Bool {
+        !isViewOnly && !directory
+    }
+
+    var isCopyableMovable: Bool {
+        !isViewOnly && !isDirectoryE2EE && !e2eEncrypted
+    }
+
+    var isModifiableWithQuickLook: Bool {
+        if directory || isViewOnly || isDirectoryE2EE {
+            return false
+        }
+        return contentType == "com.adobe.pdf" || contentType == "application/pdf" || classFile == NKCommon.typeClassFile.image.rawValue
+    }
+
+    var isDeletable: Bool {
+        if !isDirectoryE2EE && e2eEncrypted {
+            return false
+        }
+        return true
+    }
+
+    var isSettableOnOffline: Bool {
+        return session.isEmpty && !isViewOnly
+    }
+
+    var canOpenIn: Bool {
+        return session.isEmpty && !isViewOnly && !directory && !NCBrandOptions.shared.disable_openin_file
+    }
+
+    var isDirectoySettableE2EE: Bool {
+        return directory && size == 0 && !e2eEncrypted && CCUtility.isEnd(toEndEnabled: account)
+    }
+
+    var isDirectoryUnsettableE2EE: Bool {
+        return !isDirectoryE2EE && directory && size == 0 && e2eEncrypted && CCUtility.isEnd(toEndEnabled: account)
+    }
+
+    var canOpenExternalEditor: Bool {
+        if isViewOnly {
+            return false
+        }
+
+        let editors = NCUtility.shared.isDirectEditing(account: account, contentType: contentType)
+        let isRichDocument = NCUtility.shared.isRichDocument(self)
+
+        return classFile == NKCommon.typeClassFile.document.rawValue && editors.contains(NCGlobal.shared.editorText) && ((editors.contains(NCGlobal.shared.editorOnlyoffice) || isRichDocument))
     }
 
     var isDownloadUpload: Bool {
@@ -127,6 +207,10 @@ extension tableMetadata {
         status == NCGlobal.shared.metadataStatusInUpload || status == NCGlobal.shared.metadataStatusUploading
     }
 
+    @objc var isDirectoryE2EE: Bool {
+        NCUtility.shared.isDirectoryE2EE(serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId)
+    }
+
     /// Returns false if the user is lokced out of the file. I.e. The file is locked but by somone else
     func canUnlock(as user: String) -> Bool {
         return !lock || (lockOwner == user && lockOwnerType == 0)

+ 10 - 9
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -1366,7 +1366,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
 
         }, actionProvider: { _ in
 
-            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, enableDeleteLocal: true, enableViewInFolder: false, image: image)
+            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, image: image)
         })
     }
 
@@ -1474,7 +1474,6 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
 
         guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return cell }
 
-        let tableShare = dataSource.metadatasForSection[indexPath.section].metadataShare[metadata.ocId]
         let tableDirectory = dataSource.metadatasForSection[indexPath.section].directories?.filter({ $0.ocId == metadata.ocId }).first
         var isShare = false
         var isMounted = false
@@ -1531,9 +1530,11 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
                 cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderEncrypted
             } else if isShare {
                 cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderSharedWithMe
-            } else if tableShare != nil && tableShare?.shareType != 3 {
-                cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderSharedWithMe
-            } else if tableShare != nil && tableShare?.shareType == 3 {
+            } else if !metadata.shareType.isEmpty {
+                metadata.shareType.contains(3) ?
+                (cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderPublic) :
+                (cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderSharedWithMe)
+            } else if !metadata.shareType.isEmpty && metadata.shareType.contains(3)  {
                 cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderPublic
             } else if metadata.mountType == "group" {
                 cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderGroup
@@ -1573,10 +1574,10 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         // Share image
         if isShare {
             cell.fileSharedImage?.image = NCBrandColor.cacheImages.shared
-        } else if tableShare != nil && tableShare?.shareType == 3 {
-            cell.fileSharedImage?.image = NCBrandColor.cacheImages.shareByLink
-        } else if tableShare != nil && tableShare?.shareType != 3 {
-            cell.fileSharedImage?.image = NCBrandColor.cacheImages.shared
+        } else if !metadata.shareType.isEmpty {
+            metadata.shareType.contains(3) ?
+            (cell.fileSharedImage?.image = NCBrandColor.cacheImages.shareByLink) :
+            (cell.fileSharedImage?.image = NCBrandColor.cacheImages.shared)
         } else {
             cell.fileSharedImage?.image = NCBrandColor.cacheImages.canShare
         }

+ 10 - 1
iOSClient/Main/Create cloud/NCUploadAssets.swift

@@ -145,6 +145,15 @@ struct UploadAssetsView: View {
         }
     }
 
+    func getTextServerUrl(_ serverUrl: String) -> String {
+
+        if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", uploadAssets.userBaseUrl.account, serverUrl)), let metadata = NCManageDatabase.shared.getMetadataFromOcId(directory.ocId) {
+            return (metadata.fileNameView)
+        } else {
+            return (serverUrl as NSString).lastPathComponent
+        }
+    }
+
     func setFileNameMask(fileName: String?) -> String {
 
         guard let asset = uploadAssets.assets.first?.phAsset else { return "" }
@@ -354,7 +363,7 @@ struct UploadAssetsView: View {
                                 Text("/")
                                     .frame(maxWidth: .infinity, alignment: .trailing)
                             } else {
-                                Text((uploadAssets.serverUrl as NSString).lastPathComponent)
+                                Text(self.getTextServerUrl(uploadAssets.serverUrl))
                                     .frame(maxWidth: .infinity, alignment: .trailing)
                             }
                         } icon: {

+ 1 - 1
iOSClient/Media/NCMedia.swift

@@ -329,7 +329,7 @@ extension NCMedia: UICollectionViewDelegate {
         return UIContextMenuConfiguration(identifier: identifier, previewProvider: {
             return NCViewerProviderContextMenu(metadata: metadata, image: image)
         }, actionProvider: { _ in
-            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, enableDeleteLocal: false, enableViewInFolder: true, image: image)
+            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, image: image)
         })
     }
 

+ 41 - 48
iOSClient/Menu/NCCollectionViewCommon+Menu.swift

@@ -38,7 +38,6 @@ extension NCCollectionViewCommon {
 
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadata.ocId) else { return }
         let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-        let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
         let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId)
         let isOffline: Bool
 
@@ -73,6 +72,22 @@ extension NCCollectionViewCommon {
             )
         )
 
+        //
+        // DETAILS
+        //
+        if !appDelegate.disableSharesView {
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_details_", comment: ""),
+                    icon: NCUtility.shared.loadImage(named: "info"),
+                    order: 10,
+                    action: { _ in
+                        NCFunctionCenter.shared.openShare(viewController: self, metadata: metadata, indexPage: .activity)
+                    }
+                )
+            )
+        }
+
         if metadata.lock {
             var lockOwnerName = metadata.lockOwnerDisplayName.isEmpty ? metadata.lockOwner : metadata.lockOwnerDisplayName
             var lockIcon = NCUtility.shared.loadUserImage(for: metadata.lockOwner, displayName: lockOwnerName, userBaseUrl: metadata)
@@ -101,7 +116,7 @@ extension NCCollectionViewCommon {
                     title: String(format: NSLocalizedString("_locked_by_", comment: ""), lockOwnerName),
                     details: lockTimeString,
                     icon: lockIcon,
-                    order: 10,
+                    order: 20,
                     action: nil)
             )
         }
@@ -111,19 +126,18 @@ extension NCCollectionViewCommon {
         //
         let hasLockCapability = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesFilesLockVersion) >= 1
         if !metadata.directory, metadata.canUnlock(as: appDelegate.userId), hasLockCapability {
-            actions.append(NCMenuAction.lockUnlockFiles(shouldLock: !metadata.lock, metadatas: [metadata], order: 15))
+            actions.append(NCMenuAction.lockUnlockFiles(shouldLock: !metadata.lock, metadatas: [metadata], order: 30))
         }
 
         //
         // SET FOLDER E2EE (ONLY ROOT)
         //
-        //if !isDirectoryE2EE && metadata.directory && metadata.size == 0 && !metadata.e2eEncrypted && CCUtility.isEnd(toEndEnabled: appDelegate.account) {
-        if metadata.serverUrl == serverUrlHome && metadata.directory && metadata.size == 0 && !metadata.e2eEncrypted && CCUtility.isEnd(toEndEnabled: appDelegate.account) {
+        if metadata.serverUrl == serverUrlHome, metadata.isDirectoySettableE2EE {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_e2e_set_folder_encrypted_", comment: ""),
                     icon: NCUtility.shared.loadImage(named: "lock"),
-                    order: 15,
+                    order: 30,
                     action: { _ in
                         NextcloudKit.shared.markE2EEFolder(fileId: metadata.fileId, delete: false) { account, error in
                             if error == .success {
@@ -144,12 +158,12 @@ extension NCCollectionViewCommon {
         //
         // UNSET FOLDER E2EE
         //
-        if !isDirectoryE2EE && metadata.directory && metadata.size == 0 && metadata.e2eEncrypted && CCUtility.isEnd(toEndEnabled: appDelegate.account) {
+        if metadata.isDirectoryUnsettableE2EE {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_e2e_remove_folder_encrypted_", comment: ""),
                     icon: NCUtility.shared.loadImage(named: "lock"),
-                    order: 15,
+                    order: 30,
                     action: { _ in
                         NextcloudKit.shared.markE2EEFolder(fileId: metadata.fileId, delete: true) { account, error in
                             if error == .success {
@@ -167,8 +181,7 @@ extension NCCollectionViewCommon {
             )
         }
 
-
-        actions.append(.seperator(order: 20))
+        actions.append(.seperator(order: 40))
 
         //
         // FAVORITE
@@ -179,7 +192,7 @@ extension NCCollectionViewCommon {
                 NCMenuAction(
                     title: metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: ""),
                     icon: NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite),
-                    order: 30,
+                    order: 50,
                     action: { _ in
                         NCNetworking.shared.favoriteMetadata(metadata) { error in
                             if error != .success {
@@ -191,33 +204,19 @@ extension NCCollectionViewCommon {
             )
         }
 
-        //
-        // DETAILS
-        //
-        if !appDelegate.disableSharesView {
-            actions.append(
-                NCMenuAction(
-                    title: NSLocalizedString("_details_", comment: ""),
-                    icon: NCUtility.shared.loadImage(named: "info"),
-                    order: 40,
-                    action: { _ in
-                        NCFunctionCenter.shared.openShare(viewController: self, metadata: metadata, indexPage: .activity)
-                    }
-                )
-            )
-        }
-
         //
         // OFFLINE
         //
-        actions.append(.setAvailableOfflineAction(selectedMetadatas: [metadata], isAnyOffline: isOffline, viewController: self, order: 60, completion: {
-            self.reloadDataSource()
-        }))
+        if metadata.isSettableOnOffline {
+            actions.append(.setAvailableOfflineAction(selectedMetadatas: [metadata], isAnyOffline: isOffline, viewController: self, order: 60, completion: {
+                self.reloadDataSource()
+            }))
+        }
 
         //
         // OPEN with external editor
         //
-        if metadata.classFile == NKCommon.typeClassFile.document.rawValue && editors.contains(NCGlobal.shared.editorText) && ((editors.contains(NCGlobal.shared.editorOnlyoffice) || isRichDocument)) {
+        if metadata.canOpenExternalEditor {
 
             var editor = ""
             var title = ""
@@ -250,7 +249,7 @@ extension NCCollectionViewCommon {
         //
         // OPEN IN
         //
-        if !metadata.directory && !NCBrandOptions.shared.disable_openin_file {
+        if metadata.canOpenIn {
             actions.append(.openInAction(selectedMetadatas: [metadata], viewController: self, order: 80))
         }
 
@@ -262,16 +261,16 @@ extension NCCollectionViewCommon {
         }
 
         //
-        // SAVE
+        // SAVE CAMERA ROLL
         //
-        if (metadata.classFile == NKCommon.typeClassFile.image.rawValue && metadata.contentType != "image/svg+xml") || metadata.classFile == NKCommon.typeClassFile.video.rawValue {
+        if metadata.isSaveInCameraRoll {
             actions.append(.saveMediaAction(selectedMediaMetadatas: [metadata], order: 100))
         }
 
         //
         // SAVE AS SCAN
         //
-        if metadata.classFile == NKCommon.typeClassFile.image.rawValue && metadata.contentType != "image/svg+xml" {
+        if metadata.isSaveAsScan {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_save_as_scan_", comment: ""),
@@ -287,9 +286,7 @@ extension NCCollectionViewCommon {
         //
         // RENAME
         //
-        if (!isDirectoryE2EE && metadata.e2eEncrypted) || metadata.lock {
-            print("Not possible rename")
-        } else {
+        if metadata.isRenameable {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_rename_", comment: ""),
@@ -314,23 +311,21 @@ extension NCCollectionViewCommon {
         //
         // COPY - MOVE
         //
-        if isDirectoryE2EE || metadata.e2eEncrypted {
-            print("Not possible copy/move")
-        } else {
+        if metadata.isCopyableMovable {
             actions.append(.moveOrCopyAction(selectedMetadatas: [metadata], order: 130))
         }
 
         //
-        // COPY
+        // COPY IN PASTEBOARD
         //
-        if !metadata.directory {
+        if metadata.isCopyableInPasteboard {
             actions.append(.copyAction(selectOcId: [metadata.ocId], hudView: self.view, order: 140))
         }
         
         //
-        // MODIFY
+        // MODIFY WITH QUICK LOOK
         //
-        if !isDirectoryE2EE && metadata.contentType != "image/gif" && metadata.contentType != "image/svg+xml" && (metadata.contentType == "com.adobe.pdf" || metadata.contentType == "application/pdf" || metadata.classFile == NKCommon.typeClassFile.image.rawValue) {
+        if metadata.isModifiableWithQuickLook {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_modify_", comment: ""),
@@ -367,9 +362,7 @@ extension NCCollectionViewCommon {
         //
         // DELETE
         //
-        if !isDirectoryE2EE && metadata.e2eEncrypted {
-            print("Not possible delete")
-        } else {
+        if metadata.isDeletable {
             actions.append(.deleteAction(selectedMetadatas: [metadata], metadataFolder: metadataFolder, viewController: self, order: 170))
         }
 

+ 57 - 134
iOSClient/Menu/NCContextMenu.swift

@@ -26,62 +26,43 @@ import NextcloudKit
 
 class NCContextMenu: NSObject {
 
-    func viewMenu(ocId: String, viewController: UIViewController, enableDeleteLocal: Bool, enableViewInFolder: Bool, image: UIImage?) -> UIMenu {
+    func viewMenu(ocId: String, viewController: UIViewController, image: UIImage?) -> UIMenu {
 
         let appDelegate = UIApplication.shared.delegate as? AppDelegate
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
             return UIMenu()
         }
 
-        let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
         var titleDeleteConfirmFile = NSLocalizedString("_delete_file_", comment: "")
         if metadata.directory { titleDeleteConfirmFile = NSLocalizedString("_delete_folder_", comment: "") }
+
         var titleSave: String = NSLocalizedString("_save_selected_files_", comment: "")
         let metadataMOV = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
         if metadataMOV != nil {
             titleSave = NSLocalizedString("_livephoto_save_", comment: "")
         }
-        let titleFavorite = metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: "")
-
-        let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-        var isOffline = false
-        if metadata.directory {
-            if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate!.account, serverUrl)) {
-                isOffline = directory.offline
-            }
-        } else {
-            if let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) {
-                isOffline = localFile.offline
-            }
-        }
-        let titleOffline = isOffline ? NSLocalizedString("_remove_available_offline_", comment: "") : NSLocalizedString("_set_available_offline_", comment: "")
-        let titleLock = metadata.lock ? NSLocalizedString("_unlock_file_", comment: "") : NSLocalizedString("_lock_file_", comment: "")
-        let iconLock = metadata.lock ? "lock.open" : "lock"
-        let copy = UIAction(title: NSLocalizedString("_copy_file_", comment: ""), image: UIImage(systemName: "doc.on.doc")) { _ in
-            NCFunctionCenter.shared.copyPasteboard(pasteboardOcIds: [metadata.ocId], hudView: viewController.view)
-        }
-
-        let copyPath = UIAction(title: NSLocalizedString("_copy_path_", comment: ""), image: UIImage(systemName: "doc.on.clipboard")) { _ in
-            let board = UIPasteboard.general
-            board.string = NCUtilityFileSystem.shared.getPath(path: metadata.path, user: metadata.user, fileName: metadata.fileName)
-            let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_copied_path_")
-            NCContentPresenter.shared.showInfo(error: error)
-        }
 
         let detail = UIAction(title: NSLocalizedString("_details_", comment: ""), image: UIImage(systemName: "info")) { _ in
             NCFunctionCenter.shared.openShare(viewController: viewController, metadata: metadata, indexPage: .activity)
         }
 
-        let offline = UIAction(title: titleOffline, image: UIImage(systemName: "tray.and.arrow.down")) { _ in
-            NCFunctionCenter.shared.setMetadataAvalableOffline(metadata, isOffline: isOffline)
-            if let viewController = viewController as? NCCollectionViewCommon {
-                viewController.reloadDataSource()
+        let favorite = UIAction(title: metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: ""),
+                                image: NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite)) { _ in
+            NCNetworking.shared.favoriteMetadata(metadata) { error in
+                if error != .success {
+                    NCContentPresenter.shared.showError(error: error)
+                }
             }
         }
 
-        let lockUnlock = UIAction(title: titleLock, image: UIImage(systemName: iconLock)) { _ in
-            NCNetworking.shared.lockUnlockFile(metadata, shoulLock: !metadata.lock)
+        let openIn = UIAction(title: NSLocalizedString("_open_in_", comment: ""), image: UIImage(systemName: "square.and.arrow.up") ) { _ in
+            NCFunctionCenter.shared.openDownload(metadata: metadata, selector: NCGlobal.shared.selectorOpenIn)
+        }
+
+        let viewInFolder = UIAction(title: NSLocalizedString("_view_in_folder_", comment: ""), image: UIImage(systemName: "arrow.forward.square")) { _ in
+            NCFunctionCenter.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileNameBlink: metadata.fileName, fileNameOpen: nil)
         }
+
         let save = UIAction(title: titleSave, image: UIImage(systemName: "square.and.arrow.down")) { _ in
             if metadataMOV != nil {
                 NCFunctionCenter.shared.saveLivePhoto(metadata: metadata, metadataMOV: metadataMOV!)
@@ -94,54 +75,14 @@ class NCContextMenu: NSObject {
             }
         }
 
-        let viewInFolder = UIAction(title: NSLocalizedString("_view_in_folder_", comment: ""), image: UIImage(systemName: "arrow.forward.square")) { _ in
-            NCFunctionCenter.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileNameBlink: metadata.fileName, fileNameOpen: nil)
-        }
-
-        let openIn = UIAction(title: NSLocalizedString("_open_in_", comment: ""), image: UIImage(systemName: "square.and.arrow.up") ) { _ in
-            NCFunctionCenter.shared.openDownload(metadata: metadata, selector: NCGlobal.shared.selectorOpenIn)
-        }
-
-        let print = UIAction(title: NSLocalizedString("_print_", comment: ""), image: UIImage(systemName: "printer") ) { _ in
-            NCFunctionCenter.shared.openDownload(metadata: metadata, selector: NCGlobal.shared.selectorPrint)
+        let copy = UIAction(title: NSLocalizedString("_copy_file_", comment: ""), image: UIImage(systemName: "doc.on.doc")) { _ in
+            NCFunctionCenter.shared.copyPasteboard(pasteboardOcIds: [metadata.ocId], hudView: viewController.view)
         }
 
         let modify = UIAction(title: NSLocalizedString("_modify_", comment: ""), image: UIImage(systemName: "pencil.tip.crop.circle")) { _ in
             NCFunctionCenter.shared.openDownload(metadata: metadata, selector: NCGlobal.shared.selectorLoadFileQuickLook)
         }
 
-        let saveAsScan = UIAction(title: NSLocalizedString("_save_as_scan_", comment: ""), image: UIImage(systemName: "viewfinder.circle")) { _ in
-            NCFunctionCenter.shared.openDownload(metadata: metadata, selector: NCGlobal.shared.selectorSaveAsScan)
-        }
-
-        // let open = UIMenu(title: NSLocalizedString("_open_", comment: ""), image: UIImage(systemName: "square.and.arrow.up"), children: [openIn, openQuickLook])
-
-        let moveCopy = UIAction(title: NSLocalizedString("_move_or_copy_", comment: ""), image: UIImage(systemName: "arrow.up.right.square")) { _ in
-            NCFunctionCenter.shared.openSelectView(items: [metadata])
-        }
-
-        let rename = UIAction(title: NSLocalizedString("_rename_", comment: ""), image: UIImage(systemName: "pencil")) { _ in
-
-            if let vcRename = UIStoryboard(name: "NCRenameFile", bundle: nil).instantiateInitialViewController() as? NCRenameFile {
-
-                vcRename.metadata = metadata
-                vcRename.imagePreview = image
-
-                let popup = NCPopupViewController(contentController: vcRename, popupWidth: vcRename.width, popupHeight: vcRename.height)
-
-                viewController.present(popup, animated: true)
-            }
-        }
-
-        let favorite = UIAction(title: titleFavorite, image: NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite)) { _ in
-
-            NCNetworking.shared.favoriteMetadata(metadata) { error in
-                if error != .success {
-                    NCContentPresenter.shared.showError(error: error)
-                }
-            }
-        }
-
         let deleteConfirmFile = UIAction(title: titleDeleteConfirmFile, image: UIImage(systemName: "trash"), attributes: .destructive) { _ in
             NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: false) { error in
                 if error != .success {
@@ -149,77 +90,59 @@ class NCContextMenu: NSObject {
                 }
             }
         }
-
         let deleteConfirmLocal = UIAction(title: NSLocalizedString("_remove_local_file_", comment: ""), image: UIImage(systemName: "trash"), attributes: .destructive) { _ in
             NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: true) { _ in
             }
         }
+        let deleteSubMenu = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmLocal, deleteConfirmFile])
 
-        var delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmLocal, deleteConfirmFile])
+        // ------ MENU -----
 
-        if !enableDeleteLocal {
-            delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmFile])
-        }
+        var menu: [UIMenuElement] = []
 
         if metadata.directory {
-            delete = UIMenu(title: NSLocalizedString("_delete_folder_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmFile])
-        }
-
-        // ------ MENU -----
-
-        // DIR
 
-        guard !metadata.directory else {
-            var submenu = UIMenu()
-            if !isDirectoryE2EE && metadata.e2eEncrypted {
-                submenu = UIMenu(title: "", options: .displayInline, children: [favorite, offline, rename, moveCopy, copyPath])
+            if metadata.isDirectoryE2EE || metadata.e2eEncrypted {
+                menu.append(favorite)
             } else {
-                submenu = UIMenu(title: "", options: .displayInline, children: [favorite, offline, rename, moveCopy, copyPath, delete])
+                menu.append(favorite)
+                menu.append(deleteConfirmFile)
             }
-            guard appDelegate!.disableSharesView == false else { return submenu }
-            return UIMenu(title: "", children: [detail, submenu])
-        }
-
-        // FILE
-
-        var children: [UIMenuElement] = [offline, openIn, moveCopy, copy, copyPath]
+            return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])
 
-        if !metadata.lock {
-            // Workaround: PROPPATCH doesn't work (favorite)
-            // https://github.com/nextcloud/files_lock/issues/68
-            children.insert(favorite, at: 0)
-            children.append(delete)
-            children.insert(rename, at: 3)
-        } else if enableDeleteLocal {
-            children.append(deleteConfirmLocal)
-        }
-
-        if NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate!.account, elements: NCElementsJSON.shared.capabilitiesFilesLockVersion) >= 1, metadata.canUnlock(as: appDelegate!.userId) {
-            children.insert(lockUnlock, at: metadata.lock ? 0 : 1)
-        }
-
-        if (metadata.contentType != "image/svg+xml") && (metadata.classFile == NKCommon.typeClassFile.image.rawValue || metadata.classFile == NKCommon.typeClassFile.video.rawValue) {
-            children.insert(save, at: 2)
-        }
-
-        if (metadata.contentType != "image/svg+xml") && (metadata.classFile == NKCommon.typeClassFile.image.rawValue) {
-            children.insert(saveAsScan, at: 2)
-        }
-
-        if (metadata.contentType != "image/svg+xml") && (metadata.classFile == NKCommon.typeClassFile.image.rawValue || metadata.contentType == "application/pdf" || metadata.contentType == "com.adobe.pdf") {
-            children.insert(print, at: 2)
-        }
-
-        if enableViewInFolder {
-            children.insert(viewInFolder, at: children.count - 1)
-        }
+        } else {
 
-        if (!isDirectoryE2EE && metadata.contentType != "image/gif" && metadata.contentType != "image/svg+xml") && (metadata.contentType == "com.adobe.pdf" || metadata.contentType == "application/pdf" || metadata.classFile == NKCommon.typeClassFile.image.rawValue) {
-            children.insert(modify, at: children.count - 1)
+            if metadata.lock {
+                menu.append(favorite)
+                if metadata.isViewOnly {
+                    //
+                } else {
+                    menu.append(openIn)
+                    menu.append(save)
+                    menu.append(copy)
+                }
+            } else {
+                menu.append(favorite)
+                if metadata.isViewOnly {
+                    if viewController is NCMedia {
+                        menu.append(viewInFolder)
+                    }
+                } else {
+                    menu.append(openIn)
+                    menu.append(save)
+                    if viewController is NCMedia {
+                        menu.append(viewInFolder)
+                    }
+                    menu.append(copy)
+                    menu.append(modify)
+                }
+                if viewController is NCMedia {
+                    menu.append(deleteConfirmFile)
+                } else {
+                    menu.append(deleteSubMenu)
+                }
+            }
+            return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])
         }
-
-        let submenu = UIMenu(title: "", options: .displayInline, children: children)
-        guard appDelegate!.disableSharesView == false else { return submenu }
-        return UIMenu(title: "", children: [detail, submenu])
     }
 }

+ 39 - 40
iOSClient/Menu/NCViewer+Menu.swift

@@ -35,9 +35,23 @@ extension NCViewer {
         var titleFavorite = NSLocalizedString("_add_favorites_", comment: "")
         if metadata.favorite { titleFavorite = NSLocalizedString("_remove_favorites_", comment: "") }
         let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-        let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
         let isOffline = localFile?.offline == true
 
+        //
+        // DETAIL
+        //
+        if !appDelegate.disableSharesView {
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_details_", comment: ""),
+                    icon: NCUtility.shared.loadImage(named: "info"),
+                    action: { _ in
+                        NCFunctionCenter.shared.openShare(viewController: viewController, metadata: metadata, indexPage: .activity)
+                    }
+                )
+            )
+        }
+
         //
         // FAVORITE
         // Workaround: PROPPATCH doesn't work
@@ -58,39 +72,24 @@ extension NCViewer {
             )
         }
 
-        //
-        // DETAIL
-        //
-        if !appDelegate.disableSharesView {
-            actions.append(
-                NCMenuAction(
-                    title: NSLocalizedString("_details_", comment: ""),
-                    icon: NCUtility.shared.loadImage(named: "info"),
-                    action: { _ in
-                        NCFunctionCenter.shared.openShare(viewController: viewController, metadata: metadata, indexPage: .activity)
-                    }
-                )
-            )
-        }
-
         //
         // OFFLINE
         //
-        if metadata.session == "" && !webView {
+        if !webView, metadata.isSettableOnOffline {
             actions.append(.setAvailableOfflineAction(selectedMetadatas: [metadata], isAnyOffline: isOffline, viewController: viewController))
         }
 
         //
         // OPEN IN
         //
-        if metadata.session == "" && !webView {
+        if !webView, metadata.canOpenIn {
             actions.append(.openInAction(selectedMetadatas: [metadata], viewController: viewController))
         }
 
         //
         // PRINT
         //
-        if metadata.classFile == NKCommon.typeClassFile.image.rawValue || metadata.contentType == "application/pdf" || metadata.contentType == "com.adobe.pdf" {
+        if !webView, metadata.isPrintable {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_print_", comment: ""),
@@ -123,16 +122,16 @@ extension NCViewer {
 #endif
         
         //
-        // SAVE IMAGE / VIDEO
+        // SAVE CAMERA ROLL
         //
-        if metadata.classFile == NKCommon.typeClassFile.image.rawValue || metadata.classFile == NKCommon.typeClassFile.video.rawValue {
+        if !webView, metadata.isSaveInCameraRoll {
             actions.append(.saveMediaAction(selectedMediaMetadatas: [metadata]))
         }
 
         //
         // SAVE AS SCAN
         //
-        if metadata.classFile == NKCommon.typeClassFile.image.rawValue && metadata.contentType != "image/svg+xml" {
+        if !webView, metadata.isSaveAsScan {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_save_as_scan_", comment: ""),
@@ -147,7 +146,7 @@ extension NCViewer {
         //
         // RENAME
         //
-        if !webView, !metadata.lock {
+        if !webView, metadata.isRenameable {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_rename_", comment: ""),
@@ -172,14 +171,16 @@ extension NCViewer {
         //
         // COPY - MOVE
         //
-        if !webView {
+        if !webView, metadata.isCopyableMovable {
             actions.append(.moveOrCopyAction(selectedMetadatas: [metadata]))
         }
 
         //
-        // COPY
+        // COPY IN PASTEBOARD
         //
-        actions.append(.copyAction(selectOcId: [metadata.ocId], hudView: viewController.view))
+        if !webView, metadata.isCopyableInPasteboard {
+            actions.append(.copyAction(selectOcId: [metadata.ocId], hudView: viewController.view))
+        }
 
         //
         // VIEW IN FOLDER
@@ -199,18 +200,16 @@ extension NCViewer {
         //
         // DOWNLOAD IMAGE MAX RESOLUTION
         //
-        if metadata.session == "" {
-            if metadata.classFile == NKCommon.typeClassFile.image.rawValue && !CCUtility.fileProviderStorageExists(metadata) && metadata.session == "" {
-                actions.append(
-                    NCMenuAction(
-                        title: NSLocalizedString("_download_image_max_", comment: ""),
-                        icon: NCUtility.shared.loadImage(named: "square.and.arrow.down"),
-                        action: { _ in
-                            NCNetworking.shared.download(metadata: metadata, selector: "") { _, _ in }
-                        }
-                    )
+        if !webView, metadata.session.isEmpty, metadata.classFile == NKCommon.typeClassFile.image.rawValue, !CCUtility.fileProviderStorageExists(metadata) {
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_download_image_max_", comment: ""),
+                    icon: NCUtility.shared.loadImage(named: "square.and.arrow.down"),
+                    action: { _ in
+                        NCNetworking.shared.download(metadata: metadata, selector: "") { _, _ in }
+                    }
                 )
-            }
+            )
         }
 
         //
@@ -239,9 +238,9 @@ extension NCViewer {
         }
 
         //
-        // MODIFY
+        // MODIFY WITH QUICK LOOK
         //
-        if !isDirectoryE2EE && metadata.contentType != "image/gif" && (metadata.contentType == "com.adobe.pdf" || metadata.contentType == "application/pdf" || metadata.classFile == NKCommon.typeClassFile.image.rawValue) {
+        if !webView, metadata.isModifiableWithQuickLook {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_modify_", comment: ""),
@@ -256,7 +255,7 @@ extension NCViewer {
         //
         // DELETE
         //
-        if !webView {
+        if !webView, metadata.isDeletable {
             actions.append(.deleteAction(selectedMetadatas: [metadata], metadataFolder: nil, viewController: viewController))
         }
 

+ 4 - 7
iOSClient/Networking/NCNetworking.swift

@@ -393,10 +393,9 @@ import Photos
                 completion: @escaping (_ error: NKError) -> () = { error in }) {
 
         let metadata = tableMetadata.init(value: metadata)
-        let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
-        NKCommon.shared.writeLog("[INFO] Upload file \(metadata.fileNameView) with Identifier \(metadata.assetLocalIdentifier) with size \(metadata.size) [CHUNCK \(metadata.chunk), E2EE \(isDirectoryE2EE)]")
+        NKCommon.shared.writeLog("[INFO] Upload file \(metadata.fileNameView) with Identifier \(metadata.assetLocalIdentifier) with size \(metadata.size) [CHUNCK \(metadata.chunk), E2EE \(metadata.isDirectoryE2EE)]")
 
-        if isDirectoryE2EE {
+        if metadata.isDirectoryE2EE {
 #if !EXTENSION_FILE_PROVIDER_EXTENSION && !EXTENSION_WIDGET
             Task {
                 let error = await NCNetworkingE2EEUpload.shared.upload(metadata: metadata, uploadE2EEDelegate: uploadE2EEDelegate)
@@ -1164,10 +1163,9 @@ import Photos
             return completion(NKError())
         }
 
-        let isDirectoryEncrypted = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
         let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
 
-        if isDirectoryEncrypted {
+        if metadata.isDirectoryE2EE {
 #if !EXTENSION
             Task {
                 if let metadataLive = metadataLive {
@@ -1325,12 +1323,11 @@ import Photos
 
     @objc func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, viewController: UIViewController?, completion: @escaping (_ error: NKError) -> Void) {
 
-        let isDirectoryEncrypted = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
         let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
         let fileNameNew = fileNameNew.trimmingCharacters(in: .whitespacesAndNewlines)
         let fileNameNewLive = (fileNameNew as NSString).deletingPathExtension + ".mov"
 
-        if isDirectoryEncrypted {
+        if metadata.isDirectoryE2EE {
 #if !EXTENSION
             Task {
                 if let metadataLive = metadataLive {

+ 4 - 4
iOSClient/Networking/NCNetworkingProcessUpload.swift

@@ -114,7 +114,7 @@ class NCNetworkingProcessUpload: NSObject {
             // E2EE
             let uniqueMetadatas = metadatasUpload.unique(map: { $0.serverUrl })
             for metadata in uniqueMetadatas {
-                if NCUtility.shared.isDirectoryE2EE(metadata: metadata) {
+                if metadata.isDirectoryE2EE {
                     self.pauseProcess = false
                     return completition(counterUpload)
                 }
@@ -157,20 +157,20 @@ class NCNetworkingProcessUpload: NSObject {
                             for metadata in metadatas where counterUpload < maxConcurrentOperationUpload {
 
                                 // isE2EE
-                                let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
+                                let isInDirectoryE2EE = metadata.isDirectoryE2EE
 
                                 // NO WiFi
                                 if !isWiFi && metadata.session == NCNetworking.shared.sessionIdentifierBackgroundWWan {
                                     continue
                                 }
 
-                                if applicationState != .active && (isDirectoryE2EE || metadata.chunk) {
+                                if applicationState != .active && (isInDirectoryE2EE || metadata.chunk) {
                                     continue
                                 }
 
                                 if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusInUpload) {
                                     NCNetworking.shared.upload(metadata: metadata)
-                                    if isDirectoryE2EE || metadata.chunk {
+                                    if isInDirectoryE2EE || metadata.chunk {
                                         maxConcurrentOperationUpload = 1
                                     }
                                     counterUpload += 1

+ 1 - 1
iOSClient/Networking/NCOperationQueue.swift

@@ -82,7 +82,7 @@ import NextcloudKit
 
     func delete(metadata: tableMetadata, onlyLocalCache: Bool) {
 
-        if NCUtility.shared.isDirectoryE2EE(metadata: metadata) {
+        if metadata.isDirectoryE2EE {
             for case let operation as NCOperationDelete in deleteQueueE2EE.operations where operation.metadata.ocId == metadata.ocId {
                 return
             }

+ 1 - 12
iOSClient/Networking/NCService.swift

@@ -191,19 +191,8 @@ class NCService: NSObject {
                 NCBrandColor.shared.settingThemingColor(account: account)
             }
 
-            // File Sharing
+            // Sharing & Comments
             let isFilesSharingEnabled = NCManageDatabase.shared.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesFileSharingApiEnabled, exists: false)
-            if isFilesSharingEnabled {
-                NextcloudKit.shared.readShares(parameters: NKShareParameter(), options: options) { account, shares, data, error in
-                    if error == .success, let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) {
-                        NCManageDatabase.shared.deleteTableShare(account: account)
-                        if let shares = shares, !shares.isEmpty {
-                            let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: tableAccount.urlBase, userId: tableAccount.userId)
-                            NCManageDatabase.shared.addShare(account: account, home: home, shares: shares)
-                        }
-                    }
-                }
-            }
             let comments = NCManageDatabase.shared.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesFilesComments, exists: false)
             let activity = NCManageDatabase.shared.getCapabilitiesServerArray(account: account, elements: NCElementsJSON.shared.capabilitiesActivity)
             if !isFilesSharingEnabled && !comments && activity == nil {

+ 10 - 1
iOSClient/Scan document/NCUploadScanDocument.swift

@@ -372,6 +372,15 @@ struct UploadScanDocumentView: View {
         self.uploadScanDocument = uploadScanDocument
     }
 
+    func getTextServerUrl(_ serverUrl: String) -> String {
+
+        if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", uploadScanDocument.userBaseUrl.account, serverUrl)), let metadata = NCManageDatabase.shared.getMetadataFromOcId(directory.ocId) {
+            return (metadata.fileNameView)
+        } else {
+            return (serverUrl as NSString).lastPathComponent
+        }
+    }
+
     var body: some View {
 
         GeometryReader { geo in
@@ -384,7 +393,7 @@ struct UploadScanDocumentView: View {
                                     Text("/")
                                         .frame(maxWidth: .infinity, alignment: .trailing)
                                 } else {
-                                    Text((uploadScanDocument.serverUrl as NSString).lastPathComponent)
+                                    Text(self.getTextServerUrl(uploadScanDocument.serverUrl))
                                         .frame(maxWidth: .infinity, alignment: .trailing)
                                 }
                             } icon: {

+ 12 - 14
iOSClient/Select/NCSelect.swift

@@ -405,8 +405,6 @@ extension NCSelect: UICollectionViewDataSource {
         isShare = metadata.permissions.contains(NCGlobal.shared.permissionShared) && !metadataFolder.permissions.contains(NCGlobal.shared.permissionShared)
         isMounted = metadata.permissions.contains(NCGlobal.shared.permissionMounted) && !metadataFolder.permissions.contains(NCGlobal.shared.permissionMounted)
 
-        let tableShare = dataSource.metadatasForSection[indexPath.section].metadataShare[metadata.ocId]
-
         // LAYOUT LIST
 
         if layoutForView?.layout == NCGlobal.shared.layoutList {
@@ -437,10 +435,10 @@ extension NCSelect: UICollectionViewDataSource {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
                 } else if isShare {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if tableShare != nil && tableShare?.shareType != 3 {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if tableShare != nil && tableShare?.shareType == 3 {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderPublic
+                } else if !metadata.shareType.isEmpty {
+                    metadata.shareType.contains(3) ?
+                    (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
+                    (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
                 } else if metadata.mountType == "group" {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
                 } else if isMounted {
@@ -474,10 +472,10 @@ extension NCSelect: UICollectionViewDataSource {
             // Share image
             if isShare {
                 cell.imageShared.image = NCBrandColor.cacheImages.shared
-            } else if tableShare != nil && tableShare?.shareType == 3 {
-                cell.imageShared.image = NCBrandColor.cacheImages.shareByLink
-            } else if tableShare != nil && tableShare?.shareType != 3 {
-                cell.imageShared.image = NCBrandColor.cacheImages.shared
+            } else if !metadata.shareType.isEmpty {
+                metadata.shareType.contains(3) ?
+                (cell.imageShared.image = NCBrandColor.cacheImages.shareByLink) :
+                (cell.imageShared.image = NCBrandColor.cacheImages.shared)
             } else {
                 cell.imageShared.image = NCBrandColor.cacheImages.canShare
             }
@@ -531,10 +529,10 @@ extension NCSelect: UICollectionViewDataSource {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
                 } else if isShare {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if tableShare != nil && tableShare!.shareType != 3 {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if tableShare != nil && tableShare!.shareType == 3 {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderPublic
+                } else if !metadata.shareType.isEmpty {
+                    metadata.shareType.contains(3) ?
+                    (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
+                    (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
                 } else if metadata.mountType == "group" {
                     cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
                 } else if isMounted {

BIN
iOSClient/Supporting Files/af.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/an.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ar.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ast.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/az.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/be.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/br.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/bs.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ca.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/da.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/de.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/el.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/en-GB.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/eo.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-419.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-AR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CL.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-CR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-DO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-EC.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-GT.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-HN.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-MX.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-NI.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PA.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PE.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-PY.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-SV.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-UY.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/et_EE.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/eu.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fa.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fo.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/fr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/gd.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/gl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/he.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hsb.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hu.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/hy.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ia.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/id.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ig.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/is.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/it.lproj/InfoPlist.strings


BIN
iOSClient/Supporting Files/it.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ka.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/kab.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/km.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/kn.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ko.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/la.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/lb.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/lo.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/lv.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/mk.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/mn.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/mr.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/my.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ne.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/nl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/oc.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ps.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ro.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/ru.lproj/Localizable.strings


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels