Ver Fonte

Merge pull request #2325 from nextcloud/readOnly

Read only
Marino Faggiana há 2 anos atrás
pai
commit
edc972e280

+ 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 - 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: {

+ 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))
         }
 

+ 47 - 39
iOSClient/Menu/NCContextMenu.swift

@@ -33,24 +33,36 @@ class NCContextMenu: NSObject {
             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 copy = UIAction(title: NSLocalizedString("_copy_file_", comment: ""), image: UIImage(systemName: "doc.on.doc")) { _ in
-            NCFunctionCenter.shared.copyPasteboard(pasteboardOcIds: [metadata.ocId], hudView: viewController.view)
-        }
 
         let detail = UIAction(title: NSLocalizedString("_details_", comment: ""), image: UIImage(systemName: "info")) { _ in
             NCFunctionCenter.shared.openShare(viewController: viewController, metadata: metadata, indexPage: .activity)
         }
 
+        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 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!)
@@ -63,27 +75,14 @@ class NCContextMenu: NSObject {
             }
         }
 
-        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 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 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 {
@@ -91,17 +90,11 @@ 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
             }
         }
-
-        var delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmLocal, deleteConfirmFile])
-
-        if viewController is NCMedia || metadata.directory {
-            delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmFile])
-        }
+        let deleteSubMenu = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmLocal, deleteConfirmFile])
 
         // ------ MENU -----
 
@@ -109,30 +102,45 @@ class NCContextMenu: NSObject {
 
         if metadata.directory {
 
-            if isDirectoryE2EE || metadata.e2eEncrypted {
+            if metadata.isDirectoryE2EE || metadata.e2eEncrypted {
                 menu.append(favorite)
             } else {
                 menu.append(favorite)
-                menu.append(delete)
+                menu.append(deleteConfirmFile)
             }
             return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])
 
         } else {
 
             if metadata.lock {
-                menu.append(openIn)
-                menu.append(save)
-                menu.append(copy)
+                menu.append(favorite)
+                if metadata.isViewOnly {
+                    //
+                } else {
+                    menu.append(openIn)
+                    menu.append(save)
+                    menu.append(copy)
+                }
             } else {
                 menu.append(favorite)
-                menu.append(openIn)
-                menu.append(save)
+                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(viewInFolder)
+                    menu.append(deleteConfirmFile)
+                } else {
+                    menu.append(deleteSubMenu)
                 }
-                menu.append(copy)
-                menu.append(modify)
-                menu.append(delete)
             }
             return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])
         }

+ 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
             }

+ 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: {

+ 1 - 1
iOSClient/Transfers/NCTransfers.swift

@@ -149,7 +149,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate {
 
         if action != #selector(startTask(_:)) { return false }
         guard let metadata = metadataTemp else { return false }
-        if NCUtility.shared.isDirectoryE2EE(metadata: metadata) { return false }
+        if metadata.isDirectoryE2EE { return false }
 
         if metadata.status == NCGlobal.shared.metadataStatusWaitUpload || metadata.isUpload {
             return true

+ 1 - 2
iOSClient/Utility/CCUtility.m

@@ -1135,12 +1135,11 @@
 {
     NSString *fileNameViewPath = [self getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView];
     NSString *fileNamePath = [self getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileName];
-    BOOL isFolderEncrypted = [[NCUtility shared] isDirectoryE2EEWithMetadata:metadata];
 
     unsigned long long fileNameViewSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileNameViewPath error:nil] fileSize];
     unsigned long long fileNameSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileNamePath error:nil] fileSize];
 
-    if (isFolderEncrypted == true) {
+    if (metadata.isDirectoryE2EE == true) {
         if ((fileNameSize == metadata.size || fileNameViewSize == metadata.size) && fileNameViewSize > 0) {
             return true;
         } else {

+ 1 - 2
iOSClient/Utility/NCCameraRoll.swift

@@ -87,7 +87,6 @@ class NCCameraRoll: NSObject {
         let metadata = tableMetadata.init(value: metadata)
         let chunckSize = CCUtility.getChunkSize() * 1000000
         var compatibilityFormat: Bool = false
-        let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(metadata: metadata)
 
         func callCompletionWithError(_ error: Bool = true) {
             if error {
@@ -118,7 +117,7 @@ class NCCameraRoll: NSObject {
             metadata.contentType = "image/jpeg"
             fileNamePath = NSTemporaryDirectory() + fileName
             metadata.fileNameView = fileName
-            if !isDirectoryE2EE {
+            if !metadata.isDirectoryE2EE {
                 metadata.fileName = fileName
             }
             compatibilityFormat = true

+ 0 - 3
iOSClient/Utility/NCUtility.swift

@@ -781,9 +781,6 @@ class NCUtility: NSObject {
     func isDirectoryE2EE(file: NKFile) -> Bool {
         return isDirectoryE2EE(serverUrl: file.serverUrl, account: file.account, urlBase: file.urlBase, userId: file.userId)
     }
-    @objc func isDirectoryE2EE(metadata: tableMetadata) -> Bool {
-        return isDirectoryE2EE(serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId)
-    }
     @objc func isDirectoryE2EE(serverUrl: String, account: String, urlBase: String, userId: String) -> Bool {
         if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId) || serverUrl == ".." { return false }
         if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) {

+ 1 - 1
iOSClient/Viewer/NCViewerMedia/NCPlayer/NCKTVHTTPCache.swift

@@ -33,7 +33,7 @@ class NCKTVHTTPCache: NSObject {
 
     func getVideoURL(metadata: tableMetadata) -> (url: URL?, isProxy: Bool) {
 
-        if CCUtility.fileProviderStorageExists(metadata) || NCUtility.shared.isDirectoryE2EE(metadata: metadata) {
+        if CCUtility.fileProviderStorageExists(metadata) || metadata.isDirectoryE2EE {
 
             return (URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)), false)
 

+ 1 - 1
iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift

@@ -203,7 +203,7 @@ class NCPlayer: NSObject {
                         }))
                         alertController.addAction(UIAlertAction(title: NSLocalizedString("_no_", value: "No", comment: ""), style: .default, handler: { _ in }))
                         self.viewController?.present(alertController, animated: true)
-                    } else if NCUtility.shared.isDirectoryE2EE(metadata: self.metadata) {
+                    } else if self.metadata.isDirectoryE2EE {
                         let alertController = UIAlertController(title: NSLocalizedString("_info_", value: "Info", comment: ""), message: NSLocalizedString("_video_not_streamed_e2ee_", comment: ""), preferredStyle: .alert)
                         alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", value: "Yes", comment: ""), style: .default, handler: { _ in
                             self.downloadVideo(isEncrypted: true)