From 4467dd784310792e55e4b2563172fc828b4494fd Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Wed, 21 Jan 2026 18:13:12 +0100 Subject: [PATCH 1/4] Context menu fixes Signed-off-by: Milen Pivchev --- iOSClient/Menu/NCContextMenu.swift | 51 +++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/iOSClient/Menu/NCContextMenu.swift b/iOSClient/Menu/NCContextMenu.swift index 698d766d9e..9f2e8c9cb3 100644 --- a/iOSClient/Menu/NCContextMenu.swift +++ b/iOSClient/Menu/NCContextMenu.swift @@ -32,10 +32,7 @@ class NCContextMenu: NSObject { return UIMenu() } - // Build top menu items - let detail = makeDetailAction(metadata: metadata) - let favorite = makeFavoriteAction(metadata: metadata) - let share = makeShareAction() + let topMenuItems = buildTopMenuItems(metadata: metadata) let mainActionsMenu = buildMainActionsMenu( metadata: metadata, @@ -49,21 +46,44 @@ class NCContextMenu: NSObject { let deleteMenu = buildDeleteMenu(metadata: metadata) + if !NCNetworking.shared.isOnline { + return UIMenu() + } + // Assemble final menu - if NCNetworking.shared.isOnline { - let baseChildren = [ - UIMenu(title: "", options: .displayInline, children: mainActionsMenu), - UIMenu(title: "", options: .displayInline, children: clientIntegrationMenu), - UIMenu(title: "", options: .displayInline, children: deleteMenu) - ] + let baseChildren = [ + UIMenu(title: "", options: .displayInline, children: mainActionsMenu), + UIMenu(title: "", options: .displayInline, children: clientIntegrationMenu), + UIMenu(title: "", options: .displayInline, children: deleteMenu) + ] - let finalMenu = UIMenu(title: "", children: (metadata.lock ? [detail] : [detail, share, favorite]) + baseChildren) - finalMenu.preferredElementSize = .medium + let finalMenu = UIMenu(title: "", children: topMenuItems + baseChildren) + finalMenu.preferredElementSize = .medium // top menu items are shown in a short format style - return finalMenu - } else { - return UIMenu() + return finalMenu + } + + // MARK: Top Menu Items + + private func buildTopMenuItems(metadata: tableMetadata, appending items: [UIMenuElement] = []) -> [UIMenuElement] { + var topActionsMenu: [UIMenuElement] = [] + + if metadata.canShare { + topActionsMenu.append(makeShareAction()) + } + + topActionsMenu.append(makeDetailAction(metadata: metadata)) + + if !metadata.lock { + topActionsMenu.append(makeFavoriteAction(metadata: metadata)) } + +// let favorite = +// let share = makeShareAction() + +// var result: [UIMenuElement] = metadata.lock ? [detail] : [detail, share, favorite] +// result.append(contentsOf: items) + return topActionsMenu } // MARK: Basic Actions @@ -565,3 +585,4 @@ class NCContextMenu: NSObject { return clientIntegrationMenu } } + From 3586ccce6d35cc2a20d0618449f7887f253f1bc0 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Wed, 21 Jan 2026 18:14:52 +0100 Subject: [PATCH 2/4] Refactor Signed-off-by: Milen Pivchev --- iOSClient/Menu/NCContextMenu.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/iOSClient/Menu/NCContextMenu.swift b/iOSClient/Menu/NCContextMenu.swift index 9f2e8c9cb3..20aa38272e 100644 --- a/iOSClient/Menu/NCContextMenu.swift +++ b/iOSClient/Menu/NCContextMenu.swift @@ -78,11 +78,6 @@ class NCContextMenu: NSObject { topActionsMenu.append(makeFavoriteAction(metadata: metadata)) } -// let favorite = -// let share = makeShareAction() - -// var result: [UIMenuElement] = metadata.lock ? [detail] : [detail, share, favorite] -// result.append(contentsOf: items) return topActionsMenu } From 88a8c2ddf83c66336e30b177d3a3b496f384bea9 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Thu, 22 Jan 2026 17:04:38 +0100 Subject: [PATCH 3/4] Add locked by text Signed-off-by: Milen Pivchev --- iOSClient/Menu/ContextMenuActions.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iOSClient/Menu/ContextMenuActions.swift b/iOSClient/Menu/ContextMenuActions.swift index 28e45c65d0..a70c481d0c 100644 --- a/iOSClient/Menu/ContextMenuActions.swift +++ b/iOSClient/Menu/ContextMenuActions.swift @@ -143,14 +143,18 @@ enum ContextMenuActions { metadatas: [tableMetadata], completion: (() -> Void)? = nil) -> UIAction { let titleKey: String - if metadatas.count == 1 { + var subtitleKey: String = "" + + if metadatas.count == 1, let metadata = metadatas.first { titleKey = shouldLock ? "_lock_file_" : "_unlock_file_" + subtitleKey = !shouldLock ? String(format: NSLocalizedString("_locked_by_", comment: ""), metadata.lockOwnerDisplayName) : "" } else { titleKey = shouldLock ? "_lock_selected_files_" : "_unlock_selected_files_" } return UIAction( title: NSLocalizedString(titleKey, comment: ""), + subtitle: subtitleKey, image: UIImage(systemName: shouldLock ? "lock" : "lock.open") ) { _ in for metadata in metadatas where metadata.lock != shouldLock { From 181a95920e4f73f8ea40941797f901249e4864d7 Mon Sep 17 00:00:00 2001 From: Milen Pivchev Date: Thu, 22 Jan 2026 18:13:08 +0100 Subject: [PATCH 4/4] Refactor Signed-off-by: Milen Pivchev --- ...ctionViewCommon+SelectTabBarDelegate.swift | 2 +- iOSClient/Menu/ContextMenuActions.swift | 47 ++++++++++--------- iOSClient/Menu/NCContextMenu.swift | 3 +- iOSClient/Menu/NCMenuAction.swift | 2 +- .../Networking/NCNetworking+WebDAV.swift | 4 +- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift index 9f37ebd5cb..76a5b60c0f 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon+SelectTabBarDelegate.swift @@ -103,7 +103,7 @@ extension NCCollectionViewCommon: NCCollectionViewCommonSelectTabBarDelegate { Task { let metadatas = getSelectedMetadatas() for metadata in metadatas where metadata.lock == isAnyLocked { - self.networking.lockUnlockFile(metadata, shoulLock: !isAnyLocked) + self.networking.lockUnlockFile(metadata, shouldLock: !isAnyLocked) } await setEditMode(false) } diff --git a/iOSClient/Menu/ContextMenuActions.swift b/iOSClient/Menu/ContextMenuActions.swift index a70c481d0c..c6e40d6e18 100644 --- a/iOSClient/Menu/ContextMenuActions.swift +++ b/iOSClient/Menu/ContextMenuActions.swift @@ -139,28 +139,29 @@ enum ContextMenuActions { } } - static func lockUnlock(shouldLock: Bool, - metadatas: [tableMetadata], - completion: (() -> Void)? = nil) -> UIAction { - let titleKey: String - var subtitleKey: String = "" - - if metadatas.count == 1, let metadata = metadatas.first { - titleKey = shouldLock ? "_lock_file_" : "_unlock_file_" - subtitleKey = !shouldLock ? String(format: NSLocalizedString("_locked_by_", comment: ""), metadata.lockOwnerDisplayName) : "" - } else { - titleKey = shouldLock ? "_lock_selected_files_" : "_unlock_selected_files_" - } + static func lockUnlock(isLocked: Bool, + metadata: tableMetadata, + completion: (() -> Void)? = nil) -> UIAction { + let titleKey: String + var subtitleKey: String = "" + let image: UIImage? + if !metadata.canUnlock(as: metadata.userId), isLocked { + titleKey = String(format: NSLocalizedString("_locked_by_", comment: ""), metadata.lockOwnerDisplayName) + image = UIImage(systemName: "lock") + } else { + titleKey = isLocked ? "_unlock_file_" : "_lock_file_" + image = UIImage(systemName: isLocked ? "lock.open" : "lock") + subtitleKey = !metadata.lockOwnerDisplayName.isEmpty ? String(format: NSLocalizedString("_locked_by_", comment: ""), metadata.lockOwnerDisplayName) : "" + } - return UIAction( - title: NSLocalizedString(titleKey, comment: ""), - subtitle: subtitleKey, - image: UIImage(systemName: shouldLock ? "lock" : "lock.open") - ) { _ in - for metadata in metadatas where metadata.lock != shouldLock { - NCNetworking.shared.lockUnlockFile(metadata, shoulLock: shouldLock) - } - completion?() - } - } + return UIAction( + title: NSLocalizedString(titleKey, comment: ""), + subtitle: subtitleKey, + image: image, + attributes: metadata.canUnlock(as: metadata.userId) ? [] : [.disabled] + ) { _ in + NCNetworking.shared.lockUnlockFile(metadata, shouldLock: !isLocked) + completion?() + } + } } diff --git a/iOSClient/Menu/NCContextMenu.swift b/iOSClient/Menu/NCContextMenu.swift index 20aa38272e..bb98376e4a 100644 --- a/iOSClient/Menu/NCContextMenu.swift +++ b/iOSClient/Menu/NCContextMenu.swift @@ -136,10 +136,9 @@ class NCContextMenu: NSObject { // Lock/Unlock if NCNetworking.shared.isOnline, !metadata.directory, - metadata.canUnlock(as: metadata.userId), !capabilities.filesLockVersion.isEmpty { mainActionsMenu.append( - ContextMenuActions.lockUnlock(shouldLock: !metadata.lock, metadatas: [metadata]) + ContextMenuActions.lockUnlock(isLocked: metadata.lock, metadata: metadata) ) } diff --git a/iOSClient/Menu/NCMenuAction.swift b/iOSClient/Menu/NCMenuAction.swift index ddef43ec19..8d8c1d11c9 100644 --- a/iOSClient/Menu/NCMenuAction.swift +++ b/iOSClient/Menu/NCMenuAction.swift @@ -266,7 +266,7 @@ extension NCMenuAction { sender: sender, action: { _ in for metadata in metadatas where metadata.lock != shouldLock { - NCNetworking.shared.lockUnlockFile(metadata, shoulLock: shouldLock) + NCNetworking.shared.lockUnlockFile(metadata, shouldLock: shouldLock) } completion?() } diff --git a/iOSClient/Networking/NCNetworking+WebDAV.swift b/iOSClient/Networking/NCNetworking+WebDAV.swift index f96b565613..7a2e047eae 100644 --- a/iOSClient/Networking/NCNetworking+WebDAV.swift +++ b/iOSClient/Networking/NCNetworking+WebDAV.swift @@ -765,8 +765,8 @@ extension NCNetworking { // MARK: - Lock Files - func lockUnlockFile(_ metadata: tableMetadata, shoulLock: Bool) { - NextcloudKit.shared.lockUnlockFile(serverUrlFileName: metadata.serverUrlFileName, shouldLock: shoulLock, account: metadata.account) { task in + func lockUnlockFile(_ metadata: tableMetadata, shouldLock: Bool) { + NextcloudKit.shared.lockUnlockFile(serverUrlFileName: metadata.serverUrlFileName, shouldLock: shouldLock, account: metadata.account) { task in Task { let identifier = await NCNetworking.shared.networkingTasks.createIdentifier(account: metadata.account, path: metadata.serverUrlFileName,