From 3c4d6bda2f48e8e289d3fdb26c5e89136c17d45a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 16:05:10 +0800 Subject: [PATCH 01/26] Move all sharing components for FileProviderUIExt into a Sharing folder Signed-off-by: Claudio Cambra --- .../{ => Sharing}/ShareController.swift | 0 .../{ => Sharing}/ShareOptionsView.swift | 0 .../{ => Sharing}/ShareTableItemView.swift | 0 .../{ => Sharing}/ShareTableItemView.xib | 0 .../ShareTableViewDataSource.swift | 0 .../{ => Sharing}/ShareViewController.swift | 0 .../{ => Sharing}/ShareViewController.xib | 0 .../ShareViewDataSourceUIDelegate.swift | 0 .../ShareeSuggestionsDataSource.swift | 0 .../project.pbxproj | 26 ++++++++++++------- 10 files changed, 17 insertions(+), 9 deletions(-) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareController.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareOptionsView.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareTableItemView.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareTableItemView.xib (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareTableViewDataSource.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareViewController.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareViewController.xib (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareViewDataSourceUIDelegate.swift (100%) rename shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/{ => Sharing}/ShareeSuggestionsDataSource.swift (100%) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareController.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareController.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareController.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareOptionsView.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareOptionsView.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareOptionsView.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareOptionsView.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableItemView.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableItemView.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableItemView.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableItemView.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableItemView.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableItemView.xib similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableItemView.xib rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableItemView.xib diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableViewDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareTableViewDataSource.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewController.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewController.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewController.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewController.xib similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewController.xib rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewController.xib diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewDataSourceUIDelegate.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewDataSourceUIDelegate.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareViewDataSourceUIDelegate.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareViewDataSourceUIDelegate.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareeSuggestionsDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareeSuggestionsDataSource.swift similarity index 100% rename from shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/ShareeSuggestionsDataSource.swift rename to shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareeSuggestionsDataSource.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index 7162acf23b440..cc7bde0a649b5 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -280,6 +280,22 @@ path = Extensions; sourceTree = ""; }; + 537BD6772C58D0C400446ED0 /* Sharing */ = { + isa = PBXGroup; + children = ( + 5374FD432B95EE1400C78D54 /* ShareController.swift */, + 53651E452BBC0D9500ECAC29 /* ShareeSuggestionsDataSource.swift */, + 53FE14662B8F78B6006C4193 /* ShareOptionsView.swift */, + 53FE14582B8E3F6C006C4193 /* ShareTableItemView.swift */, + 531522812B8E01C6002E31BE /* ShareTableItemView.xib */, + 53FE144F2B8E0658006C4193 /* ShareTableViewDataSource.swift */, + 537630922B85F4B00026BFAB /* ShareViewController.swift */, + 537630902B85F4980026BFAB /* ShareViewController.xib */, + 53FE14642B8F6700006C4193 /* ShareViewDataSourceUIDelegate.swift */, + ); + path = Sharing; + sourceTree = ""; + }; 538E396827F4765000FA63D5 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -321,16 +337,8 @@ isa = PBXGroup; children = ( 5376307B2B85E2E00026BFAB /* Extensions */, + 537BD6772C58D0C400446ED0 /* Sharing */, 53B979802B84C81F002DA742 /* DocumentActionViewController.swift */, - 5374FD432B95EE1400C78D54 /* ShareController.swift */, - 53651E452BBC0D9500ECAC29 /* ShareeSuggestionsDataSource.swift */, - 53FE14662B8F78B6006C4193 /* ShareOptionsView.swift */, - 53FE14582B8E3F6C006C4193 /* ShareTableItemView.swift */, - 531522812B8E01C6002E31BE /* ShareTableItemView.xib */, - 53FE144F2B8E0658006C4193 /* ShareTableViewDataSource.swift */, - 537630922B85F4B00026BFAB /* ShareViewController.swift */, - 537630902B85F4980026BFAB /* ShareViewController.xib */, - 53FE14642B8F6700006C4193 /* ShareViewDataSourceUIDelegate.swift */, 53FE14572B8E3A7C006C4193 /* FileProviderUIExt.entitlements */, 53B979852B84C81F002DA742 /* Info.plist */, ); From 3a983c22bf19c0025c987cc92d3d8e2c298e37c6 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 16:18:58 +0800 Subject: [PATCH 02/26] Add basic LockViewController components Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 16 ++++++++++++++++ .../Locking/LockViewController.xib | 19 +++++++++++++++++++ .../project.pbxproj | 16 ++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift new file mode 100644 index 0000000000000..99eee30804ff2 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -0,0 +1,16 @@ +// +// LockViewController.swift +// FileProviderUIExt +// +// Created by Claudio Cambra on 30/7/24. +// + +import AppKit +import FileProvider +import NextcloudKit +import OSLog +import QuickLookThumbnailing + +class LockViewController: NSViewController { + +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib new file mode 100644 index 0000000000000..0f40790ecb7ad --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index cc7bde0a649b5..0a6e233667c45 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 537630952B860D560026BFAB /* FPUIExtensionServiceSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537630942B860D560026BFAB /* FPUIExtensionServiceSource.swift */; }; 537630972B860D920026BFAB /* FPUIExtensionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537630962B860D920026BFAB /* FPUIExtensionService.swift */; }; 537630982B8612F00026BFAB /* FPUIExtensionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537630962B860D920026BFAB /* FPUIExtensionService.swift */; }; + 537BD67A2C58D67800446ED0 /* LockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6792C58D67800446ED0 /* LockViewController.swift */; }; + 537BD67C2C58D7B700446ED0 /* LockViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537BD67B2C58D7B700446ED0 /* LockViewController.xib */; }; 538E396A27F4765000FA63D5 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */; }; 538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */; }; 538E397627F4765000FA63D5 /* FileProviderExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 538E396727F4765000FA63D5 /* FileProviderExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -163,6 +165,8 @@ 537630922B85F4B00026BFAB /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; 537630942B860D560026BFAB /* FPUIExtensionServiceSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPUIExtensionServiceSource.swift; sourceTree = ""; }; 537630962B860D920026BFAB /* FPUIExtensionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPUIExtensionService.swift; sourceTree = ""; }; + 537BD6792C58D67800446ED0 /* LockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockViewController.swift; sourceTree = ""; }; + 537BD67B2C58D7B700446ED0 /* LockViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LockViewController.xib; sourceTree = ""; }; 538E396727F4765000FA63D5 /* FileProviderExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FileProviderExt.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; }; 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = ""; }; @@ -296,6 +300,15 @@ path = Sharing; sourceTree = ""; }; + 537BD6782C58D0FC00446ED0 /* Locking */ = { + isa = PBXGroup; + children = ( + 537BD6792C58D67800446ED0 /* LockViewController.swift */, + 537BD67B2C58D7B700446ED0 /* LockViewController.xib */, + ); + path = Locking; + sourceTree = ""; + }; 538E396827F4765000FA63D5 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -337,6 +350,7 @@ isa = PBXGroup; children = ( 5376307B2B85E2E00026BFAB /* Extensions */, + 537BD6782C58D0FC00446ED0 /* Locking */, 537BD6772C58D0C400446ED0 /* Sharing */, 53B979802B84C81F002DA742 /* DocumentActionViewController.swift */, 53FE14572B8E3A7C006C4193 /* FileProviderUIExt.entitlements */, @@ -625,6 +639,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 537BD67C2C58D7B700446ED0 /* LockViewController.xib in Resources */, 531522822B8E01C6002E31BE /* ShareTableItemView.xib in Resources */, 537630912B85F4980026BFAB /* ShareViewController.xib in Resources */, ); @@ -702,6 +717,7 @@ 537630932B85F4B00026BFAB /* ShareViewController.swift in Sources */, 53FE14672B8F78B6006C4193 /* ShareOptionsView.swift in Sources */, 53651E462BBC0D9500ECAC29 /* ShareeSuggestionsDataSource.swift in Sources */, + 537BD67A2C58D67800446ED0 /* LockViewController.swift in Sources */, 53FE14652B8F6700006C4193 /* ShareViewDataSourceUIDelegate.swift in Sources */, 53B979812B84C81F002DA742 /* DocumentActionViewController.swift in Sources */, 5374FD442B95EE1400C78D54 /* ShareController.swift in Sources */, From b975b2dfa17a8d03568beaae768db7a653c055c4 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 16:19:29 +0800 Subject: [PATCH 03/26] Add lock/unlock actions in FileProviderUIExt info plist Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Info.plist | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist index 85f108b15fc96..3f843aaed12c3 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist @@ -2,16 +2,32 @@ - CFBundleName - $(PRODUCT_NAME) - CFBundleDisplayName - $(OC_APPLICATION_NAME) File Provider UI Extension - CFBundleIdentifier - $(OC_APPLICATION_REV_DOMAIN).$(PRODUCT_NAME) + CFBundleName + $(PRODUCT_NAME) + CFBundleDisplayName + $(OC_APPLICATION_NAME) File Provider UI Extension + CFBundleIdentifier + $(OC_APPLICATION_REV_DOMAIN).$(PRODUCT_NAME) NSExtension NSExtensionFileProviderActions + + NSExtensionFileProviderActionIdentifier + com.nextcloud.desktopclient.FileProviderUIExt.UnlockFileAction + NSExtensionFileProviderActionName + Unlock file + NSExtensionFileProviderActionActivationRule + SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo."isUnlockable" == YES ).@count > 0 + + + NSExtensionFileProviderActionActivationRule + SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo."isLockable" == YES ).@count > 0 + NSExtensionFileProviderActionName + Lock file + NSExtensionFileProviderActionIdentifier + com.nextcloud.desktopclient.FileProviderUIExt.LockFileAction + NSExtensionFileProviderActionActivationRule TRUEPREDICATE From 954b6ca942ba96461ea2a632b8cb621d54e41b20 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 16:20:10 +0800 Subject: [PATCH 04/26] Handle new locking action identifiers in document action view controller of FileProviderUIExt Signed-off-by: Claudio Cambra --- .../DocumentActionViewController.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift index 96363e962b124..d14c3dd3e9f5b 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift @@ -36,17 +36,21 @@ class DocumentActionViewController: FPUIActionExtensionViewController { ) { Logger.actionViewController.info("Preparing action: \(actionIdentifier, privacy: .public)") - if actionIdentifier == "com.nextcloud.desktopclient.FileProviderUIExt.ShareAction" { + switch (actionIdentifier) { + case "com.nextcloud.desktopclient.FileProviderUIExt.ShareAction": prepare(childViewController: ShareViewController(itemIdentifiers)) + case "com.nextcloud.desktopclient.FileProviderUIExt.LockFileAction": + prepare(childViewController: LockViewController(itemIdentifiers)) + case "com.nextcloud.desktopclient.FileProviderUIExt.UnlockFileAction": + prepare(childViewController: LockViewController(itemIdentifiers)) + default: + return } - } override func prepare(forError error: Error) { Logger.actionViewController.info( - """ - Preparing for error: \(error.localizedDescription, privacy: .public) - """ + "Preparing for error: \(error.localizedDescription, privacy: .public)" ) } From 86a741bc40c22ae5b6578ea3bdbcbda6364aaaf5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 17:15:43 +0800 Subject: [PATCH 05/26] Add basic properties to lock view controller Signed-off-by: Claudio Cambra --- .../DocumentActionViewController.swift | 4 ++-- .../Locking/LockViewController.swift | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift index d14c3dd3e9f5b..dfff3bf34ae7a 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/DocumentActionViewController.swift @@ -40,9 +40,9 @@ class DocumentActionViewController: FPUIActionExtensionViewController { case "com.nextcloud.desktopclient.FileProviderUIExt.ShareAction": prepare(childViewController: ShareViewController(itemIdentifiers)) case "com.nextcloud.desktopclient.FileProviderUIExt.LockFileAction": - prepare(childViewController: LockViewController(itemIdentifiers)) + prepare(childViewController: LockViewController(itemIdentifiers, locking: true)) case "com.nextcloud.desktopclient.FileProviderUIExt.UnlockFileAction": - prepare(childViewController: LockViewController(itemIdentifiers)) + prepare(childViewController: LockViewController(itemIdentifiers, locking: false)) default: return } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 99eee30804ff2..71f318715321b 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -12,5 +12,16 @@ import OSLog import QuickLookThumbnailing class LockViewController: NSViewController { + let itemIdentifiers: [NSFileProviderItemIdentifier] + let locking: Bool + init(_ itemIdentifiers: [NSFileProviderItemIdentifier], locking: Bool) { + self.itemIdentifiers = itemIdentifiers + self.locking = locking + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } } From 515cc5c96cccbd0d75ceba887cdb8d1fc0d2990b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 17:42:39 +0800 Subject: [PATCH 06/26] Design lock view in file provider ui Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 6 + .../Locking/LockViewController.xib | 107 +++++++++++++++++- 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 71f318715321b..03a7b184af026 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -15,6 +15,12 @@ class LockViewController: NSViewController { let itemIdentifiers: [NSFileProviderItemIdentifier] let locking: Bool + @IBOutlet weak var fileNameIcon: NSImageView! + @IBOutlet weak var fileNameLabel: NSTextField! + @IBOutlet weak var descriptionLabel: NSTextField! + @IBOutlet weak var closeButton: NSButton! + @IBOutlet weak var loadingIndicator: NSProgressIndicator! + init(_ itemIdentifiers: [NSFileProviderItemIdentifier], locking: Bool) { self.itemIdentifiers = itemIdentifiers self.locking = locking diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib index 0f40790ecb7ad..61843b01c13dd 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -3,17 +3,114 @@ + - + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 1b2fc0e0340c0412dc75bc81648b29a0b8b7e8f5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 17:43:39 +0800 Subject: [PATCH 07/26] Add close action to lock view controller Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 8 ++++++++ .../FileProviderUIExt/Locking/LockViewController.xib | 3 +++ 2 files changed, 11 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 03a7b184af026..2d7b4735798ed 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -21,6 +21,10 @@ class LockViewController: NSViewController { @IBOutlet weak var closeButton: NSButton! @IBOutlet weak var loadingIndicator: NSProgressIndicator! + var actionViewController: DocumentActionViewController! { + return parent as? DocumentActionViewController + } + init(_ itemIdentifiers: [NSFileProviderItemIdentifier], locking: Bool) { self.itemIdentifiers = itemIdentifiers self.locking = locking @@ -30,4 +34,8 @@ class LockViewController: NSViewController { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + @IBAction func closeAction(_ sender: Any) { + actionViewController.extensionContext.completeRequest() + } } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib index 61843b01c13dd..0a583a09c3f46 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -80,6 +80,9 @@ + + + From 9ccbf3f2c5663c2befe9c56c882dd714d5aa6fae Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:16:06 +0800 Subject: [PATCH 08/26] Move service connection fetcher method into a utils file Signed-off-by: Claudio Cambra --- .../FileProviderCommunication.swift | 31 +++++++++++++++++++ .../Sharing/ShareTableViewDataSource.swift | 23 ++------------ .../project.pbxproj | 4 +++ 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/FileProviderCommunication.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/FileProviderCommunication.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/FileProviderCommunication.swift new file mode 100644 index 0000000000000..111e282dcadb7 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/FileProviderCommunication.swift @@ -0,0 +1,31 @@ +// +// FileProviderCommunication.swift +// FileProviderUIExt +// +// Created by Claudio Cambra on 30/7/24. +// + +import FileProvider + +enum FileProviderCommunicationError: Error { + case serviceNotFound + case remoteProxyObjectInvalid +} + +func serviceConnection( + url: URL, interruptionHandler: @escaping () -> Void +) async throws -> FPUIExtensionService { + let services = try await FileManager().fileProviderServicesForItem(at: url) + guard let service = services[fpUiExtensionServiceName] else { + throw FileProviderCommunicationError.serviceNotFound + } + let connection: NSXPCConnection + connection = try await service.fileProviderConnection() + connection.remoteObjectInterface = NSXPCInterface(with: FPUIExtensionService.self) + connection.interruptionHandler = interruptionHandler + connection.resume() + guard let proxy = connection.remoteObjectProxy as? FPUIExtensionService else { + throw FileProviderCommunicationError.remoteProxyObjectInvalid + } + return proxy +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift index 3cca1d1a9df51..f0d0baf99c852 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift @@ -84,7 +84,9 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } do { - let connection = try await serviceConnection(url: itemURL) + let connection = try await serviceConnection(url: itemURL, interruptionHandler: { + Logger.sharesDataSource.error("Service connection interrupted") + }) guard let serverPath = await connection.itemServerPath(identifier: itemIdentifier), let credentials = await connection.credentials() as? Dictionary, let convertedAccount = Account(dictionary: credentials), @@ -118,25 +120,6 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } } - private func serviceConnection(url: URL) async throws -> FPUIExtensionService { - let services = try await FileManager().fileProviderServicesForItem(at: url) - guard let service = services[fpUiExtensionServiceName] else { - Logger.sharesDataSource.error("Couldn't get service, required service not present") - throw NSFileProviderError(.providerNotFound) - } - let connection: NSXPCConnection - connection = try await service.fileProviderConnection() - connection.remoteObjectInterface = NSXPCInterface(with: FPUIExtensionService.self) - connection.interruptionHandler = { - Logger.sharesDataSource.error("Service connection interrupted") - } - connection.resume() - guard let proxy = connection.remoteObjectProxy as? FPUIExtensionService else { - throw NSFileProviderError(.serverUnreachable) - } - return proxy - } - private func fetch( itemIdentifier: NSFileProviderItemIdentifier, itemRelativePath: String ) async -> [NKShare] { diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index 0a6e233667c45..ff6aa0624e368 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 537630982B8612F00026BFAB /* FPUIExtensionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537630962B860D920026BFAB /* FPUIExtensionService.swift */; }; 537BD67A2C58D67800446ED0 /* LockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6792C58D67800446ED0 /* LockViewController.swift */; }; 537BD67C2C58D7B700446ED0 /* LockViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537BD67B2C58D7B700446ED0 /* LockViewController.xib */; }; + 537BD6802C58F01B00446ED0 /* FileProviderCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */; }; 538E396A27F4765000FA63D5 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */; }; 538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */; }; 538E397627F4765000FA63D5 /* FileProviderExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 538E396727F4765000FA63D5 /* FileProviderExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -167,6 +168,7 @@ 537630962B860D920026BFAB /* FPUIExtensionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPUIExtensionService.swift; sourceTree = ""; }; 537BD6792C58D67800446ED0 /* LockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockViewController.swift; sourceTree = ""; }; 537BD67B2C58D7B700446ED0 /* LockViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LockViewController.xib; sourceTree = ""; }; + 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderCommunication.swift; sourceTree = ""; }; 538E396727F4765000FA63D5 /* FileProviderExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FileProviderExt.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; }; 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = ""; }; @@ -353,6 +355,7 @@ 537BD6782C58D0FC00446ED0 /* Locking */, 537BD6772C58D0C400446ED0 /* Sharing */, 53B979802B84C81F002DA742 /* DocumentActionViewController.swift */, + 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */, 53FE14572B8E3A7C006C4193 /* FileProviderUIExt.entitlements */, 53B979852B84C81F002DA742 /* Info.plist */, ); @@ -725,6 +728,7 @@ 53FE14592B8E3F6C006C4193 /* ShareTableItemView.swift in Sources */, 5376307D2B85E2ED0026BFAB /* Logger+Extensions.swift in Sources */, 53FE14502B8E0658006C4193 /* ShareTableViewDataSource.swift in Sources */, + 537BD6802C58F01B00446ED0 /* FileProviderCommunication.swift in Sources */, 537630982B8612F00026BFAB /* FPUIExtensionService.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From 58586e84ac9718fd4aed71ad6e523404fbd876c8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:47:38 +0800 Subject: [PATCH 09/26] Move item metadata fetch into util file in FileProviderUIExt Signed-off-by: Claudio Cambra --- .../Extensions/Logger+Extensions.swift | 1 + .../FileProviderUIExt/MetadataProvider.swift | 45 +++++++++++++++++ .../Sharing/ShareTableViewDataSource.swift | 49 ++++--------------- .../project.pbxproj | 4 ++ 4 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift index 960171034da09..64836328b5ebd 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift @@ -11,6 +11,7 @@ extension Logger { private static var subsystem = Bundle.main.bundleIdentifier! static let actionViewController = Logger(subsystem: subsystem, category: "actionViewController") + static let metadataProvider = Logger(subsystem: subsystem, category: "metadataProvider") static let shareCapabilities = Logger(subsystem: subsystem, category: "shareCapabilities") static let shareController = Logger(subsystem: subsystem, category: "shareController") static let shareeDataSource = Logger(subsystem: subsystem, category: "shareeDataSource") diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift new file mode 100644 index 0000000000000..890c3206577e2 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift @@ -0,0 +1,45 @@ +// +// MetadataProvider.swift +// FileProviderUIExt +// +// Created by Claudio Cambra on 30/7/24. +// + +import Foundation +import NextcloudKit +import OSLog + +func fetchItemMetadata(itemRelativePath: String, kit: NextcloudKit) async -> NKFile? { + func slashlessPath(_ string: String) -> String { + var strCopy = string + if strCopy.hasPrefix("/") { + strCopy.removeFirst() + } + if strCopy.hasSuffix("/") { + strCopy.removeLast() + } + return strCopy + } + + let nkCommon = kit.nkCommonInstance + let urlBase = slashlessPath(nkCommon.urlBase) + let davSuffix = slashlessPath(nkCommon.dav) + let userId = nkCommon.userId + let itemRelPath = slashlessPath(itemRelativePath) + + let itemFullServerPath = "\(urlBase)/\(davSuffix)/files/\(userId)/\(itemRelPath)" + return await withCheckedContinuation { continuation in + kit.readFileOrFolder(serverUrlFileName: itemFullServerPath, depth: "0") { + account, files, data, error in + guard error == .success else { + Logger.metadataProvider.error( + "Error getting item metadata: \(error.errorDescription)" + ) + continuation.resume(returning: nil) + return + } + Logger.metadataProvider.info("Successfully retrieved item metadata") + continuation.resume(returning: files.first) + } + } +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift index f0d0baf99c852..826711f0c6260 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift @@ -66,7 +66,14 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } func reload() async { - guard let itemURL = itemURL else { return } + guard let itemURL else { + presentError("No item URL, cannot reload data!") + return + } + guard let kit else { + presentError("NextcloudKit instance is unavailable, cannot reload data!") + return + } guard let itemIdentifier = await withCheckedContinuation({ (continuation: CheckedContinuation) -> Void in NSFileProviderManager.getIdentifierForUserVisibleFile( @@ -106,7 +113,7 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele presentError("Server does not support shares.") return } - itemMetadata = await fetchItemMetadata(itemRelativePath: serverPathString) + itemMetadata = await fetchItemMetadata(itemRelativePath: serverPathString, kit: kit) guard itemMetadata?.permissions.contains("R") == true else { presentError("This file cannot be shared.") return @@ -163,44 +170,6 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } } - private func fetchItemMetadata(itemRelativePath: String) async -> NKFile? { - guard let kit = kit else { - presentError("Could not fetch item metadata as NextcloudKit instance is unavailable") - return nil - } - - func slashlessPath(_ string: String) -> String { - var strCopy = string - if strCopy.hasPrefix("/") { - strCopy.removeFirst() - } - if strCopy.hasSuffix("/") { - strCopy.removeLast() - } - return strCopy - } - - let nkCommon = kit.nkCommonInstance - let urlBase = slashlessPath(nkCommon.urlBase) - let davSuffix = slashlessPath(nkCommon.dav) - let userId = nkCommon.userId - let itemRelPath = slashlessPath(itemRelativePath) - - let itemFullServerPath = "\(urlBase)/\(davSuffix)/files/\(userId)/\(itemRelPath)" - return await withCheckedContinuation { continuation in - kit.readFileOrFolder(serverUrlFileName: itemFullServerPath, depth: "0") { - account, files, data, error in - guard error == .success else { - self.presentError("Error getting item metadata: \(error.errorDescription)") - continuation.resume(returning: nil) - return - } - Logger.sharesDataSource.info("Successfully retrieved item metadata") - continuation.resume(returning: files.first) - } - } - } - private func presentError(_ errorString: String) { Logger.sharesDataSource.error("\(errorString, privacy: .public)") Task { @MainActor in self.uiDelegate?.showError(errorString) } diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index ff6aa0624e368..b2613dddd6c04 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 537BD67A2C58D67800446ED0 /* LockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6792C58D67800446ED0 /* LockViewController.swift */; }; 537BD67C2C58D7B700446ED0 /* LockViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537BD67B2C58D7B700446ED0 /* LockViewController.xib */; }; 537BD6802C58F01B00446ED0 /* FileProviderCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */; }; + 537BD6822C58F72E00446ED0 /* MetadataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */; }; 538E396A27F4765000FA63D5 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */; }; 538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */; }; 538E397627F4765000FA63D5 /* FileProviderExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 538E396727F4765000FA63D5 /* FileProviderExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -169,6 +170,7 @@ 537BD6792C58D67800446ED0 /* LockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockViewController.swift; sourceTree = ""; }; 537BD67B2C58D7B700446ED0 /* LockViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LockViewController.xib; sourceTree = ""; }; 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderCommunication.swift; sourceTree = ""; }; + 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetadataProvider.swift; sourceTree = ""; }; 538E396727F4765000FA63D5 /* FileProviderExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FileProviderExt.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; }; 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = ""; }; @@ -356,6 +358,7 @@ 537BD6772C58D0C400446ED0 /* Sharing */, 53B979802B84C81F002DA742 /* DocumentActionViewController.swift */, 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */, + 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */, 53FE14572B8E3A7C006C4193 /* FileProviderUIExt.entitlements */, 53B979852B84C81F002DA742 /* Info.plist */, ); @@ -717,6 +720,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 537BD6822C58F72E00446ED0 /* MetadataProvider.swift in Sources */, 537630932B85F4B00026BFAB /* ShareViewController.swift in Sources */, 53FE14672B8F78B6006C4193 /* ShareOptionsView.swift in Sources */, 53651E462BBC0D9500ECAC29 /* ShareeSuggestionsDataSource.swift in Sources */, From 70d0c74b844c3d7c70cf4231caf4552643016998 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:48:11 +0800 Subject: [PATCH 10/26] Add convenience method to present and log errors in lock view controller Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 2d7b4735798ed..ae113bee7759e 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -38,4 +38,9 @@ class LockViewController: NSViewController { @IBAction func closeAction(_ sender: Any) { actionViewController.extensionContext.completeRequest() } + + private func presentError(_ error: String) { + Logger.lockViewController.error("Error: \(error, privacy: .public)") + descriptionLabel.stringValue = "Error: \(error)" + } } From 7cd50005c2a039d3ae1fd19ccc4b00fad4c2e444 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:51:10 +0800 Subject: [PATCH 11/26] Add method to simply provide file details in locking view Signed-off-by: Claudio Cambra --- .../Extensions/Logger+Extensions.swift | 1 + .../Locking/LockViewController.swift | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift index 64836328b5ebd..d2e38c3cc0953 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift @@ -11,6 +11,7 @@ extension Logger { private static var subsystem = Bundle.main.bundleIdentifier! static let actionViewController = Logger(subsystem: subsystem, category: "actionViewController") + static let lockViewController = Logger(subsystem: subsystem, category: "lockViewController") static let metadataProvider = Logger(subsystem: subsystem, category: "metadataProvider") static let shareCapabilities = Logger(subsystem: subsystem, category: "shareCapabilities") static let shareController = Logger(subsystem: subsystem, category: "shareController") diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index ae113bee7759e..369ac02562121 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -43,4 +43,31 @@ class LockViewController: NSViewController { Logger.lockViewController.error("Error: \(error, privacy: .public)") descriptionLabel.stringValue = "Error: \(error)" } + + private func updateFileDetailsDisplay(itemUrl: URL) async { + let lockAction = locking ? "Locking" : "Unlocking" + fileNameLabel.stringValue = "\(lockAction) file \(itemUrl.lastPathComponent)…" + + let request = QLThumbnailGenerator.Request( + fileAt: itemUrl, + size: CGSize(width: 48, height: 48), + scale: 1.0, + representationTypes: .icon + ) + let generator = QLThumbnailGenerator.shared + let fileThumbnail = await withCheckedContinuation { continuation in + generator.generateRepresentations(for: request) { thumbnail, type, error in + if thumbnail == nil || error != nil { + Logger.lockViewController.error( + "Could not get thumbnail: \(error, privacy: .public)" + ) + } + continuation.resume(returning: thumbnail) + } + } + + fileNameIcon.image = + fileThumbnail?.nsImage ?? + NSImage(systemSymbolName: "doc", accessibilityDescription: "doc") + } } From 72ec0d5f1f9738e30897d1bd55ac0230aa82280a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:51:48 +0800 Subject: [PATCH 12/26] Process target item on init of lock view controller Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 369ac02562121..4116ff7bc7b38 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -29,6 +29,16 @@ class LockViewController: NSViewController { self.itemIdentifiers = itemIdentifiers self.locking = locking super.init(nibName: nil, bundle: nil) + + guard let firstItem = itemIdentifiers.first else { + Logger.shareViewController.error("called without items") + closeAction(self) + return + } + + Task { + await processItemIdentifier(firstItem) + } } required init?(coder: NSCoder) { @@ -44,6 +54,27 @@ class LockViewController: NSViewController { descriptionLabel.stringValue = "Error: \(error)" } + private func processItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) async { + guard let manager = NSFileProviderManager(for: actionViewController.domain) else { + fatalError("NSFileProviderManager isn't expected to fail") + } + + do { + let itemUrl = try await manager.getUserVisibleURL(for: itemIdentifier) + guard itemUrl.startAccessingSecurityScopedResource() else { + Logger.lockViewController.error("Could not access scoped resource for item url!") + return + } + await updateFileDetailsDisplay(itemUrl: itemUrl) + itemUrl.stopAccessingSecurityScopedResource() + } catch let error { + let errorString = "Error processing item: \(error)" + Logger.lockViewController.error("\(errorString, privacy: .public)") + fileNameLabel.stringValue = "Could not lock unknown item…" + descriptionLabel.stringValue = errorString + } + } + private func updateFileDetailsDisplay(itemUrl: URL) async { let lockAction = locking ? "Locking" : "Unlocking" fileNameLabel.stringValue = "\(lockAction) file \(itemUrl.lastPathComponent)…" From 2b7734ac4d65df733c92384cc8ca03b3f4d40fc7 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 30 Jul 2024 18:52:06 +0800 Subject: [PATCH 13/26] Perform lock/unlock procedure in lock view controller Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 4116ff7bc7b38..0916041f60246 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -7,6 +7,7 @@ import AppKit import FileProvider +import NextcloudFileProviderKit import NextcloudKit import OSLog import QuickLookThumbnailing @@ -67,6 +68,7 @@ class LockViewController: NSViewController { } await updateFileDetailsDisplay(itemUrl: itemUrl) itemUrl.stopAccessingSecurityScopedResource() + await lockOrUnlockFile(localItemUrl: itemUrl) } catch let error { let errorString = "Error processing item: \(error)" Logger.lockViewController.error("\(errorString, privacy: .public)") @@ -101,4 +103,88 @@ class LockViewController: NSViewController { fileThumbnail?.nsImage ?? NSImage(systemSymbolName: "doc", accessibilityDescription: "doc") } + + private func lockOrUnlockFile(localItemUrl: URL) async { + descriptionLabel.stringValue = "Fetching file details…" + + guard let itemIdentifier = await withCheckedContinuation({ + (continuation: CheckedContinuation) -> Void in + NSFileProviderManager.getIdentifierForUserVisibleFile( + at: localItemUrl + ) { identifier, domainIdentifier, error in + defer { continuation.resume(returning: identifier) } + guard error == nil else { + self.presentError("No item with identifier: \(error.debugDescription)") + return + } + } + }) else { + presentError("Could not get identifier for item, no shares can be acquired.") + return + } + + do { + let connection = try await serviceConnection(url: localItemUrl, interruptionHandler: { + Logger.lockViewController.error("Service connection interrupted") + }) + guard let serverPath = await connection.itemServerPath(identifier: itemIdentifier), + let credentials = await connection.credentials() as? Dictionary, + let account = Account(dictionary: credentials), + !account.password.isEmpty + else { + presentError("Failed to get details from File Provider Extension.") + return + } + let serverPathString = serverPath as String + let itemServerRelativePath = serverPathString + let kit = NextcloudKit() + kit.setup( + user: account.username, + userId: account.username, + password: account.password, + urlBase: account.serverUrl + ) + // guard let capabilities = await fetchCapabilities() else { + guard let itemMetadata = await fetchItemMetadata( + itemRelativePath: serverPathString, kit: kit + ) else { + presentError("Could not get item metadata.") + return + } + + // Run lock state checks + if locking { + guard !itemMetadata.lock else { + presentError("File is already locked.") + return + } + } else { + guard itemMetadata.lock else { + presentError("File is already unlocked.") + return + } + } + + descriptionLabel.stringValue = + "Communicating with server, \(locking ? "locking" : "unlocking") file…" + + await withCheckedContinuation { continuation in + kit.lockUnlockFile( + serverUrlFileName: itemServerRelativePath, + shouldLock: locking, + completion: { account, error in + if error == .success { + self.descriptionLabel.stringValue = + "File \(self.locking ? "locked" : "unlocked")!" + continuation.resume() + } else { + self.presentError("Could not lock file: \(error).") + } + } + ) + } + } catch let error { + presentError("Could not lock file: \(error).") + } + } } From c5be665ce0f52cc31a9594efd3d1d37c6a616309 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 15:15:57 +0800 Subject: [PATCH 14/26] Add convenience function to stop/hide loading indicator in lock view controller Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 0916041f60246..cdb34165326ee 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -50,6 +50,11 @@ class LockViewController: NSViewController { actionViewController.extensionContext.completeRequest() } + private func stopIndicatingLoading() { + loadingIndicator.stopAnimation(self) + loadingIndicator.isHidden = true + } + private func presentError(_ error: String) { Logger.lockViewController.error("Error: \(error, privacy: .public)") descriptionLabel.stringValue = "Error: \(error)" From cce98f1e841879972a677ce0755ef71a135f849c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 15:16:08 +0800 Subject: [PATCH 15/26] Stop loading indicator when presenting error Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index cdb34165326ee..d261c095510e4 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -58,6 +58,7 @@ class LockViewController: NSViewController { private func presentError(_ error: String) { Logger.lockViewController.error("Error: \(error, privacy: .public)") descriptionLabel.stringValue = "Error: \(error)" + stopIndicatingLoading() } private func processItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) async { From 4db6f8c2edc577660d3af2f8b018502e20ace245 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 15:16:59 +0800 Subject: [PATCH 16/26] Pull out error handling from completionHandler for nckit lockunlock Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index d261c095510e4..d170fc26b41e9 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -174,21 +174,20 @@ class LockViewController: NSViewController { descriptionLabel.stringValue = "Communicating with server, \(locking ? "locking" : "unlocking") file…" - await withCheckedContinuation { continuation in + let error = await withCheckedContinuation { continuation in kit.lockUnlockFile( serverUrlFileName: itemServerRelativePath, shouldLock: locking, - completion: { account, error in - if error == .success { - self.descriptionLabel.stringValue = - "File \(self.locking ? "locked" : "unlocked")!" - continuation.resume() - } else { - self.presentError("Could not lock file: \(error).") - } + completion: { _, error in + continuation.resume(returning: error) } ) } + if error == .success { + descriptionLabel.stringValue = "File \(self.locking ? "locked" : "unlocked")!" + } else { + presentError("Could not lock file: \(error.errorDescription).") + } } catch let error { presentError("Could not lock file: \(error).") } From bcbfdc942ea0acf90b8f9d328924410ad689f94b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 15:17:09 +0800 Subject: [PATCH 17/26] Once finished locking/unlocking, stop loading indicator Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index d170fc26b41e9..3acbfcf1707e4 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -185,6 +185,7 @@ class LockViewController: NSViewController { } if error == .success { descriptionLabel.stringValue = "File \(self.locking ? "locked" : "unlocked")!" + stopIndicatingLoading() } else { presentError("Could not lock file: \(error.errorDescription).") } From 8533fdd4a0e2c06dcf875b98a52048eff06c0579 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 15:33:08 +0800 Subject: [PATCH 18/26] Make sure not to check for kit before we should in shares table view data source Signed-off-by: Claudio Cambra --- .../Sharing/ShareTableViewDataSource.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift index 826711f0c6260..31d9b578fc68e 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift @@ -70,10 +70,6 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele presentError("No item URL, cannot reload data!") return } - guard let kit else { - presentError("NextcloudKit instance is unavailable, cannot reload data!") - return - } guard let itemIdentifier = await withCheckedContinuation({ (continuation: CheckedContinuation) -> Void in NSFileProviderManager.getIdentifierForUserVisibleFile( @@ -113,6 +109,10 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele presentError("Server does not support shares.") return } + guard let kit else { + presentError("NextcloudKit instance is unavailable, cannot reload data!") + return + } itemMetadata = await fetchItemMetadata(itemRelativePath: serverPathString, kit: kit) guard itemMetadata?.permissions.contains("R") == true else { presentError("This file cannot be shared.") From e805993b9fc638dd285aa710bc1058073e4f8413 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 16:55:24 +0800 Subject: [PATCH 19/26] Fix file lock server url in lockviewcontroller Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 3acbfcf1707e4..af24b5ea534e1 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -142,7 +142,6 @@ class LockViewController: NSViewController { return } let serverPathString = serverPath as String - let itemServerRelativePath = serverPathString let kit = NextcloudKit() kit.setup( user: account.username, @@ -173,10 +172,18 @@ class LockViewController: NSViewController { descriptionLabel.stringValue = "Communicating with server, \(locking ? "locking" : "unlocking") file…" - + + let serverUrlFileName = itemMetadata.serverUrl + "/" + itemMetadata.fileName + Logger.lockViewController.info( + """ + Locking file: \(serverUrlFileName, privacy: .public) + \(self.locking ? "locking" : "unlocking", privacy: .public) + """ + ) + let error = await withCheckedContinuation { continuation in kit.lockUnlockFile( - serverUrlFileName: itemServerRelativePath, + serverUrlFileName: serverUrlFileName, shouldLock: locking, completion: { _, error in continuation.resume(returning: error) From 51fba996cb726ef5d60c1ca74d7403c6c273e4c9 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 18:17:54 +0800 Subject: [PATCH 20/26] Fix XIB initialisation in LockViewController Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 21 +++++++++++++++---- .../Locking/LockViewController.xib | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index af24b5ea534e1..4e033740a4474 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -22,6 +22,10 @@ class LockViewController: NSViewController { @IBOutlet weak var closeButton: NSButton! @IBOutlet weak var loadingIndicator: NSProgressIndicator! + public override var nibName: NSNib.Name? { + return NSNib.Name(self.className) + } + var actionViewController: DocumentActionViewController! { return parent as? DocumentActionViewController } @@ -30,22 +34,31 @@ class LockViewController: NSViewController { self.itemIdentifiers = itemIdentifiers self.locking = locking super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func viewDidLoad() { guard let firstItem = itemIdentifiers.first else { Logger.shareViewController.error("called without items") closeAction(self) return } + Logger.lockViewController.info( + """ + Locking \(self.locking ? "enabled" : "disabled", privacy: .public) for items: + \(firstItem.rawValue, privacy: .public) + """ + ) + Task { await processItemIdentifier(firstItem) } } - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - @IBAction func closeAction(_ sender: Any) { actionViewController.extensionContext.completeRequest() } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib index 0a583a09c3f46..33c88d33e328f 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -14,6 +14,7 @@ + From 6d87b210c322d2795b3dbf16af480eb8fe2d41b4 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jul 2024 19:54:02 +0800 Subject: [PATCH 21/26] Fix internal layouting of lock view by simply using a nsview rather than fumbling with a stack view Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.xib | 78 +++++++++---------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib index 33c88d33e328f..cf0a91eedae6f 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -14,35 +14,34 @@ - + - - - + + - - + + - - + + - + - - + + - - + + @@ -50,7 +49,7 @@ - + @@ -59,7 +58,10 @@ - + + + + @@ -70,8 +72,8 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + From ec8b65c24834f5b783cf24cffdfda0d2538865bc Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 1 Aug 2024 15:32:07 +0800 Subject: [PATCH 22/26] Add warn image to locking view if there is an error Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 2 ++ .../FileProviderUIExt/Locking/LockViewController.xib | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 4e033740a4474..3b49c097d5312 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -21,6 +21,7 @@ class LockViewController: NSViewController { @IBOutlet weak var descriptionLabel: NSTextField! @IBOutlet weak var closeButton: NSButton! @IBOutlet weak var loadingIndicator: NSProgressIndicator! + @IBOutlet weak var warnImage: NSImageView! public override var nibName: NSNib.Name? { return NSNib.Name(self.className) @@ -66,6 +67,7 @@ class LockViewController: NSViewController { private func stopIndicatingLoading() { loadingIndicator.stopAnimation(self) loadingIndicator.isHidden = true + warnImage.isHidden = false } private func presentError(_ error: String) { diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib index cf0a91eedae6f..6df0fea32b51b 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.xib @@ -15,6 +15,7 @@ + @@ -29,6 +30,10 @@ + @@ -90,19 +95,23 @@ + + + + @@ -111,6 +120,7 @@ + From 820fbbd3c3c5d16ea3e31bc9b4f9c85b65ee88c8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 1 Aug 2024 15:34:35 +0800 Subject: [PATCH 23/26] Fix NSExtensionFileProviderActionActivationRules for locking menu items Signed-off-by: Claudio Cambra --- .../MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist index 3f843aaed12c3..31930b7627abc 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Info.plist @@ -18,11 +18,11 @@ NSExtensionFileProviderActionName Unlock file NSExtensionFileProviderActionActivationRule - SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo."isUnlockable" == YES ).@count > 0 + SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo.locked != nil && !($fileproviderItem.contentType.identifier UTI-CONFORMS-TO "public.folder") ).@count > 0 NSExtensionFileProviderActionActivationRule - SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo."isLockable" == YES ).@count > 0 + SUBQUERY ( fileproviderItems, $fileproviderItem, $fileproviderItem.userInfo.locked == nil && !($fileproviderItem.contentType.identifier UTI-CONFORMS-TO "public.folder") ).@count > 0 NSExtensionFileProviderActionName Lock file NSExtensionFileProviderActionIdentifier From 71454fc40e392c61fcc4e96a0b0e4720f972cd58 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 1 Aug 2024 15:59:03 +0800 Subject: [PATCH 24/26] Display checkmark when file lock completed Signed-off-by: Claudio Cambra --- .../FileProviderUIExt/Locking/LockViewController.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index 3b49c097d5312..d7070fc9dc789 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -207,6 +207,10 @@ class LockViewController: NSViewController { } if error == .success { descriptionLabel.stringValue = "File \(self.locking ? "locked" : "unlocked")!" + warnImage.image = NSImage( + systemSymbolName: "checkmark.circle.fill", + accessibilityDescription: "checkmark.circle.fill" + ) stopIndicatingLoading() } else { presentError("Could not lock file: \(error.errorDescription).") From bda7d45a6b164466e6e187a15528efbc115dda87 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 1 Aug 2024 16:21:01 +0800 Subject: [PATCH 25/26] Do not provide items if account is not set up correctly Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index fd3670a38f2c2..db5eda2d50beb 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -104,7 +104,15 @@ import OSLog request _: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void ) -> Progress { - if let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) { + if ncAccount == nil { + Logger.fileProviderExtension.error( + """ + Not fetching item for identifier: \(identifier.rawValue, privacy: .public) + as account not set up yet. + """ + ) + completionHandler(nil, NSFileProviderError(.notAuthenticated)) + } else if let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) { completionHandler(item, nil) } else { completionHandler(nil, NSFileProviderError(.noSuchItem)) From 44f640a330b48e6953b0ddaf72ae7e043f66c064 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 1 Aug 2024 17:36:35 +0800 Subject: [PATCH 26/26] Signal enumeration of locked/unlocked file Signed-off-by: Claudio Cambra --- .../Locking/LockViewController.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift index d7070fc9dc789..f7347848afc7f 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Locking/LockViewController.swift @@ -212,6 +212,18 @@ class LockViewController: NSViewController { accessibilityDescription: "checkmark.circle.fill" ) stopIndicatingLoading() + if let manager = NSFileProviderManager(for: actionViewController.domain) { + do { + try await manager.signalEnumerator(for: itemIdentifier) + } catch let error { + presentError( + """ + Could not signal lock state change in virtual file. + Changes may take a while to be reflected on your Mac. + Error: \(error.localizedDescription) + """) + } + } } else { presentError("Could not lock file: \(error.errorDescription).") }