Browse Source

Delete / Move / Copy (#2554)

* delete

* add indexPath

* cleaning code

* added queryDB

* added refresh()

* coding

* Update NCMenuAction.swift

* coding

* Update NCMedia.swift

* Update NCOperationQueue.swift

* Update NCGlobal.swift

* coding

* Update NCMenuAction.swift

* coding

* cleaning

* coding

* Update Localizable.strings

* coding

* cleaning code

* Update NCViewerMediaPage.swift

* #2548

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* Improvements

* cleaning

* cleaning

* Build 2

* #2551

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* Update NCMedia.swift

* improved code

* fixed

---------

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>
Marino Faggiana 1 year ago
parent
commit
f06f5c180a
68 changed files with 988 additions and 971 deletions
  1. 2 0
      Brand/Intro/NCIntroCollectionViewCell.swift
  2. 1 1
      Brand/Intro/NCIntroViewController.swift
  3. 18 2
      Nextcloud.xcodeproj/project.pbxproj
  4. 1 0
      Share/NCShareExtension+DataSource.swift
  5. 1 0
      Share/NCShareExtension+NCDelegate.swift
  6. 3 2
      iOSClient/Activity/NCActivity.swift
  7. 7 0
      iOSClient/Activity/NCActivityTableViewCell.swift
  8. 1 12
      iOSClient/Data/NCDataSource.swift
  9. 0 18
      iOSClient/Data/NCDatabase.swift
  10. 16 10
      iOSClient/Data/NCManageDatabase+Account.swift
  11. 12 6
      iOSClient/Data/NCManageDatabase+Activity.swift
  12. 4 2
      iOSClient/Data/NCManageDatabase+Avatar.swift
  13. 2 1
      iOSClient/Data/NCManageDatabase+Capabilities.swift
  14. 4 2
      iOSClient/Data/NCManageDatabase+DashboardWidget.swift
  15. 16 2
      iOSClient/Data/NCManageDatabase+Directory.swift
  16. 10 5
      iOSClient/Data/NCManageDatabase+E2EE.swift
  17. 2 1
      iOSClient/Data/NCManageDatabase+LayoutForView.swift
  18. 209 0
      iOSClient/Data/NCManageDatabase+LocalFile.swift
  19. 33 16
      iOSClient/Data/NCManageDatabase+Metadata.swift
  20. 10 6
      iOSClient/Data/NCManageDatabase+Share.swift
  21. 2 1
      iOSClient/Data/NCManageDatabase+Video.swift
  22. 13 145
      iOSClient/Data/NCManageDatabase.swift
  23. 27 23
      iOSClient/Favorites/NCFavorite.swift
  24. 35 31
      iOSClient/Files/NCFiles.swift
  25. 9 6
      iOSClient/Groupfolders/NCGroupfolders.swift
  26. 60 38
      iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
  27. 11 10
      iOSClient/Main/Collection Common/NCGridCell.swift
  28. 13 12
      iOSClient/Main/Collection Common/NCListCell.swift
  29. 6 4
      iOSClient/Main/Collection Common/NCSelectableNavigationView.swift
  30. 1 1
      iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift
  31. 1 1
      iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift
  32. 37 8
      iOSClient/Main/NCActionCenter.swift
  33. 1 0
      iOSClient/Main/NCCellProtocol.swift
  34. 2 1
      iOSClient/Media/Cell/NCGridMediaCell.swift
  35. 79 58
      iOSClient/Media/NCMedia.swift
  36. 4 3
      iOSClient/Menu/NCCollectionViewCommon+Menu.swift
  37. 9 5
      iOSClient/Menu/NCContextMenu.swift
  38. 4 2
      iOSClient/Menu/NCMedia+Menu.swift
  39. 12 8
      iOSClient/Menu/NCMenuAction.swift
  40. 4 3
      iOSClient/Menu/NCViewer+Menu.swift
  41. 4 6
      iOSClient/NCGlobal.swift
  42. 2 2
      iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift
  43. 36 49
      iOSClient/Networking/NCNetworking.swift
  44. 0 54
      iOSClient/Networking/NCOperationQueue.swift
  45. 7 0
      iOSClient/Notification/NCNotification.swift
  46. 37 33
      iOSClient/Offline/NCOffline.swift
  47. 16 12
      iOSClient/Recent/NCRecent.swift
  48. 6 5
      iOSClient/Rename file/NCRenameFile.swift
  49. 2 0
      iOSClient/Scan document/NCScan+CollectionView.swift
  50. 1 0
      iOSClient/Scan document/NCScanCell.swift
  51. 1 1
      iOSClient/Scan document/NCUploadScanDocument.swift
  52. 87 291
      iOSClient/Select/NCSelect.swift
  53. 2 0
      iOSClient/Share/NCShare.swift
  54. 6 0
      iOSClient/Share/NCShareCommentsCell.swift
  55. 1 0
      iOSClient/Share/NCShareLinkCell.swift
  56. 11 0
      iOSClient/Share/NCShareUserCell.swift
  57. 15 6
      iOSClient/Shares/NCShares.swift
  58. 3 0
      iOSClient/Supporting Files/en.lproj/Localizable.strings
  59. 10 10
      iOSClient/Transfers/NCTransferCell.swift
  60. 11 7
      iOSClient/Transfers/NCTransfers.swift
  61. 2 0
      iOSClient/Trash/Cell/NCTrashListCell+NCTrashCellProtocol.swift
  62. 1 0
      iOSClient/Trash/NCTrash+CollectionView.swift
  63. 2 1
      iOSClient/Trash/NCTrash.swift
  64. 5 5
      iOSClient/Viewer/NCViewer.swift
  65. 1 1
      iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift
  66. 13 24
      iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift
  67. 23 17
      iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift
  68. 1 1
      iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift

+ 2 - 0
Brand/Intro/NCIntroCollectionViewCell.swift

@@ -30,6 +30,8 @@ class NCIntroCollectionViewCell: UICollectionViewCell {
     @IBOutlet weak var titleLabel: UILabel!
     @IBOutlet weak var imageView: UIImageView!
 
+    var indexPath = IndexPath()
+
     override func awakeFromNib() {
         super.awakeFromNib()
     }

+ 1 - 1
Brand/Intro/NCIntroViewController.swift

@@ -137,7 +137,7 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
         let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "introCell", for: indexPath) as? NCIntroCollectionViewCell)!
         cell.backgroundColor = NCBrandColor.shared.customer
-
+        cell.indexPath = indexPath
         cell.titleLabel.textColor = textColor
         cell.titleLabel.text = titles[indexPath.row]
         cell.imageView.image = images[indexPath.row]

+ 18 - 2
Nextcloud.xcodeproj/project.pbxproj

@@ -462,6 +462,13 @@
 		F785EEA42461A4A600B3F945 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; };
 		F785EEA52461A4CF00B3F945 /* CCUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F7053E3D1C639DF500741EA5 /* CCUtility.m */; };
 		F785EEA62461A4FB00B3F945 /* CCUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F7053E3D1C639DF500741EA5 /* CCUtility.m */; };
+		F7864ACC2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864ACD2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864ACE2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864ACF2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864AD02A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864AD12A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
+		F7864AD22A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */; };
 		F787704F22E7019900F287A9 /* NCShareLinkCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F787704E22E7019900F287A9 /* NCShareLinkCell.xib */; };
 		F787AC09298BCB4A0001BB00 /* SVGKitSwift in Frameworks */ = {isa = PBXBuildFile; productRef = F787AC08298BCB4A0001BB00 /* SVGKitSwift */; };
 		F787AC0B298BCB540001BB00 /* SVGKitSwift in Frameworks */ = {isa = PBXBuildFile; productRef = F787AC0A298BCB540001BB00 /* SVGKitSwift */; };
@@ -1100,6 +1107,7 @@
 		F783031028B4C86200B84583 /* libc++.1.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.1.tbd"; path = "usr/lib/libc++.1.tbd"; sourceTree = SDKROOT; };
 		F783031128B4C86200B84583 /* libc++abi.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++abi.tbd"; path = "usr/lib/libc++abi.tbd"; sourceTree = SDKROOT; };
 		F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EE.swift; sourceTree = "<group>"; };
+		F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+LocalFile.swift"; sourceTree = "<group>"; };
 		F787704E22E7019900F287A9 /* NCShareLinkCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareLinkCell.xib; sourceTree = "<group>"; };
 		F78A10BE29322E8A008499B8 /* NCManageDatabase+Directory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Directory.swift"; sourceTree = "<group>"; };
 		F78A18B523CDD07D00F681F3 /* NCViewerRichWorkspaceWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerRichWorkspaceWebView.swift; sourceTree = "<group>"; };
@@ -2172,6 +2180,7 @@
 				F72FD3B4297ED49A00075D28 /* NCManageDatabase+E2EE.swift */,
 				F757CC8129E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift */,
 				F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */,
+				F7864ACB2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift */,
 				AF4BF61827562A4B0081CEEF /* NCManageDatabase+Metadata.swift */,
 				F749B649297B0CBB00087535 /* NCManageDatabase+Share.swift */,
 				F7E98C1527E0D0FC001F9F19 /* NCManageDatabase+Video.swift */,
@@ -3288,6 +3297,7 @@
 				F72FD3BA297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */,
 				F7E98C1927E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */,
 				2C1D5D7623E2DE3300334ABB /* NCManageDatabase.swift in Sources */,
+				F7864AD22A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F314F1142A30E2DE00BC7FAB /* View+Extension.swift in Sources */,
 				F7D68FD028CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift in Sources */,
 				F343A4C12A1E734600DDA874 /* Optional+Extension.swift in Sources */,
@@ -3379,6 +3389,7 @@
 				F7490E6C29882AEA009DCE94 /* String+Extension.swift in Sources */,
 				F7490E6B29882A92009DCE94 /* NCGlobal.swift in Sources */,
 				F7490E7529882BE2009DCE94 /* NCManageDatabase+Directory.swift in Sources */,
+				F7864AD12A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F7490E8729882CA8009DCE94 /* ThreadSafeDictionary.swift in Sources */,
 				F757CC8729E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */,
 				F7490E8229882C80009DCE94 /* NCManageDatabase+E2EE.swift in Sources */,
@@ -3391,6 +3402,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				F7864ACF2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F7245925289BB59100474787 /* ThreadSafeDictionary.swift in Sources */,
 				F7EDE4E5262D7BBE00414FE6 /* NCSectionHeaderMenu.swift in Sources */,
 				F7BF9D852934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
@@ -3479,6 +3491,7 @@
 				F78302FE28B4C44700B84583 /* NCBrand.swift in Sources */,
 				F749B64B297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */,
 				F7817CF929801A3500FFBC65 /* Data+Extension.swift in Sources */,
+				F7864ACD2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F343A4B42A1E084100DDA874 /* PHAsset+Extension.swift in Sources */,
 				F793E59F28B764F6005E4B02 /* NCContentPresenter.swift in Sources */,
 				F76DEE9828F808AF0041B1C9 /* LockscreenWidgetProvider.swift in Sources */,
@@ -3536,6 +3549,7 @@
 				F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */,
 				F798F0E725880609000DAFFD /* UIColor+Extension.swift in Sources */,
 				F7D68FCF28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift in Sources */,
+				F7864AD02A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				AF4BF61B27562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */,
 				F70460542499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
 				F78A10C329322E8A008499B8 /* NCManageDatabase+Directory.swift in Sources */,
@@ -3749,6 +3763,7 @@
 				F7C7B489245EBA4100D93E60 /* NCViewerQuickLook.swift in Sources */,
 				F758B45E212C569D00515F55 /* NCScanCell.swift in Sources */,
 				F7581D1A25EFDA61004DC699 /* NCLoginWeb+Menu.swift in Sources */,
+				F7864ACC2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F7F4F11027ECDC4A008676F9 /* UIDevice+Extension.swift in Sources */,
 				F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */,
 				F70D8D8124A4A9BF000A5756 /* NCNetworkingProcessUpload.swift in Sources */,
@@ -3792,6 +3807,7 @@
 				F72FD3B7297ED49A00075D28 /* NCManageDatabase+E2EE.swift in Sources */,
 				F7A8D74128F18254008BBE1C /* UIColor+Extension.swift in Sources */,
 				F7A8D73428F17E12008BBE1C /* NCDatabase.swift in Sources */,
+				F7864ACE2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F7A8D74028F18212008BBE1C /* UIImage+Extension.swift in Sources */,
 				F757CC8429E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */,
 				F78E2D6729AF02DB0024D4F3 /* Database.swift in Sources */,
@@ -4608,7 +4624,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 1;
+				CURRENT_PROJECT_VERSION = 2;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4673,7 +4689,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 1;
+				CURRENT_PROJECT_VERSION = 2;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;

+ 1 - 0
Share/NCShareExtension+DataSource.swift

@@ -65,6 +65,7 @@ extension NCShareExtension: UICollectionViewDataSource {
         cell.delegate = self
 
         cell.fileObjectId = metadata.ocId
+        cell.indexPath = indexPath
         cell.fileUser = metadata.ownerId
         cell.labelTitle.text = metadata.fileNameView
         cell.labelTitle.textColor = .label

+ 1 - 0
Share/NCShareExtension+NCDelegate.swift

@@ -127,6 +127,7 @@ extension NCShareExtension: NCShareCellDelegate, NCRenameFileDelegate, NCListCel
         let resultInternalType = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: fileName, mimeType: "", directory: false)
         vcRename.delegate = self
         vcRename.fileName = fileName
+        vcRename.indexPath = IndexPath()
         if let previewImage = UIImage.downsample(imageAt: URL(fileURLWithPath: NSTemporaryDirectory() + fileName), to: CGSize(width: 140, height: 140)) {
             vcRename.imagePreview = previewImage
         } else {

+ 3 - 2
iOSClient/Activity/NCActivity.swift

@@ -213,6 +213,7 @@ extension NCActivity: UITableViewDataSource {
             return UITableViewCell()
         }
 
+        cell.indexPath = indexPath
         cell.tableComments = comment
         cell.delegate = self
         cell.sizeToFit()
@@ -247,7 +248,7 @@ extension NCActivity: UITableViewDataSource {
         var orderKeysId: [String] = []
 
         cell.idActivity = activity.idActivity
-
+        cell.indexPath = indexPath
         cell.avatar.image = nil
         cell.avatar.isHidden = true
         cell.subjectTrailingConstraint.constant = 10
@@ -360,7 +361,7 @@ extension NCActivity {
         if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
             bottom = -mainTabBar.getHight()
         }
-        NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom-5, style: .medium)
+        NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom - 5, style: .medium)
 
         let dispatchGroup = DispatchGroup()
         loadComments(disptachGroup: dispatchGroup)

+ 7 - 0
iOSClient/Activity/NCActivityTableViewCell.swift

@@ -31,6 +31,7 @@ class NCActivityCollectionViewCell: UICollectionViewCell {
     @IBOutlet weak var imageView: UIImageView!
 
     var fileId = ""
+    var indexPath = IndexPath()
 
     override func awakeFromNib() {
         super.awakeFromNib()
@@ -49,12 +50,17 @@ class NCActivityTableViewCell: UITableViewCell, NCCellProtocol {
     @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
 
     private var user: String = ""
+    private var index = IndexPath()
 
     var idActivity: Int = 0
     var activityPreviews: [tableActivityPreview] = []
     var didSelectItemEnable: Bool = true
     var viewController = UIViewController()
 
+    var indexPath: IndexPath {
+        get { return index }
+        set { index = newValue }
+    }
     var fileAvatarImageView: UIImageView? {
         get { return avatar }
     }
@@ -145,6 +151,7 @@ extension NCActivityTableViewCell: UICollectionViewDataSource {
         let cell: NCActivityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! NCActivityCollectionViewCell
 
         cell.imageView.image = nil
+        cell.indexPath = indexPath
 
         let activityPreview = activityPreviews[indexPath.row]
         let fileId = String(activityPreview.fileId)

+ 1 - 12
iOSClient/Data/NCDataSource.swift

@@ -35,7 +35,6 @@ class NCDataSource: NSObject {
     private var sectionsValue: [String] = []
     private var providers: [NKSearchProvider]?
     private var searchResults: [NKSearchResult]?
-    private var localFiles: [tableLocalFile] = []
 
     private var ascending: Bool = true
     private var sort: String = ""
@@ -54,7 +53,6 @@ class NCDataSource: NSObject {
             !(NCGlobal.shared.includeHiddenFiles.contains($0.fileNameView) || $0.isTransferInForeground)
         })
         self.directory = directory
-        self.localFiles = NCManageDatabase.shared.getTableLocalFile(account: account)
         self.sort = sort ?? "none"
         self.ascending = ascending ?? false
         self.directoryOnTop = directoryOnTop ?? true
@@ -78,7 +76,6 @@ class NCDataSource: NSObject {
         self.sectionsValue.removeAll()
         self.providers = nil
         self.searchResults = nil
-        self.localFiles.removeAll()
     }
 
     func clearDirectory() {
@@ -175,7 +172,6 @@ class NCDataSource: NSObject {
         let metadatas = self.metadatas.filter({ getSectionValue(metadata: $0) == sectionValue})
         let metadataForSection = NCMetadataForSection(sectionValue: sectionValue,
                                                       metadatas: metadatas,
-                                                      localFiles: self.localFiles,
                                                       lastSearchResult: searchResult,
                                                       sort: self.sort,
                                                       ascending: self.ascending,
@@ -341,7 +337,6 @@ class NCMetadataForSection: NSObject {
 
     var sectionValue: String
     var metadatas: [tableMetadata]
-    var localFiles: [tableLocalFile]
     var lastSearchResult: NKSearchResult?
     var unifiedSearchInProgress: Bool = false
 
@@ -360,14 +355,11 @@ class NCMetadataForSection: NSObject {
     public var numDirectory: Int = 0
     public var numFile: Int = 0
     public var totalSize: Int64 = 0
-    public var metadataOffLine: [String] = []
-    public var directories: [tableDirectory]?
 
-    init(sectionValue: String, metadatas: [tableMetadata], localFiles: [tableLocalFile], lastSearchResult: NKSearchResult?, sort: String, ascending: Bool, directoryOnTop: Bool, favoriteOnTop: Bool, filterLivePhoto: Bool) {
+    init(sectionValue: String, metadatas: [tableMetadata], lastSearchResult: NKSearchResult?, sort: String, ascending: Bool, directoryOnTop: Bool, favoriteOnTop: Bool, filterLivePhoto: Bool) {
 
         self.sectionValue = sectionValue
         self.metadatas = metadatas
-        self.localFiles = localFiles
         self.lastSearchResult = lastSearchResult
         self.sort = sort
         self.ascending = ascending
@@ -389,7 +381,6 @@ class NCMetadataForSection: NSObject {
         metadatasFavoriteFile.removeAll()
         metadatasDirectory.removeAll()
         metadatasFile.removeAll()
-        metadataOffLine.removeAll()
 
         numDirectory = 0
         numFile = 0
@@ -474,8 +465,6 @@ class NCMetadataForSection: NSObject {
             }
         }
 
-        directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "ocId IN %@", ocIds), sorted: "serverUrl", ascending: true)
-
         metadatas.removeAll()
 
         // Struct view : favorite dir -> favorite file -> directory -> files

+ 0 - 18
iOSClient/Data/NCDatabase.swift

@@ -109,24 +109,6 @@ class tableGPS: Object {
     @objc dynamic var placemarkThoroughfare = ""
 }
 
-class tableLocalFile: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var etag = ""
-    @objc dynamic var exifDate: NSDate?
-    @objc dynamic var exifLatitude = ""
-    @objc dynamic var exifLongitude = ""
-    @objc dynamic var exifLensModel: String?
-    @objc dynamic var favorite: Bool = false
-    @objc dynamic var fileName = ""
-    @objc dynamic var ocId = ""
-    @objc dynamic var offline: Bool = false
-
-    override static func primaryKey() -> String {
-        return "ocId"
-    }
-}
-
 class tablePhotoLibrary: Object {
 
     @objc dynamic var account = ""

+ 16 - 10
iOSClient/Data/NCManageDatabase+Account.swift

@@ -148,10 +148,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return nil }
             return tableAccount.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -161,12 +162,13 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableAccount.self).sorted(byKeyPath: "account", ascending: true)
             if !results.isEmpty {
                 return Array(results.map { $0.account })
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -176,10 +178,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAccount.self).filter(predicate).first else { return nil }
             return tableAccount.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -189,11 +192,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "user", ascending: true)]
             let results = realm.objects(tableAccount.self).sorted(by: sorted)
             return Array(results.map { tableAccount.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -203,11 +207,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "alias", ascending: true), SortDescriptor(keyPath: "user", ascending: true)]
             let results = realm.objects(tableAccount.self).sorted(by: sorted)
             return Array(results.map { tableAccount.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -217,6 +222,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return "" }
             if result.autoUploadFileName.isEmpty {
                 return NCBrandOptions.shared.folderDefaultAutoUpload
@@ -224,7 +230,7 @@ extension NCManageDatabase {
                 return result.autoUploadFileName
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return ""
@@ -234,6 +240,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return "" }
             if result.autoUploadDirectory.isEmpty {
                 return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId)
@@ -246,7 +253,7 @@ extension NCManageDatabase {
                 }
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return ""
@@ -266,10 +273,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return NCGlobal.shared.subfolderGranularityMonthly }
             return result.autoUploadSubfolderGranularity
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return NCGlobal.shared.subfolderGranularityMonthly
@@ -283,7 +291,6 @@ extension NCManageDatabase {
         do {
             let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableAccount.self)
                 for result in results {
                     if result.account == account {
@@ -307,7 +314,6 @@ extension NCManageDatabase {
         do {
             let realm = try Realm()
             try realm.write {
-
                 if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
                     result.password = "********"
                 }

+ 12 - 6
iOSClient/Data/NCManageDatabase+Activity.swift

@@ -196,6 +196,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableActivity.self).filter(predicate).sorted(byKeyPath: "idActivity", ascending: false)
             let allActivity = Array(results.map(tableActivity.init))
             guard let filterFileId = filterFileId else {
@@ -205,7 +206,7 @@ extension NCManageDatabase {
             let filtered = allActivity.filter({ String($0.objectId) == filterFileId && $0.type != "comments" })
             return (all: allActivity, filter: filtered)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return([], [])
@@ -215,10 +216,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && key == %@", account, idActivity, key).first
             return results.map { tableActivitySubjectRich.init(value: $0) }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -228,6 +230,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && id == %@", account, idActivity, id)
             var activitySubjectRich = results.first
             if results.count == 2 {
@@ -239,7 +242,7 @@ extension NCManageDatabase {
             }
             return activitySubjectRich.map { tableActivitySubjectRich.init(value: $0) }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -251,6 +254,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             for id in orderKeysId {
                 if let result = realm.objects(tableActivityPreview.self).filter("account == %@ && idActivity == %d && fileId == %d", account, idActivity, Int(id) ?? 0).first {
                     results.append(result)
@@ -258,7 +262,7 @@ extension NCManageDatabase {
             }
             return results
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -284,9 +288,10 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             return realm.objects(tableActivityLatestId.self).filter("account == %@", account).first
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -328,10 +333,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId).sorted(byKeyPath: "creationDateTime", ascending: false)
             return Array(results.map(tableComments.init))
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []

+ 4 - 2
iOSClient/Data/NCManageDatabase+Avatar.swift

@@ -60,10 +60,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first else { return nil }
             return tableAvatar.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -116,6 +117,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first
             if result == nil {
                 NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)
@@ -125,7 +127,7 @@ extension NCManageDatabase {
             }
             return UIImage(contentsOfFile: fileNameLocalPath)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)

+ 2 - 1
iOSClient/Data/NCManageDatabase+Capabilities.swift

@@ -56,10 +56,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else { return nil }
             return result.jsondata
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil

+ 4 - 2
iOSClient/Data/NCManageDatabase+DashboardWidget.swift

@@ -54,11 +54,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let resultDashboard = realm.objects(tableDashboardWidget.self).filter("account == %@ AND id == %@", account, id).first else { return (nil, nil) }
             let resultsButton = realm.objects(tableDashboardWidgetButton.self).filter("account == %@ AND id == %@", account, id).sorted(byKeyPath: "type", ascending: true)
             return (tableDashboardWidget.init(value: resultDashboard), Array(resultsButton.map { tableDashboardWidgetButton.init(value: $0) }))
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return (nil, nil)
@@ -68,11 +69,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sortProperties = [SortDescriptor(keyPath: "order", ascending: true), SortDescriptor(keyPath: "title", ascending: true)]
             let results = realm.objects(tableDashboardWidget.self).filter("account == %@", account).sorted(by: sortProperties)
             return Array(results.map { tableDashboardWidget.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []

+ 16 - 2
iOSClient/Data/NCManageDatabase+Directory.swift

@@ -128,19 +128,33 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableDirectory.self).filter(predicate).first else { return nil }
             return tableDirectory.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
     }
 
+    func getTableDirectory(ocId: String) -> tableDirectory? {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            return realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+        return nil
+    }
+
     func getTablesDirectory(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableDirectory]? {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableDirectory.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
             if results.isEmpty {
                 return nil
@@ -148,7 +162,7 @@ extension NCManageDatabase {
                 return Array(results.map { tableDirectory.init(value: $0) })
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil

+ 10 - 5
iOSClient/Data/NCManageDatabase+E2EE.swift

@@ -102,10 +102,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableE2eEncryption.self).filter(predicate).sorted(byKeyPath: "metadataKeyIndex", ascending: false).first else { return nil }
             return tableE2eEncryption.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -117,6 +118,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results: Results<tableE2eEncryption>
             results = realm.objects(tableE2eEncryption.self).filter(predicate)
             if results.isEmpty {
@@ -125,7 +127,7 @@ extension NCManageDatabase {
                 return Array(results.map { tableE2eEncryption.init(value: $0) })
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -157,10 +159,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
             return tableE2eEncryptionLock.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -170,6 +173,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableE2eEncryptionLock.self).filter("account == %@", account)
             if results.isEmpty {
                 return []
@@ -177,7 +181,7 @@ extension NCManageDatabase {
                 return Array(results.map { tableE2eEncryptionLock.init(value: $0) })
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -221,10 +225,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableE2eMetadata.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
             return tableE2eMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil

+ 2 - 1
iOSClient/Data/NCManageDatabase+LayoutForView.swift

@@ -117,13 +117,14 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
                 return NCDBLayoutForView(value: result)
             } else {
                 return setLayoutForView(account: account, key: key, serverUrl: serverUrl)
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return setLayoutForView(account: account, key: key, serverUrl: serverUrl)

+ 209 - 0
iOSClient/Data/NCManageDatabase+LocalFile.swift

@@ -0,0 +1,209 @@
+//
+//  NCManageDatabase+LocalFile.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 01/08/23.
+//  Copyright © 2023 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+import RealmSwift
+import NextcloudKit
+
+class tableLocalFile: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var etag = ""
+    @objc dynamic var exifDate: NSDate?
+    @objc dynamic var exifLatitude = ""
+    @objc dynamic var exifLongitude = ""
+    @objc dynamic var exifLensModel: String?
+    @objc dynamic var favorite: Bool = false
+    @objc dynamic var fileName = ""
+    @objc dynamic var ocId = ""
+    @objc dynamic var offline: Bool = false
+
+    override static func primaryKey() -> String {
+        return "ocId"
+    }
+}
+extension NCManageDatabase {
+
+    // MARK: -
+    // MARK: Table LocalFile - return RESULT
+
+    func getTableLocalFile(ocId: String) -> tableLocalFile? {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            return realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+        return nil
+    }
+
+    // MARK: -
+    // MARK: Table LocalFile
+
+    func addLocalFile(metadata: tableMetadata) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let addObject = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) ?? tableLocalFile()
+                addObject.account = metadata.account
+                addObject.etag = metadata.etag
+                addObject.exifDate = NSDate()
+                addObject.exifLatitude = "-1"
+                addObject.exifLongitude = "-1"
+                addObject.ocId = metadata.ocId
+                addObject.fileName = metadata.fileName
+                realm.add(addObject, update: .all)
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func addLocalFile(account: String, etag: String, ocId: String, fileName: String) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let addObject = tableLocalFile()
+                addObject.account = account
+                addObject.etag = etag
+                addObject.exifDate = NSDate()
+                addObject.exifLatitude = "-1"
+                addObject.exifLongitude = "-1"
+                addObject.ocId = ocId
+                addObject.fileName = fileName
+                realm.add(addObject, update: .all)
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func deleteLocalFile(predicate: NSPredicate) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let results = realm.objects(tableLocalFile.self).filter(predicate)
+                realm.delete(results)
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func setLocalFile(ocId: String, fileName: String?, etag: String?) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
+                if let fileName = fileName {
+                    result?.fileName = fileName
+                }
+                if let etag = etag {
+                    result?.etag = etag
+                }
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    @objc func setLocalFile(ocId: String, exifDate: NSDate?, exifLatitude: String, exifLongitude: String, exifLensModel: String?) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first {
+                    result.exifDate = exifDate
+                    result.exifLatitude = exifLatitude
+                    result.exifLongitude = exifLongitude
+                    if exifLensModel?.count ?? 0 > 0 {
+                        result.exifLensModel = exifLensModel
+                    }
+                }
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func setLocalFile(ocId: String, offline: Bool) {
+
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
+                result?.offline = offline
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func getTableLocalFile(account: String) -> [tableLocalFile] {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            let results = realm.objects(tableLocalFile.self).filter("account == %@", account)
+            return Array(results.map { tableLocalFile.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+
+        return []
+    }
+
+    func getTableLocalFile(predicate: NSPredicate) -> tableLocalFile? {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else { return nil }
+            return tableLocalFile.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+
+        return nil
+    }
+
+    func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            return Array(results.map { tableLocalFile.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+
+        return []
+    }
+}

+ 33 - 16
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -751,10 +751,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableMetadata.self).filter(predicate).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -764,10 +765,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -780,6 +782,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             if (tableMetadata().objectSchema.properties.contains { $0.name == sorted }) {
                 results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
             } else {
@@ -804,7 +807,7 @@ extension NCManageDatabase {
                 }
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         if finals.isEmpty {
@@ -818,10 +821,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableMetadata.self).filter(predicate)
             return Array(results.map { tableMetadata.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -833,6 +837,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
             if !results.isEmpty {
                 if page == 0 || limit == 0 {
@@ -849,7 +854,7 @@ extension NCManageDatabase {
                 }
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return metadatas
@@ -859,6 +864,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
             if results.isEmpty {
                 return nil
@@ -866,7 +872,7 @@ extension NCManageDatabase {
                 return tableMetadata.init(value: results[index])
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -877,10 +883,11 @@ extension NCManageDatabase {
         guard let ocId else { return nil }
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -891,9 +898,10 @@ extension NCManageDatabase {
         guard let ocId else { return nil }
         do {
             let realm = try Realm()
+            realm.refresh()
             return realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
         return nil
     }
@@ -902,11 +910,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let fileId = fileId else { return nil }
             guard let result = realm.objects(tableMetadata.self).filter("fileId == %@", fileId).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -930,10 +939,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -946,13 +956,14 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableMetadata.self).filter("account == %@ AND directory == true AND favorite == true", account).sorted(byKeyPath: "fileNameView", ascending: true)
             for result in results {
                 counter += 1
                 listIdentifierRank[result.ocId] = NSNumber(value: Int64(counter))
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return listIdentifierRank
@@ -992,12 +1003,13 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier != '' AND deleteAssetLocalIdentifier == true", account)
             for result in results {
                 assetLocalIdentifiers.append(result.assetLocalIdentifier)
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return assetLocalIdentifiers
@@ -1007,6 +1019,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             try realm.write {
                 let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier IN %@", account, assetLocalIdentifiers)
                 for result in results {
@@ -1038,10 +1051,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@ AND ocId != %@ AND classFile == %@", metadata.account, metadata.serverUrl, fileName, metadata.ocId, classFile)).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -1137,9 +1151,10 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             return realm.objects(tableMetadata.self).filter(NSPredicate(format: "status == %i || status == %i", NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)).count
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return 0
@@ -1149,11 +1164,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let directory = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
             guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", directory.ocId).first else { return nil }
             return tableMetadata.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -1166,6 +1182,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let groupfolders = realm.objects(TableGroupfolders.self).filter("account == %@", account)
             for groupfolder in groupfolders {
                 let mountPoint = groupfolder.mountPoint.hasPrefix("/") ? groupfolder.mountPoint : "/" + groupfolder.mountPoint
@@ -1176,7 +1193,7 @@ extension NCManageDatabase {
                 }
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return metadatas

+ 10 - 6
iOSClient/Data/NCManageDatabase+Share.swift

@@ -141,11 +141,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
             let results = realm.objects(tableShare.self).filter("account == %@", account).sorted(by: sortProperties)
             return Array(results.map { tableShare.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -155,6 +156,7 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
             let firstShareLink = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND shareType == 3", metadata.account, metadata.serverUrl, metadata.fileName).first
             if let firstShareLink = firstShareLink {
@@ -165,7 +167,7 @@ extension NCManageDatabase {
                 return(firstShareLink: firstShareLink, share: Array(results.map { tableShare.init(value: $0) }))
             }
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return (nil, nil)
@@ -175,10 +177,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableShare.self).filter("account = %@ AND idShare = %d", account, idShare).first else { return nil }
             return tableShare.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil
@@ -188,11 +191,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
             let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).sorted(by: sortProperties)
             return Array(results.map { tableShare.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -202,11 +206,12 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
             let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).sorted(by: sortProperties)
             return Array(results.map { tableShare.init(value: $0) })
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return []
@@ -229,7 +234,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-
             try realm.write {
                 let result = realm.objects(tableShare.self).filter("account == %@", account)
                 realm.delete(result)

+ 2 - 1
iOSClient/Data/NCManageDatabase+Video.swift

@@ -140,10 +140,11 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first else { return nil }
             return tableVideo.init(value: result)
         } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
         }
 
         return nil

+ 13 - 145
iOSClient/Data/NCManageDatabase.swift

@@ -264,6 +264,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).first else { return NSUUID().uuidString }
             return result.chunkFolder
         } catch let error as NSError {
@@ -279,6 +280,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).sorted(byKeyPath: "fileName", ascending: true)
             for result in results {
                 filesNames.append(result.fileName)
@@ -323,6 +325,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableChunk.self).filter("account == %@ AND fileName == %@", account, fileName).first else { return nil }
             return tableChunk.init(value: result)
         } catch let error as NSError {
@@ -419,6 +422,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
             if results.isEmpty {
                 return nil
@@ -436,6 +440,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableDirectEditingCreators.self).filter(predicate)
             if results.isEmpty {
                 return nil
@@ -453,6 +458,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
             if results.isEmpty {
                 return nil
@@ -508,6 +514,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableExternalSites.self).filter("account == %@", account).sorted(byKeyPath: "idExternalSite", ascending: true)
             if results.isEmpty {
                 return nil
@@ -550,6 +557,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let result = realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first
             return result?.location
         } catch let error as NSError {
@@ -559,151 +567,6 @@ class NCManageDatabase: NSObject {
         return nil
     }
 
-    // MARK: -
-    // MARK: Table LocalFile
-
-    func addLocalFile(metadata: tableMetadata) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let addObject = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) ?? tableLocalFile()
-                addObject.account = metadata.account
-                addObject.etag = metadata.etag
-                addObject.exifDate = NSDate()
-                addObject.exifLatitude = "-1"
-                addObject.exifLongitude = "-1"
-                addObject.ocId = metadata.ocId
-                addObject.fileName = metadata.fileName
-                realm.add(addObject, update: .all)
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
-    func addLocalFile(account: String, etag: String, ocId: String, fileName: String) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let addObject = tableLocalFile()
-                addObject.account = account
-                addObject.etag = etag
-                addObject.exifDate = NSDate()
-                addObject.exifLatitude = "-1"
-                addObject.exifLongitude = "-1"
-                addObject.ocId = ocId
-                addObject.fileName = fileName
-                realm.add(addObject, update: .all)
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
-    func deleteLocalFile(predicate: NSPredicate) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let results = realm.objects(tableLocalFile.self).filter(predicate)
-                realm.delete(results)
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
-    func setLocalFile(ocId: String, fileName: String?, etag: String?) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
-                if let fileName = fileName {
-                    result?.fileName = fileName
-                }
-                if let etag = etag {
-                    result?.etag = etag
-                }
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
-    @objc func setLocalFile(ocId: String, exifDate: NSDate?, exifLatitude: String, exifLongitude: String, exifLensModel: String?) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first {
-                    result.exifDate = exifDate
-                    result.exifLatitude = exifLatitude
-                    result.exifLongitude = exifLongitude
-                    if exifLensModel?.count ?? 0 > 0 {
-                        result.exifLensModel = exifLensModel
-                    }
-                }
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
-    func getTableLocalFile(account: String) -> [tableLocalFile] {
-
-        do {
-            let realm = try Realm()
-            let results = realm.objects(tableLocalFile.self).filter("account == %@", account)
-            return Array(results.map { tableLocalFile.init(value: $0) })
-        } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-
-        return []
-    }
-
-    func getTableLocalFile(predicate: NSPredicate) -> tableLocalFile? {
-
-        do {
-            let realm = try Realm()
-            guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else { return nil }
-            return tableLocalFile.init(value: result)
-        } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-
-        return nil
-    }
-
-    func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] {
-
-        do {
-            let realm = try Realm()
-            let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-            return Array(results.map { tableLocalFile.init(value: $0) })
-        } catch let error as NSError {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-
-        return []
-    }
-
-    func setLocalFile(ocId: String, offline: Bool) {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
-                result?.offline = offline
-            }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-    }
-
     // MARK: -
     // MARK: Table Photo Library
 
@@ -752,6 +615,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tablePhotoLibrary.self).filter(predicate)
             let idsAsset = results.map { $0.idAsset }
             return Array(idsAsset)
@@ -798,6 +662,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableTag.self).filter(predicate)
             return Array(results.map { tableTag.init(value: $0) })
         } catch let error as NSError {
@@ -811,6 +676,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableTag.self).filter(predicate).first else { return nil }
             return tableTag.init(value: result)
         } catch let error as NSError {
@@ -932,6 +798,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             let results = realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: sort, ascending: ascending)
             return Array(results.map { tableTrash.init(value: $0) })
         } catch let error as NSError {
@@ -945,6 +812,7 @@ class NCManageDatabase: NSObject {
 
         do {
             let realm = try Realm()
+            realm.refresh()
             guard let result = realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first else { return nil }
             return tableTrash.init(value: result)
         } catch let error as NSError {

+ 27 - 23
iOSClient/Favorites/NCFavorite.swift

@@ -49,29 +49,33 @@ class NCFavorite: NCCollectionViewCommon {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
-        super.reloadDataSource()
+    override func queryDB(isForced: Bool) {
 
-        DispatchQueue.global().async {
-            var metadatas: [tableMetadata] = []
+        var metadatas: [tableMetadata] = []
 
-            if self.serverUrl.isEmpty {
-                metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND favorite == true", self.appDelegate.account))
-            } else {
-                metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
-            }
+        if self.serverUrl.isEmpty {
+            metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND favorite == true", self.appDelegate.account))
+        } else {
+            metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
+        }
 
-            self.dataSource = NCDataSource(metadatas: metadatas,
-                                           account: self.appDelegate.account,
-                                           sort: self.layoutForView?.sort,
-                                           ascending: self.layoutForView?.ascending,
-                                           directoryOnTop: self.layoutForView?.directoryOnTop,
-                                           favoriteOnTop: true,
-                                           filterLivePhoto: true,
-                                           groupByField: self.groupByField,
-                                           providers: self.providers,
-                                           searchResults: self.searchResults)
+        self.dataSource = NCDataSource(metadatas: metadatas,
+                                       account: self.appDelegate.account,
+                                       sort: self.layoutForView?.sort,
+                                       ascending: self.layoutForView?.ascending,
+                                       directoryOnTop: self.layoutForView?.directoryOnTop,
+                                       favoriteOnTop: true,
+                                       filterLivePhoto: true,
+                                       groupByField: self.groupByField,
+                                       providers: self.providers,
+                                       searchResults: self.searchResults)
+    }
+
+    override func reloadDataSource(isForced: Bool = true) {
+        super.reloadDataSource()
 
+        DispatchQueue.global().async {
+            self.queryDB(isForced: isForced)
             DispatchQueue.main.async {
                 self.refreshControl.endRefreshing()
                 self.collectionView.reloadData()
@@ -79,8 +83,8 @@ class NCFavorite: NCCollectionViewCommon {
         }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
 
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()
@@ -101,7 +105,7 @@ class NCFavorite: NCCollectionViewCommon {
 
         } else {
 
-            networkReadFolder(forced: forced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
+            networkReadFolder(isForced: isForced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
                 if error == .success, let metadatas = metadatas {
                     for metadata in metadatas where (!metadata.directory && NCManageDatabase.shared.isDownloadMetadata(metadata, download: false)) {
                         NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile)
@@ -112,7 +116,7 @@ class NCFavorite: NCCollectionViewCommon {
                     self.refreshControl.endRefreshing()
                     self.isReloadDataSourceNetworkInProgress = false
                     self.richWorkspaceText = tableDirectory?.richWorkspace
-                    if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || forced {
+                    if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || isForced {
                         self.reloadDataSource()
                     } else {
                         self.collectionView?.reloadData()

+ 35 - 31
iOSClient/Files/NCFiles.swift

@@ -74,7 +74,7 @@ class NCFiles: NCCollectionViewCommon {
         }
         super.initialize()
 
-        reloadDataSource(forced: false)
+        reloadDataSource(isForced: false)
         reloadDataSourceNetwork()
     }
 
@@ -83,38 +83,42 @@ class NCFiles: NCCollectionViewCommon {
     // forced: do no make the etag of directory test (default)
     //
 
-    override func reloadDataSource(forced: Bool = true) {
+    override func queryDB(isForced: Bool) {
+
+        let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
+        let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
+        let metadataTransfer = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "status != %i AND serverUrl == %@", NCGlobal.shared.metadataStatusNormal, self.serverUrl))
+        if self.metadataFolder == nil {
+            self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, serverUrl: self.serverUrl)
+        }
+
+        if !isForced, let directory, directory.etag == self.dataSource.directory?.etag, metadataTransfer == nil, self.fileNameBlink == nil, self.fileNameOpen == nil {
+            return
+        }
+
+        self.richWorkspaceText = directory?.richWorkspace
+        self.dataSource = NCDataSource(
+            metadatas: metadatas,
+            account: self.appDelegate.account,
+            directory: directory,
+            sort: self.layoutForView?.sort,
+            ascending: self.layoutForView?.ascending,
+            directoryOnTop: self.layoutForView?.directoryOnTop,
+            favoriteOnTop: true,
+            filterLivePhoto: true,
+            groupByField: self.groupByField,
+            providers: self.providers,
+            searchResults: self.searchResults)
+    }
+
+    override func reloadDataSource(isForced: Bool = true) {
         super.reloadDataSource()
 
         DispatchQueue.main.async { self.refreshControl.endRefreshing() }
         DispatchQueue.global().async {
             guard !self.isSearchingMode, !self.appDelegate.account.isEmpty, !self.appDelegate.urlBase.isEmpty, !self.serverUrl.isEmpty else { return }
 
-            let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
-            if self.metadataFolder == nil {
-                self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, serverUrl: self.serverUrl)
-            }
-            let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
-            let metadataTransfer = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "status != %i AND serverUrl == %@", NCGlobal.shared.metadataStatusNormal, self.serverUrl))
-            self.richWorkspaceText = directory?.richWorkspace
-
-            // FORCED false: test the directory.etag
-            if !forced, let directory = directory, directory.etag == self.dataSource.directory?.etag, metadataTransfer == nil, self.fileNameBlink == nil, self.fileNameOpen == nil {
-                return
-            }
-
-            self.dataSource = NCDataSource(
-                metadatas: metadatas,
-                account: self.appDelegate.account,
-                directory: directory,
-                sort: self.layoutForView?.sort,
-                ascending: self.layoutForView?.ascending,
-                directoryOnTop: self.layoutForView?.directoryOnTop,
-                favoriteOnTop: true,
-                filterLivePhoto: true,
-                groupByField: self.groupByField,
-                providers: self.providers,
-                searchResults: self.searchResults)
+            self.queryDB(isForced: isForced)
 
             DispatchQueue.main.async {
                 self.collectionView.reloadData()
@@ -128,8 +132,8 @@ class NCFiles: NCCollectionViewCommon {
         }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
         guard !isSearchingMode else {
             networkSearch()
             return
@@ -137,7 +141,7 @@ class NCFiles: NCCollectionViewCommon {
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()
 
-        networkReadFolder(forced: forced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
+        networkReadFolder(isForced: isForced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
             if error == .success {
                 for metadata in metadatas ?? [] where !metadata.directory && NCManageDatabase.shared.isDownloadMetadata(metadata, download: false) {
                     NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile)
@@ -147,7 +151,7 @@ class NCFiles: NCCollectionViewCommon {
             self.isReloadDataSourceNetworkInProgress = false
             self.richWorkspaceText = tableDirectory?.richWorkspace
 
-            if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || forced {
+            if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || isForced {
                 self.reloadDataSource()
             } else if self.dataSource.getMetadataSourceForAllSections().isEmpty {
                 DispatchQueue.main.async {

+ 9 - 6
iOSClient/Groupfolders/NCGroupfolders.swift

@@ -49,8 +49,7 @@ class NCGroupfolders: NCCollectionViewCommon {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
-        super.reloadDataSource()
+    override func queryDB(isForced: Bool) {
 
         var metadatas: [tableMetadata] = []
 
@@ -71,7 +70,12 @@ class NCGroupfolders: NCCollectionViewCommon {
             groupByField: self.groupByField,
             providers: self.providers,
             searchResults: self.searchResults)
+    }
 
+    override func reloadDataSource(isForced: Bool = true) {
+        super.reloadDataSource()
+
+        self.queryDB(isForced: isForced)
         DispatchQueue.main.async {
             self.isReloadDataSourceNetworkInProgress = false
             self.refreshControl.endRefreshing()
@@ -79,8 +83,8 @@ class NCGroupfolders: NCCollectionViewCommon {
         }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
 
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()
@@ -119,8 +123,7 @@ class NCGroupfolders: NCCollectionViewCommon {
             }
         } else {
 
-            networkReadFolder(forced: forced) { _, _, _, _, _ in
-
+            networkReadFolder(isForced: isForced) { _, _, _, _, _ in
                 self.reloadDataSource()
             }
         }

+ 60 - 38
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -25,6 +25,7 @@ import UIKit
 import Realm
 import NextcloudKit
 import EasyTipView
+import JGProgressHUD
 
 class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, NCSectionFooterDelegate, UIAdaptivePresentationControllerDelegate, NCEmptyDataSetDelegate, UIContextMenuInteractionDelegate, NCAccountRequestDelegate, NCSelectableNavigationView {
 
@@ -40,6 +41,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     internal var isDirectoryE2EE = false
     internal var isEditMode = false
     internal var selectOcId: [String] = []
+    internal var selectIndexPath: [IndexPath] = []
     internal var metadataFolder: tableMetadata?
     internal var dataSource = NCDataSource()
     internal var richWorkspaceText: String?
@@ -127,7 +129,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         collectionView.refreshControl = refreshControl
         refreshControl.action(for: .valueChanged) { _ in
             self.dataSource.clearDirectory()
-            self.reloadDataSourceNetwork(forced: true)
+            self.reloadDataSourceNetwork(isForced: true)
         }
 
         // Empty
@@ -210,7 +212,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         navigationController?.setNavigationBarHidden(false, animated: true)
         setNavigationItem()
 
-        reloadDataSource(forced: false)
+        reloadDataSource(isForced: false)
         if !isSearchingMode {
             reloadDataSourceNetwork()
         }
@@ -295,6 +297,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         if isEditMode {
             isEditMode = !isEditMode
             selectOcId.removeAll()
+            selectIndexPath.removeAll()
         }
 
         if self.view?.window != nil {
@@ -339,7 +342,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     @objc func reloadDataSourceNetworkForced(_ notification: NSNotification) {
 
         if !isSearchingMode {
-            reloadDataSourceNetwork(forced: true)
+            reloadDataSourceNetwork(isForced: true)
         }
     }
 
@@ -354,37 +357,49 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     @objc func deleteFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,
-              let account = userInfo["account"] as? String,
-              let error = userInfo["error"] as? NKError
-        else { return }
+              let error = userInfo["error"] as? NKError else { return }
+        let onlyLocalCache: Bool = userInfo["onlyLocalCache"] as? Bool ?? false
 
-        if error == .success, account == appDelegate.account {
-            reloadDataSource()
+        self.queryDB(isForced: true)
+
+        if error == .success, let indexPath = userInfo["indexPath"] as? [IndexPath], !indexPath.isEmpty, !onlyLocalCache {
+            collectionView?.performBatchUpdates({
+                collectionView?.deleteItems(at: indexPath)
+            }, completion: { _ in
+                self.collectionView?.reloadData()
+            })
+        } else {
+            if error != .success {
+                NCContentPresenter.shared.showError(error: error)
+            }
+            self.collectionView?.reloadData()
+        }
+
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
         }
     }
 
     @objc func moveFile(_ notification: NSNotification) {
-
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let serverUrlFrom = userInfo["serverUrlFrom"] as? String,
-              serverUrlFrom == self.serverUrl
-        else { return }
-
-        reloadDataSource()
+        deleteFile(notification)
     }
 
     @objc func copyFile(_ notification: NSNotification) {
 
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let serverUrlTo = userInfo["serverUrlTo"] as? String,
-              serverUrlTo == self.serverUrl
-        else { return }
+        guard let userInfo = notification.userInfo as NSDictionary? else { return }
 
-        reloadDataSource()
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
+        }
     }
 
     @objc func renameFile(_ notification: NSNotification) {
 
+        guard let userInfo = notification.userInfo as NSDictionary?,
+              let account = userInfo["account"] as? String,
+              account == appDelegate.account
+        else { return }
+        
         if isSearchingMode {
             reloadDataSourceNetwork()
         } else {
@@ -405,7 +420,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         else { return }
 
         if e2ee {
-            reloadDataSourceNetwork(forced: true)
+            reloadDataSourceNetwork(isForced: true)
         } else if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId)  {
             reloadDataSource()
             if withPush {
@@ -670,6 +685,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         } else {
             navigationController?.navigationBar.topItem?.title = titlePreviusFolder
         }
+        navigationItem.title = titleCurrentFolder
     }
 
     func getNavigationTitle() -> String {
@@ -811,11 +827,11 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         sortMenu.toggleMenu(viewController: self, account: appDelegate.account, key: layoutKey, sortButton: sender as? UIButton, serverUrl: serverUrl)
     }
 
-    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any) {
-        tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: image, sender: sender)
+    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {
+        tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: image, indexPath: indexPath, sender: sender)
     }
 
-    func tapShareListItem(with objectId: String, sender: Any) {
+    func tapShareListItem(with objectId: String, indexPath: IndexPath, sender: Any) {
 
         if isEditMode { return }
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(objectId) else { return }
@@ -823,14 +839,14 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         NCActionCenter.shared.openShare(viewController: self, metadata: metadata, page: .sharing)
     }
 
-    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any) {
+    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {
 
         if isEditMode { return }
 
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(objectId) else { return }
 
         if namedButtonMore == NCGlobal.shared.buttonMoreMore || namedButtonMore == NCGlobal.shared.buttonMoreLock {
-            toggleMenu(metadata: metadata, imageIcon: image)
+            toggleMenu(metadata: metadata, indexPath: indexPath, imageIcon: image)
         } else if namedButtonMore == NCGlobal.shared.buttonMoreStop {
             NCNetworking.shared.cancelTransferMetadata(metadata) { }
         }
@@ -861,16 +877,16 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         }
     }
 
-    func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
     }
 
-    func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
     }
 
-    func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    func longPressMoreListItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
     }
 
-    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
     }
 
     @objc func longPressCollecationView(_ gestureRecognizer: UILongPressGestureRecognizer) {
@@ -924,7 +940,9 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
 
     // MARK: - DataSource + NC Endpoint
 
-    @objc func reloadDataSource(forced: Bool = true) {
+    func queryDB(isForced: Bool) { }
+
+    @objc func reloadDataSource(isForced: Bool = true) {
         guard !appDelegate.account.isEmpty else { return }
 
         // E2EE
@@ -944,7 +962,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         }
     }
 
-    @objc func reloadDataSourceNetwork(forced: Bool = false) { }
+    @objc func reloadDataSourceNetwork(isForced: Bool = false) { }
 
     @objc func networkSearch() {
         guard !appDelegate.account.isEmpty, let literalSearch = literalSearch, !literalSearch.isEmpty
@@ -1025,7 +1043,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         }
     }
 
-    @objc func networkReadFolder(forced: Bool, completion: @escaping(_ tableDirectory: tableDirectory?, _ metadatas: [tableMetadata]?, _ metadatasUpdate: [tableMetadata]?, _ metadatasDelete: [tableMetadata]?, _ error: NKError) -> Void) {
+    @objc func networkReadFolder(isForced: Bool, completion: @escaping(_ tableDirectory: tableDirectory?, _ metadatas: [tableMetadata]?, _ metadatasUpdate: [tableMetadata]?, _ metadatasDelete: [tableMetadata]?, _ error: NKError) -> Void) {
 
         var tableDirectory: tableDirectory?
 
@@ -1038,7 +1056,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             if let metadataFolder = metadataFolder {
                 tableDirectory = NCManageDatabase.shared.setDirectory(serverUrl: self.serverUrl, richWorkspace: metadataFolder.richWorkspace, account: account)
             }
-            if forced || tableDirectory?.etag != metadataFolder?.etag || metadataFolder?.e2eEncrypted ?? false {
+            if isForced || tableDirectory?.etag != metadataFolder?.etag || metadataFolder?.e2eEncrypted ?? false {
                 NCNetworking.shared.readFolder(serverUrl: self.serverUrl, account: self.appDelegate.account) { account, metadataFolder, metadatas, metadatasUpdate, _, metadatasDelete, error in
                     guard error == .success else {
                         completion(tableDirectory, nil, nil, nil, error)
@@ -1250,8 +1268,10 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
         if isEditMode {
             if let index = selectOcId.firstIndex(of: metadata.ocId) {
                 selectOcId.remove(at: index)
+                selectIndexPath.removeAll(where: { $0 == indexPath })
             } else {
                 selectOcId.append(metadata.ocId)
+                selectIndexPath.append(indexPath)
             }
             collectionView.reloadItems(at: [indexPath])
             return
@@ -1321,7 +1341,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
 
         }, actionProvider: { _ in
 
-            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, image: image)
+            return NCContextMenu().viewMenu(ocId: metadata.ocId, indexPath: indexPath, viewController: self, image: image)
         })
     }
 
@@ -1421,7 +1441,6 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
 
         guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return cell }
 
-        let tableDirectory = dataSource.metadatasForSection[indexPath.section].directories?.filter({ $0.ocId == metadata.ocId }).first
         var isShare = false
         var isMounted = false
         var a11yValues: [String] = []
@@ -1440,6 +1459,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         cell.filePreviewImageView?.image = nil
         cell.filePreviewImageView?.backgroundColor = nil
         cell.fileObjectId = metadata.ocId
+        cell.indexPath = indexPath
         cell.fileUser = metadata.ownerId
         cell.fileProgressView?.isHidden = true
         cell.fileProgressView?.progress = 0.0
@@ -1472,6 +1492,8 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
 
         if metadata.directory {
 
+            let tableDirectory = NCManageDatabase.shared.getTableDirectory(ocId: metadata.ocId)
+
             if metadata.e2eEncrypted {
                 cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderEncrypted
             } else if isShare {
@@ -1493,7 +1515,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
             }
 
             // Local image: offline
-            if let tableDirectory = tableDirectory, tableDirectory.offline {
+            if let tableDirectory, tableDirectory.offline {
                 cell.fileLocalImage?.image = NCBrandColor.cacheImages.offlineFlag
             }
 
@@ -1503,7 +1525,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         } else {
 
             // image local
-            if dataSource.metadatasForSection[indexPath.section].metadataOffLine.contains(metadata.ocId) {
+            if NCManageDatabase.shared.getTableLocalFile(ocId: metadata.ocId) != nil {
                 a11yValues.append(NSLocalizedString("_offline_", comment: ""))
                 cell.fileLocalImage?.image = NCBrandColor.cacheImages.offlineFlag
             } else if CCUtility.fileProviderStorageExists(metadata) {

+ 11 - 10
iOSClient/Main/Collection Common/NCGridCell.swift

@@ -36,7 +36,8 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
     @IBOutlet weak var imageVisualEffect: UIVisualEffectView!
     @IBOutlet weak var progressView: UIProgressView!
 
-    internal var objectId = ""
+    var objectId = ""
+    var indexPath = IndexPath()
     private var user = ""
 
     weak var delegate: NCGridCellDelegate?
@@ -134,15 +135,15 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
     }
 
     @IBAction func touchUpInsideMore(_ sender: Any) {
-        delegate?.tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, sender: sender)
+        delegate?.tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender)
     }
 
     @objc func longPressInsideMore(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     @objc func longPress(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressGridItem(with: objectId, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressGridItem(with: objectId, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     fileprivate func setA11yActions() {
@@ -218,16 +219,16 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
 }
 
 protocol NCGridCellDelegate: AnyObject {
-    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any)
-    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer)
-    func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer)
+    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any)
+    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
+    func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
 }
 
 // optional func
 extension NCGridCellDelegate {
-    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any) {}
-    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {}
-    func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {}
+    func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {}
+    func longPressMoreGridItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {}
+    func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {}
 }
 
 // MARK: - Grid Layout

+ 13 - 12
iOSClient/Main/Collection Common/NCListCell.swift

@@ -48,6 +48,7 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
 
     private var objectId = ""
     private var user = ""
+    var indexPath = IndexPath()
 
     weak var delegate: NCListCellDelegate?
     var namedButtonMore = ""
@@ -158,19 +159,19 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
     }
     
     @IBAction func touchUpInsideShare(_ sender: Any) {
-        delegate?.tapShareListItem(with: objectId, sender: sender)
+        delegate?.tapShareListItem(with: objectId, indexPath: indexPath, sender: sender)
     }
 
     @IBAction func touchUpInsideMore(_ sender: Any) {
-        delegate?.tapMoreListItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, sender: sender)
+        delegate?.tapMoreListItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender)
     }
 
     @objc func longPressInsideMore(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressMoreListItem(with: objectId, namedButtonMore: namedButtonMore, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressMoreListItem(with: objectId, namedButtonMore: namedButtonMore, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     @objc func longPress(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressListItem(with: objectId, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressListItem(with: objectId, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     fileprivate func setA11yActions() {
@@ -299,18 +300,18 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
 }
 
 protocol NCListCellDelegate: AnyObject {
-    func tapShareListItem(with objectId: String, sender: Any)
-    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any)
-    func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer)
-    func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer)
+    func tapShareListItem(with objectId: String, indexPath: IndexPath, sender: Any)
+    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any)
+    func longPressMoreListItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
+    func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
 }
 
 // optional func
 extension NCListCellDelegate {
-    func tapShareListItem(with objectId: String, sender: Any) {}
-    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any) {}
-    func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {}
-    func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {}
+    func tapShareListItem(with objectId: String, indexPath: IndexPath, sender: Any) {}
+    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {}
+    func longPressMoreListItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {}
+    func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {}
 }
 
 // MARK: - List Layout

+ 6 - 4
iOSClient/Main/Collection Common/NCSelectableNavigationView.swift

@@ -40,13 +40,14 @@ protocol NCSelectableNavigationView: AnyObject {
     var collectionView: UICollectionView! { get set }
     var isEditMode: Bool { get set }
     var selectOcId: [String] { get set }
+    var selectIndexPath: [IndexPath] { get set }
     var titleCurrentFolder: String { get }
     var navigationItem: UINavigationItem { get }
     var navigationController: UINavigationController? { get }
     var layoutKey: String { get }
     var selectActions: [NCMenuAction] { get }
 
-    func reloadDataSource(forced: Bool)
+    func reloadDataSource(isForced: Bool)
     func setNavigationItem()
 
     func tapSelectMenu()
@@ -77,6 +78,7 @@ extension NCSelectableNavigationView {
     func tapSelect() {
         isEditMode = !isEditMode
         selectOcId.removeAll()
+        selectIndexPath.removeAll()
         self.setNavigationItem()
         self.collectionView.reloadData()
     }
@@ -152,13 +154,13 @@ extension NCSelectableNavigationView where Self: UIViewController {
             actions.append(.saveMediaAction(selectedMediaMetadatas: selectedMediaMetadatas, completion: tapSelect))
         }
         actions.append(.setAvailableOfflineAction(selectedMetadatas: selectedMetadatas, isAnyOffline: isAnyOffline, viewController: self, completion: {
-            self.reloadDataSource(forced: true)
+            self.reloadDataSource(isForced: true)
             self.tapSelect()
         }))
 
-        actions.append(.moveOrCopyAction(selectedMetadatas: selectedMetadatas, completion: tapSelect))
+        actions.append(.moveOrCopyAction(selectedMetadatas: selectedMetadatas, indexPath: selectIndexPath, completion: tapSelect))
         actions.append(.copyAction(selectOcId: selectOcId, hudView: self.view, completion: tapSelect))
-        actions.append(.deleteAction(selectedMetadatas: selectedMetadatas, viewController: self, completion: tapSelect))
+        actions.append(.deleteAction(selectedMetadatas: selectedMetadatas, indexPath: selectIndexPath, viewController: self, completion: tapSelect))
         return actions
     }
 }

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift

@@ -211,7 +211,7 @@ import XLForm
 
     // MARK: - Action
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         guard let serverUrl = serverUrl else {
             return

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift

@@ -190,7 +190,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
 
     // MARK: - Action
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         if serverUrl != nil {
 

+ 37 - 8
iOSClient/Main/NCActionCenter.swift

@@ -652,21 +652,49 @@ class NCActionCenter: NSObject, UIDocumentInteractionControllerDelegate, NCSelec
 
     // MARK: - NCSelect + Delegate
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
-        if serverUrl != nil && !items.isEmpty {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
+        if let serverUrl, !items.isEmpty {
+            let hud = JGProgressHUD()
+            hud.textLabel.text = copy ? NSLocalizedString("_copying_progess_", comment: "") : NSLocalizedString("_moving_progess_", comment: "")
+            if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
+               let view = appDelegate.window?.rootViewController?.view {
+                hud.show(in: view)
+            }
             if copy {
-                for case let metadata as tableMetadata in items {
-                    NCOperationQueue.shared.copyMove(metadata: metadata, serverUrl: serverUrl!, overwrite: overwrite, move: false)
+                Task {
+                    var error = NKError()
+                    var ocId: [String] = []
+                    for case let metadata as tableMetadata in items where error == .success {
+                        error = await NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite)
+                        if error == .success {
+                            ocId.append(metadata.ocId)
+                        }
+                    }
+                    if error != .success {
+                        NCContentPresenter.shared.showError(error: error)
+                    }
+                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCopyFile, userInfo: ["ocId": ocId, "indexPath": indexPath, "hud": hud])
                 }
-            } else if move {
-                for case let metadata as tableMetadata in items {
-                    NCOperationQueue.shared.copyMove(metadata: metadata, serverUrl: serverUrl!, overwrite: overwrite, move: true)
+            } else {
+                Task {
+                    var error = NKError()
+                    var ocId: [String] = []
+                    for case let metadata as tableMetadata in items where error == .success {
+                        error = await NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite)
+                        if error == .success {
+                            ocId.append(metadata.ocId)
+                        }
+                    }
+                    if error != .success {
+                        NCContentPresenter.shared.showError(error: error)
+                    }
+                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMoveFile, userInfo: ["ocId": ocId, "indexPath": indexPath, "hud": hud])
                 }
             }
         }
     }
 
-    func openSelectView(items: [tableMetadata]) {
+    func openSelectView(items: [tableMetadata], indexPath: [IndexPath]) {
         guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
 
         let navigationController = UIStoryboard(name: "NCSelect", bundle: nil).instantiateInitialViewController() as? UINavigationController
@@ -701,6 +729,7 @@ class NCActionCenter: NSObject, UIDocumentInteractionControllerDelegate, NCSelec
             vc.typeOfCommandView = .copyMove
             vc.items = copyItems
             vc.serverUrl = serverUrl
+            vc.selectIndexPath = indexPath
 
             vc.navigationItem.backButtonTitle = vc.titleCurrentFolder
             listViewController.insert(vc, at: 0)

+ 1 - 0
iOSClient/Main/NCCellProtocol.swift

@@ -39,6 +39,7 @@ protocol NCCellProtocol {
     var fileSharedImage: UIImageView? { get set }
     var fileMoreImage: UIImageView? { get set }
     var cellSeparatorView: UIView? { get set }
+    var indexPath: IndexPath { get set }
 
     func titleInfoTrailingDefault()
     func titleInfoTrailingFull()

+ 2 - 1
iOSClient/Media/Cell/NCGridMediaCell.swift

@@ -32,7 +32,8 @@ class NCGridMediaCell: UICollectionViewCell, NCCellProtocol {
 
     private var objectId: String = ""
     private var user: String = ""
-
+    var indexPath = IndexPath()
+    
     var date: Date?
 
     var filePreviewImageView: UIImageView? {

+ 79 - 58
iOSClient/Media/NCMedia.swift

@@ -23,6 +23,7 @@
 
 import UIKit
 import NextcloudKit
+import JGProgressHUD
 
 class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
@@ -43,6 +44,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
     internal var isEditMode = false
     internal var selectOcId: [String] = []
+    internal var selectIndexPath: [IndexPath] = []
 
     internal var filterClassTypeImage = false
     internal var filterClassTypeVideo = false
@@ -120,6 +122,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
         NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(copyFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterCopyFile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterUploadedFile), object: nil)
 
@@ -140,6 +143,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMoveFile), object: nil)
+        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterCopyFile), object: nil)
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterUploadedFile), object: nil)
     }
@@ -170,39 +174,41 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     @objc func deleteFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,
-              let account = userInfo["account"] as? String,
-              let ocIds = userInfo["ocId"] as? [String],
-              let error = userInfo["error"] as? NKError
-        else { return }
+              let error = userInfo["error"] as? NKError else { return }
+        let onlyLocalCache: Bool = userInfo["onlyLocalCache"] as? Bool ?? false
 
-        if error == .success, account == appDelegate.account {
-            var items: [IndexPath] = []
-            var index: Int = 0
-            for metadata in metadatas {
-                if ocIds.contains(metadata.ocId) {
-                    self.metadatas.remove(at: index)
-                    items.append(IndexPath(row: index, section: 0))
-                }
-                if ocIds.count == items.count { break }
-                index += 1
-            }
-            if ocIds.count == items.count {
-                self.collectionView?.deleteItems(at: items)
-            } else {
-                self.reloadDataSourceWithCompletion { _ in }
+        self.queryDB(isForced: true)
+
+        if error == .success, let indexPath = userInfo["indexPath"] as? [IndexPath], !indexPath.isEmpty, !onlyLocalCache {
+            collectionView?.performBatchUpdates({
+                collectionView?.deleteItems(at: indexPath)
+            }, completion: { _ in
+                self.collectionView?.reloadData()
+            })
+        } else {
+            if error != .success {
+                NCContentPresenter.shared.showError(error: error)
             }
+            self.collectionView?.reloadData()
+        }
+
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
         }
-        self.updateMediaControlVisibility()
     }
 
     @objc func moveFile(_ notification: NSNotification) {
 
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let account = userInfo["account"] as? String,
-              account == appDelegate.account
-        else { return }
+        guard let userInfo = notification.userInfo as NSDictionary? else { return }
 
-        self.reloadDataSourceWithCompletion { _ in }
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
+        }
+    }
+
+    @objc func copyFile(_ notification: NSNotification) {
+
+        moveFile(notification)
     }
 
     @objc func renameFile(_ notification: NSNotification) {
@@ -280,7 +286,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
     // MARK: Select Path
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         guard let serverUrl = serverUrl else { return }
         let path = CCUtility.returnPathfromServerUrl(serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account) ?? ""
@@ -314,8 +320,10 @@ extension NCMedia: UICollectionViewDelegate {
         if isEditMode {
             if let index = selectOcId.firstIndex(of: metadata.ocId) {
                 selectOcId.remove(at: index)
+                selectIndexPath.removeAll(where: { $0 == indexPath })
             } else {
                 selectOcId.append(metadata.ocId)
+                selectIndexPath.append(indexPath)
             }
             if indexPath.section <  collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section) {
                 collectionView.reloadItems(at: [indexPath])
@@ -338,7 +346,7 @@ extension NCMedia: UICollectionViewDelegate {
         return UIContextMenuConfiguration(identifier: identifier, previewProvider: {
             return NCViewerProviderContextMenu(metadata: metadata, image: image)
         }, actionProvider: { _ in
-            return NCContextMenu().viewMenu(ocId: metadata.ocId, viewController: self, image: image)
+            return NCContextMenu().viewMenu(ocId: metadata.ocId, indexPath: indexPath, viewController: self, image: image)
         })
     }
 
@@ -400,6 +408,7 @@ extension NCMedia: UICollectionViewDataSource {
 
             cell.date = metadata.date as Date
             cell.fileObjectId = metadata.ocId
+            cell.indexPath = indexPath
             cell.fileUser = metadata.ownerId
 
             if metadata.isAudioOrVideo {
@@ -443,14 +452,7 @@ extension NCMedia {
 
     // MARK: - Datasource
 
-    @objc func reloadDataSourceWithCompletion(_ completion: @escaping (_ metadatas: [tableMetadata]) -> Void) {
-        guard !appDelegate.account.isEmpty else { return }
-
-        if account != appDelegate.account {
-            self.metadatas = []
-            account = appDelegate.account
-            collectionView?.reloadData()
-        }
+    func queryDB(isForced: Bool) {
 
         livePhoto = CCUtility.getLivePhoto()
 
@@ -470,18 +472,32 @@ extension NCMedia {
         }
 
         guard let predicate = predicate else { return }
+
+        self.metadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate, livePhoto: self.livePhoto)
+
+        switch CCUtility.getMediaSortDate() {
+        case "date":
+            self.metadatas = self.metadatas.sorted(by: {($0.date as Date) > ($1.date as Date)} )
+        case "creationDate":
+            self.metadatas = self.metadatas.sorted(by: {($0.creationDate as Date) > ($1.creationDate as Date)} )
+        case "uploadDate":
+            self.metadatas = self.metadatas.sorted(by: {($0.uploadDate as Date) > ($1.uploadDate as Date)} )
+        default:
+            break
+        }
+    }
+
+    @objc func reloadDataSourceWithCompletion(_ completion: @escaping (_ metadatas: [tableMetadata]) -> Void) {
+        guard !appDelegate.account.isEmpty else { return }
+
+        if account != appDelegate.account {
+            self.metadatas = []
+            account = appDelegate.account
+            DispatchQueue.main.async { self.collectionView?.reloadData() }
+        }
+
         DispatchQueue.global().async {
-            self.metadatas = NCManageDatabase.shared.getMetadatasMedia(predicate: predicate, livePhoto: self.livePhoto)
-            switch CCUtility.getMediaSortDate() {
-            case "date":
-                self.metadatas = self.metadatas.sorted(by: {($0.date as Date) > ($1.date as Date)} )
-            case "creationDate":
-                self.metadatas = self.metadatas.sorted(by: {($0.creationDate as Date) > ($1.creationDate as Date)} )
-            case "uploadDate":
-                self.metadatas = self.metadatas.sorted(by: {($0.uploadDate as Date) > ($1.uploadDate as Date)} )
-            default:
-                break
-            }
+            self.queryDB(isForced: true)
             DispatchQueue.main.sync {
                 self.reloadDataThenPerform {
                     self.updateMediaControlVisibility()
@@ -513,7 +529,14 @@ extension NCMedia {
     private func searchOldMedia(value: Int = -30, limit: Int = 300) {
 
         if oldInProgress { return } else { oldInProgress = true }
-        collectionView.reloadData()
+        DispatchQueue.main.async {
+            self.collectionView.reloadData()
+            var bottom: CGFloat = 0
+            if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
+                bottom = -mainTabBar.getHight()
+            }
+            NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom - 5, style: .medium)
+        }
 
         var lessDate = Date()
         if predicateDefault != nil {
@@ -529,19 +552,15 @@ extension NCMedia {
             greaterDate = Calendar.current.date(byAdding: .day, value: value, to: lessDate)!
         }
 
-        var bottom: CGFloat = 0
-        if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
-            bottom = -mainTabBar.getHight()
-        }
-        NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom-5, style: .medium)
-
-        let options = NKRequestOptions(timeout: 300)
+        let options = NKRequestOptions(timeout: 300, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
         
         NextcloudKit.shared.searchMedia(path: mediaPath, lessDate: lessDate, greaterDate: greaterDate, elementDate: "d:getlastmodified/", limit: limit, showHiddenFiles: CCUtility.getShowHiddenFiles(), options: options) { account, files, data, error in
 
             self.oldInProgress = false
-            NCActivityIndicator.shared.stop()
-            self.collectionView.reloadData()
+            DispatchQueue.main.async {
+                NCActivityIndicator.shared.stop()
+                self.collectionView.reloadData()
+            }
 
             if error == .success && account == self.appDelegate.account {
                 if files.count > 0 {
@@ -616,12 +635,14 @@ extension NCMedia {
 
         reloadDataThenPerform {
 
-            let options = NKRequestOptions(timeout: 300)
+            let options = NKRequestOptions(timeout: 300, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
             
             NextcloudKit.shared.searchMedia(path: self.mediaPath, lessDate: lessDate, greaterDate: greaterDate, elementDate: "d:getlastmodified/", limit: limit, showHiddenFiles: CCUtility.getShowHiddenFiles(), options: options) { account, files, data, error in
 
                 self.newInProgress = false
-                self.mediaCommandView?.activityIndicator.stopAnimating()
+                DispatchQueue.main.async {
+                    self.mediaCommandView?.activityIndicator.stopAnimating()
+                }
 
                 if error == .success && account == self.appDelegate.account && files.count > 0 {
                     NCManageDatabase.shared.convertFilesToMetadatas(files, useMetadataFolder: false) { _, _, metadatas in

+ 4 - 3
iOSClient/Menu/NCCollectionViewCommon+Menu.swift

@@ -32,7 +32,7 @@ import Queuer
 
 extension NCCollectionViewCommon {
 
-    func toggleMenu(metadata: tableMetadata, imageIcon: UIImage?) {
+    func toggleMenu(metadata: tableMetadata, indexPath: IndexPath, imageIcon: UIImage?) {
 
         var actions = [NCMenuAction]()
 
@@ -317,6 +317,7 @@ extension NCCollectionViewCommon {
 
                             vcRename.metadata = metadata
                             vcRename.imagePreview = imageIcon
+                            vcRename.indexPath = indexPath
 
                             let popup = NCPopupViewController(contentController: vcRename, popupWidth: vcRename.width, popupHeight: vcRename.height)
 
@@ -331,7 +332,7 @@ extension NCCollectionViewCommon {
         // COPY - MOVE
         //
         if metadata.isCopyableMovable {
-            actions.append(.moveOrCopyAction(selectedMetadatas: [metadata], order: 130))
+            actions.append(.moveOrCopyAction(selectedMetadatas: [metadata], indexPath: [indexPath], order: 130))
         }
 
         //
@@ -386,7 +387,7 @@ extension NCCollectionViewCommon {
         // DELETE
         //
         if metadata.isDeletable {
-            actions.append(.deleteAction(selectedMetadatas: [metadata], metadataFolder: metadataFolder, viewController: self, order: 170))
+            actions.append(.deleteAction(selectedMetadatas: [metadata], indexPath: [indexPath], metadataFolder: metadataFolder, viewController: self, order: 170))
         }
 
         applicationHandle.addCollectionViewCommonMenu(metadata: metadata, imageIcon: imageIcon, actions: &actions)

+ 9 - 5
iOSClient/Menu/NCContextMenu.swift

@@ -28,7 +28,7 @@ import JGProgressHUD
 
 class NCContextMenu: NSObject {
 
-    func viewMenu(ocId: String, viewController: UIViewController, image: UIImage?) -> UIMenu {
+    func viewMenu(ocId: String, indexPath: IndexPath, viewController: UIViewController, image: UIImage?) -> UIMenu {
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return UIMenu() }
 
         var downloadRequest: DownloadRequest?
@@ -158,16 +158,21 @@ class NCContextMenu: NSObject {
             }
             let alertController = UIAlertController(title: nil, message: nil, preferredStyle: alertStyle)
             alertController.addAction(UIAlertAction(title: NSLocalizedString("_delete_file_", comment: ""), style: .destructive) { _ in
+                let hud = JGProgressHUD()
+                hud.textLabel.text = NSLocalizedString("_deletion_progess_", comment: "")
+                if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
+                   let view = appDelegate.window?.rootViewController?.view {
+                    hud.show(in: view)
+                }
                 Task {
                     var ocId: [String] = []
-                    let account: String = metadata.account
                     let error = await NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: false)
                     if error == .success {
                         ocId.append(metadata.ocId)
                     } else {
                         NCContentPresenter.shared.showError(error: error)
                     }
-                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["account": account, "ocId": ocId, "error": error])
+                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": [indexPath], "onlyLocalCache": false, "error": error, "hud": hud])
                 }
             })
             alertController.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel) { _ in })
@@ -178,14 +183,13 @@ class NCContextMenu: NSObject {
                                           image: UIImage(systemName: "trash"), attributes: .destructive) { _ in
             Task {
                 var ocId: [String] = []
-                let account: String = metadata.account
                 let error = await NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: true)
                 if error == .success {
                     ocId.append(metadata.ocId)
                 } else {
                     NCContentPresenter.shared.showError(error: error)
                 }
-                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["account": account, "ocId": ocId, "error": error])
+                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": [indexPath], "onlyLocalCache": true, "error": error])
             }
         }
 

+ 4 - 2
iOSClient/Menu/NCMedia+Menu.swift

@@ -29,6 +29,7 @@ extension NCMedia {
     func tapSelect() {
         self.isEditMode = false
         self.selectOcId.removeAll()
+        self.selectIndexPath.removeAll()
         self.reloadDataThenPerform { }
     }
 
@@ -90,6 +91,7 @@ extension NCMedia {
                         viewController.delegate = self
                         viewController.typeOfCommandView = .select
                         viewController.type = "mediaFolder"
+                        viewController.selectIndexPath = self.selectIndexPath
 
                         self.present(navigationController, animated: true, completion: nil)
                     }
@@ -207,7 +209,7 @@ extension NCMedia {
             //
             // COPY - MOVE
             //
-            actions.append(.moveOrCopyAction(selectedMetadatas: selectedMetadatas, completion: tapSelect))
+            actions.append(.moveOrCopyAction(selectedMetadatas: selectedMetadatas, indexPath: selectIndexPath, completion: tapSelect))
 
             //
             // COPY
@@ -218,7 +220,7 @@ extension NCMedia {
             // DELETE
             // can't delete from cache because is needed for NCMedia view, and if locked can't delete from server either.
             if !selectedMetadatas.contains(where: { $0.lock && $0.lockOwner != appDelegate.userId }) {
-                actions.append(.deleteAction(selectedMetadatas: selectedMetadatas, metadataFolder: nil, viewController: self, completion: tapSelect))
+                actions.append(.deleteAction(selectedMetadatas: selectedMetadatas, indexPath: selectIndexPath, metadataFolder: nil, viewController: self, completion: tapSelect))
             }
         }
     }

+ 12 - 8
iOSClient/Menu/NCMenuAction.swift

@@ -25,6 +25,7 @@
 import Foundation
 import UIKit
 import NextcloudKit
+import JGProgressHUD
 
 class NCMenuAction {
     let title: String
@@ -105,7 +106,7 @@ extension NCMenuAction {
     }
 
     /// Delete files either from cache or from Nextcloud
-    static func deleteAction(selectedMetadatas: [tableMetadata], metadataFolder: tableMetadata? = nil, viewController: UIViewController, order: Int = 0, completion: (() -> Void)? = nil) -> NCMenuAction {
+    static func deleteAction(selectedMetadatas: [tableMetadata], indexPath: [IndexPath], metadataFolder: tableMetadata? = nil, viewController: UIViewController, order: Int = 0, completion: (() -> Void)? = nil) -> NCMenuAction {
         var titleDelete = NSLocalizedString("_delete_", comment: "")
         if selectedMetadatas.count > 1 {
             titleDelete = NSLocalizedString("_delete_selected_files_", comment: "")
@@ -145,6 +146,12 @@ extension NCMenuAction {
                     preferredStyle: .alert)
                 if canDeleteServer {
                     alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_delete_", comment: ""), style: .default) { (_: UIAlertAction) in
+                        let hud = JGProgressHUD()
+                        hud.textLabel.text = NSLocalizedString("_deletion_progess_", comment: "")
+                        if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
+                           let view = appDelegate.window?.rootViewController?.view {
+                            hud.show(in: view)
+                        }
                         Task {
                             var error = NKError()
                             var ocId: [String] = []
@@ -155,10 +162,7 @@ extension NCMenuAction {
                                     ocId.append(metadata.ocId)
                                 }
                             }
-                            if error != .success {
-                                NCContentPresenter.shared.showError(error: error)
-                            }
-                            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["account": account, "ocId": ocId, "error": error])
+                            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": indexPath, "onlyLocalCache": false, "error": error, "hud": hud])
                         }
                         completion?()
                     })
@@ -180,7 +184,7 @@ extension NCMenuAction {
                             if error != .success {
                                 NCContentPresenter.shared.showError(error: error)
                             }
-                            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["account": account, "ocId": ocId, "error": error])
+                            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": indexPath, "onlyLocalCache": true, "error": error])
                         }
                         completion?()
                     })
@@ -261,13 +265,13 @@ extension NCMenuAction {
     }
 
     /// Open view that lets the user move or copy the files within Nextcloud
-    static func moveOrCopyAction(selectedMetadatas: [tableMetadata], order: Int = 0, completion: (() -> Void)? = nil) -> NCMenuAction {
+    static func moveOrCopyAction(selectedMetadatas: [tableMetadata], indexPath: [IndexPath], order: Int = 0, completion: (() -> Void)? = nil) -> NCMenuAction {
         NCMenuAction(
             title: NSLocalizedString("_move_or_copy_selected_files_", comment: ""),
             icon: NCUtility.shared.loadImage(named: "arrow.up.right.square"),
             order: order,
             action: { _ in
-                NCActionCenter.shared.openSelectView(items: selectedMetadatas)
+                NCActionCenter.shared.openSelectView(items: selectedMetadatas, indexPath: indexPath)
                 completion?()
             }
         )

+ 4 - 3
iOSClient/Menu/NCViewer+Menu.swift

@@ -27,7 +27,7 @@ import NextcloudKit
 
 extension NCViewer {
 
-    func toggleMenu(viewController: UIViewController, metadata: tableMetadata, webView: Bool, imageIcon: UIImage?) {
+    func toggleMenu(viewController: UIViewController, metadata: tableMetadata, webView: Bool, imageIcon: UIImage?, indexPath: IndexPath = IndexPath()) {
 
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadata.ocId) else { return }
         
@@ -182,6 +182,7 @@ extension NCViewer {
                             vcRename.metadata = metadata
                             vcRename.disableChangeExt = true
                             vcRename.imagePreview = imageIcon
+                            vcRename.indexPath = indexPath
 
                             let popup = NCPopupViewController(contentController: vcRename, popupWidth: vcRename.width, popupHeight: vcRename.height)
 
@@ -196,7 +197,7 @@ extension NCViewer {
         // COPY - MOVE
         //
         if !webView, metadata.isCopyableMovable {
-            actions.append(.moveOrCopyAction(selectedMetadatas: [metadata]))
+            actions.append(.moveOrCopyAction(selectedMetadatas: [metadata], indexPath: []))
         }
 
         //
@@ -269,7 +270,7 @@ extension NCViewer {
         // DELETE
         //
         if !webView, metadata.isDeletable {
-            actions.append(.deleteAction(selectedMetadatas: [metadata], metadataFolder: nil, viewController: viewController))
+            actions.append(.deleteAction(selectedMetadatas: [metadata], indexPath: [], metadataFolder: nil, viewController: viewController))
         }
 
         viewController.presentMenu(with: actions)

+ 4 - 6
iOSClient/NCGlobal.swift

@@ -146,12 +146,10 @@ class NCGlobal: NSObject {
     let layoutList                                  = "typeLayoutList"
     let layoutGrid                                  = "typeLayoutGrid"
 
-    let layoutViewMove                              = "LayoutMove"
     let layoutViewTrash                             = "LayoutTrash"
     let layoutViewOffline                           = "LayoutOffline"
     let layoutViewFavorite                          = "LayoutFavorite"
     let layoutViewFiles                             = "LayoutFiles"
-    let layoutViewViewInFolder                      = "LayoutViewInFolder"
     let layoutViewTransfers                         = "LayoutTransfers"
     let layoutViewRecent                            = "LayoutRecent"
     let layoutViewShares                            = "LayoutShares"
@@ -351,10 +349,10 @@ class NCGlobal: NSObject {
     let notificationCenterProgressTask                          = "progressTask"                    // userInfo: account, ocId, serverUrl, status, chunk, e2eEncrypted, progress, totalBytes, totalBytesExpected
 
     let notificationCenterCreateFolder                          = "createFolder"                    // userInfo: ocId, serverUrl, account, e2ee, withPush
-    let notificationCenterDeleteFile                            = "deleteFile"                      // userInfo: account, ocIds, error
-    let notificationCenterRenameFile                            = "renameFile"                      // userInfo: ocId, account
-    let notificationCenterMoveFile                              = "moveFile"                        // userInfo: ocId, account, serverUrlFrom
-    let notificationCenterCopyFile                              = "copyFile"                        // userInfo: ocId, serverUrlTo
+    let notificationCenterDeleteFile                            = "deleteFile"                      // userInfo: [ocId], [indexPath], onlyLocalCache, hud?
+    let notificationCenterMoveFile                              = "moveFile"                        // userInfo: [ocId], [indexPath], hud?
+    let notificationCenterCopyFile                              = "copyFile"                        // userInfo: [ocId], [indexPath], hud?
+    let notificationCenterRenameFile                            = "renameFile"                      // userInfo: ocId, account, indexPath
     let notificationCenterFavoriteFile                          = "favoriteFile"                    // userInfo: ocId, serverUrl
 
     let notificationCenterOperationReadFile                     = "operationReadFile"               // userInfo: ocId

+ 2 - 2
iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift

@@ -32,7 +32,7 @@ class NCNetworkingE2EERename: NSObject {
         return instance
     }()
 
-    func rename(metadata: tableMetadata, fileNameNew: String) async -> (NKError) {
+    func rename(metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath) async -> (NKError) {
 
         if let error = NCNetworkingE2EE.shared.isE2EEVersionWriteable(account: metadata.account) {
             return error
@@ -93,7 +93,7 @@ class NCNetworkingE2EERename: NSObject {
         await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
         
         if error == .success {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account])
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "indexPath": indexPath])
         }
 
         return error

+ 36 - 49
iOSClient/Networking/NCNetworking.swift

@@ -1333,7 +1333,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     // MARK: - WebDav Rename
 
-    func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, viewController: UIViewController?, completion: @escaping (_ error: NKError) -> Void) {
+    func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath, viewController: UIViewController?, completion: @escaping (_ error: NKError) -> Void) {
 
         let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
         let fileNameNew = fileNameNew.trimmingCharacters(in: .whitespacesAndNewlines)
@@ -1343,26 +1343,26 @@ class NCNetworking: NSObject, NKCommonDelegate {
 #if !EXTENSION
             Task {
                 if let metadataLive = metadataLive {
-                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadataLive, fileNameNew: fileNameNew)
+                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadataLive, fileNameNew: fileNameNew, indexPath: indexPath)
                     if error == .success {
-                        let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew)
+                        let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
                         DispatchQueue.main.async { completion(error) }
                     } else {
                         DispatchQueue.main.async { completion(error) }
                     }
                 } else {
-                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew)
+                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
                     DispatchQueue.main.async { completion(error) }
                 }
             }
 #endif
         } else {
             if metadataLive == nil {
-                renameMetadataPlain(metadata, fileNameNew: fileNameNew, completion: completion)
+                renameMetadataPlain(metadata, fileNameNew: fileNameNew, indexPath: indexPath, completion: completion)
             } else {
-                renameMetadataPlain(metadataLive!, fileNameNew: fileNameNewLive) { error in
+                renameMetadataPlain(metadataLive!, fileNameNew: fileNameNewLive, indexPath: indexPath) { error in
                     if error == .success {
-                        self.renameMetadataPlain(metadata, fileNameNew: fileNameNew, completion: completion)
+                        self.renameMetadataPlain(metadata, fileNameNew: fileNameNew, indexPath: indexPath, completion: completion)
                     } else {
                         completion(error)
                     }
@@ -1371,7 +1371,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         }
     }
 
-    private func renameMetadataPlain(_ metadata: tableMetadata, fileNameNew: String, completion: @escaping (_ error: NKError) -> Void) {
+    private func renameMetadataPlain(_ metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath, completion: @escaping (_ error: NKError) -> Void) {
 
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
@@ -1428,7 +1428,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
                 }
 
                 if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account])
+                    NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "indexPath": indexPath])
                 }
             }
 
@@ -1438,80 +1438,67 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     // MARK: - WebDav Move
 
-    @objc func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ error: NKError) -> Void) {
+    @objc func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
 
         if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
-            moveMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite) { error in
-                if error == .success {
-                    self.moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
-                } else {
-                    completion(error)
-                }
+            let error = await moveMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
+            if error == .success {
+                return await moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
+            } else {
+                return error
             }
-        } else {
-            moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
         }
+        return await moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
     }
 
-    private func moveMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ error: NKError) -> Void) {
+    private func moveMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
 
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
-            return completion(NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_no_permission_modify_file_"))
+            return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_no_permission_modify_file_")
         }
 
-        let serverUrlFrom = metadata.serverUrl
         let serverUrlFileNameSource = metadata.serverUrl + "/" + metadata.fileName
         let serverUrlFileNameDestination = serverUrlTo + "/" + metadata.fileName
 
-        NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite) { account, error in
-
-            if error == .success {
-                if metadata.directory {
-                    NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName), account: account)
-                }
-                NCManageDatabase.shared.moveMetadata(ocId: metadata.ocId, serverUrlTo: serverUrlTo)
-                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMoveFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "serverUrlFrom": serverUrlFrom])
+        let result = await NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite)
+        if result.error == .success {
+            if metadata.directory {
+                NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName), account: result.account)
             }
-
-            completion(error)
+            NCManageDatabase.shared.moveMetadata(ocId: metadata.ocId, serverUrlTo: serverUrlTo)
         }
+
+        return result.error
     }
 
     // MARK: - WebDav Copy
 
-    func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ error: NKError) -> Void) {
+    func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
 
         if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
-            copyMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite) { error in
-                if error == .success {
-                    self.copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
-                } else {
-                    completion(error)
-                }
+            let error = await copyMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
+            if error == .success {
+                return await copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
+            } else {
+                return error
             }
-        } else {
-            copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
         }
+        return await copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
     }
 
-    private func copyMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ error: NKError) -> Void) {
+    private func copyMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
 
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
-            return completion(NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_no_permission_modify_file_"))
+            return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_no_permission_modify_file_")
         }
 
         let serverUrlFileNameSource = metadata.serverUrl + "/" + metadata.fileName
         let serverUrlFileNameDestination = serverUrlTo + "/" + metadata.fileName
 
-        NextcloudKit.shared.copyFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite) { _, error in
-
-            if error == .success {
-                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCopyFile, userInfo: ["ocId": metadata.ocId, "serverUrlTo": serverUrlTo])
-            }
-            completion(error)
-        }
+        let result = await NextcloudKit.shared.copyFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite)
+        return result.error
     }
 
     // MARK: - Direct Download

+ 0 - 54
iOSClient/Networking/NCOperationQueue.swift

@@ -32,7 +32,6 @@ import NextcloudKit
     }()
 
     private var downloadQueue = Queuer(name: "downloadQueue", maxConcurrentOperationCount: 5, qualityOfService: .default)
-    private let copyMoveQueue = Queuer(name: "copyMoveQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
     private let synchronizationQueue = Queuer(name: "synchronizationQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
     private let downloadThumbnailQueue = Queuer(name: "downloadThumbnailQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
     private let downloadThumbnailActivityQueue = Queuer(name: "downloadThumbnailActivityQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
@@ -42,7 +41,6 @@ import NextcloudKit
 
     @objc func cancelAllQueue() {
         downloadCancelAll()
-        copyMoveCancelAll()
         synchronizationCancelAll()
         downloadThumbnailCancelAll()
         downloadThumbnailActivityCancelAll()
@@ -75,19 +73,6 @@ import NextcloudKit
         return false
     }
 
-    // MARK: - Copy Move file
-
-    func copyMove(metadata: tableMetadata, serverUrl: String, overwrite: Bool, move: Bool) {
-        for case let operation as NCOperationCopyMove in copyMoveQueue.operations where operation.metadata.ocId == metadata.ocId {
-            return
-        }
-        copyMoveQueue.addOperation(NCOperationCopyMove(metadata: metadata, serverUrlTo: serverUrl, overwrite: overwrite, move: move))
-    }
-
-    func copyMoveCancelAll() {
-        copyMoveQueue.cancelAll()
-    }
-
     // MARK: - Synchronization
 
     func synchronizationMetadata(_ metadata: tableMetadata, selector: String) {
@@ -244,45 +229,6 @@ class NCOperationDownload: ConcurrentOperation {
 
 // MARK: -
 
-class NCOperationCopyMove: ConcurrentOperation {
-
-    var metadata: tableMetadata
-    var serverUrlTo: String
-    var overwrite: Bool
-    var move: Bool
-
-    init(metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, move: Bool) {
-        self.metadata = tableMetadata.init(value: metadata)
-        self.serverUrlTo = serverUrlTo
-        self.overwrite = overwrite
-        self.move = move
-    }
-
-    override func start() {
-        if isCancelled {
-            self.finish()
-        } else {
-            if move {
-                NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { error in
-                    if error != .success {
-                        NCContentPresenter.shared.showError(error: error)
-                    }
-                    self.finish()
-                }
-            } else {
-                NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { error in
-                    if error != .success {
-                        NCContentPresenter.shared.showError(error: error)
-                    }
-                    self.finish()
-                }
-            }
-        }
-    }
-}
-
-// MARK: -
-
 class NCOperationSynchronization: ConcurrentOperation {
 
     var metadata: tableMetadata

+ 7 - 0
iOSClient/Notification/NCNotification.swift

@@ -127,6 +127,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
         let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NCNotificationCell
         cell.delegate = self
         cell.selectionStyle = .none
+        cell.indexPath = indexPath
 
         let notification = notifications[indexPath.row]
         let urlIcon = URL(string: notification.icon)
@@ -347,10 +348,16 @@ class NCNotificationCell: UITableViewCell, NCCellProtocol {
     @IBOutlet weak var secondaryWidth: NSLayoutConstraint!
 
     private var user = ""
+    private var index = IndexPath()
 
     weak var delegate: NCNotificationCellDelegate?
     var notification: NKNotifications?
 
+
+    var indexPath: IndexPath {
+        get { return index }
+        set { index = newValue }
+    }
     var fileAvatarImageView: UIImageView? {
         get { return avatar }
     }

+ 37 - 33
iOSClient/Offline/NCOffline.swift

@@ -49,40 +49,44 @@ class NCOffline: NCCollectionViewCommon {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
-        super.reloadDataSource()
+    override func queryDB(isForced: Bool) {
 
-        DispatchQueue.global().async {
-            var ocIds: [String] = []
-            var metadatas: [tableMetadata] = []
-
-            if self.serverUrl.isEmpty {
-                if let directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", self.appDelegate.account), sorted: "serverUrl", ascending: true) {
-                    for directory: tableDirectory in directories {
-                        ocIds.append(directory.ocId)
-                    }
-                }
-                let files = NCManageDatabase.shared.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", self.appDelegate.account), sorted: "fileName", ascending: true)
-                for file in files {
-                    ocIds.append(file.ocId)
+        var ocIds: [String] = []
+        var metadatas: [tableMetadata] = []
+
+        if self.serverUrl.isEmpty {
+            if let directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", self.appDelegate.account), sorted: "serverUrl", ascending: true) {
+                for directory: tableDirectory in directories {
+                    ocIds.append(directory.ocId)
                 }
-                metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", self.appDelegate.account, ocIds))
-            } else {
-                metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
             }
+            let files = NCManageDatabase.shared.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", self.appDelegate.account), sorted: "fileName", ascending: true)
+            for file in files {
+                ocIds.append(file.ocId)
+            }
+            metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", self.appDelegate.account, ocIds))
+        } else {
+            metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
+        }
 
-            self.dataSource = NCDataSource(
-                metadatas: metadatas,
-                account: self.appDelegate.account,
-                sort: self.layoutForView?.sort,
-                ascending: self.layoutForView?.ascending,
-                directoryOnTop: self.layoutForView?.directoryOnTop,
-                favoriteOnTop: true,
-                filterLivePhoto: true,
-                groupByField: self.groupByField,
-                providers: self.providers,
-                searchResults: self.searchResults)
+        self.dataSource = NCDataSource(
+            metadatas: metadatas,
+            account: self.appDelegate.account,
+            sort: self.layoutForView?.sort,
+            ascending: self.layoutForView?.ascending,
+            directoryOnTop: self.layoutForView?.directoryOnTop,
+            favoriteOnTop: true,
+            filterLivePhoto: true,
+            groupByField: self.groupByField,
+            providers: self.providers,
+            searchResults: self.searchResults)
+    }
 
+    override func reloadDataSource(isForced: Bool = true) {
+        super.reloadDataSource()
+
+        DispatchQueue.global().async {
+            self.queryDB(isForced: isForced)
             DispatchQueue.main.async {
                 self.refreshControl.endRefreshing()
                 self.collectionView.reloadData()
@@ -90,8 +94,8 @@ class NCOffline: NCCollectionViewCommon {
         }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
 
         guard !serverUrl.isEmpty else {
             self.reloadDataSource()
@@ -101,7 +105,7 @@ class NCOffline: NCCollectionViewCommon {
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()
 
-        networkReadFolder(forced: forced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
+        networkReadFolder(isForced: isForced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in
             if error == .success, let metadatas = metadatas {
                 for metadata in metadatas where (!metadata.directory && NCManageDatabase.shared.isDownloadMetadata(metadata, download: true)) {
                     NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile)
@@ -112,7 +116,7 @@ class NCOffline: NCCollectionViewCommon {
                 self.refreshControl.endRefreshing()
                 self.isReloadDataSourceNetworkInProgress = false
                 self.richWorkspaceText = tableDirectory?.richWorkspace
-                if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || forced {
+                if metadatasUpdate?.count ?? 0 > 0 || metadatasDelete?.count ?? 0 > 0 || isForced {
                     self.reloadDataSource()
                 } else {
                     self.collectionView?.reloadData()

+ 16 - 12
iOSClient/Recent/NCRecent.swift

@@ -49,19 +49,23 @@ class NCRecent: NCCollectionViewCommon {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
+    override func queryDB(isForced: Bool) {
+
+        let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "account == %@", self.appDelegate.account), page: 1, limit: 100, sorted: "date", ascending: false)
+        self.dataSource = NCDataSource(metadatas: metadatas,
+                                       account: self.appDelegate.account,
+                                       directoryOnTop: false,
+                                       favoriteOnTop: false,
+                                       groupByField: self.groupByField,
+                                       providers: self.providers,
+                                       searchResults: self.searchResults)
+    }
+
+    override func reloadDataSource(isForced: Bool = true) {
         super.reloadDataSource()
 
         DispatchQueue.global().async {
-            let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "account == %@", self.appDelegate.account), page: 1, limit: 100, sorted: "date", ascending: false)
-            self.dataSource = NCDataSource(metadatas: metadatas,
-                                           account: self.appDelegate.account,
-                                           directoryOnTop: false,
-                                           favoriteOnTop: false,
-                                           groupByField: self.groupByField,
-                                           providers: self.providers,
-                                           searchResults: self.searchResults)
-
+            self.queryDB(isForced: isForced)
             DispatchQueue.main.async {
                 self.refreshControl.endRefreshing()
                 self.collectionView.reloadData()
@@ -69,8 +73,8 @@ class NCRecent: NCCollectionViewCommon {
         }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
 
         let requestBodyRecent =
         """

+ 6 - 5
iOSClient/Rename file/NCRenameFile.swift

@@ -48,6 +48,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
     let height: CGFloat = 310
 
     var metadata: tableMetadata?
+    var indexPath: IndexPath = IndexPath()
     var fileName: String?
     var imagePreview: UIImage?
     var disableChangeExt: Bool = false
@@ -173,7 +174,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
             if metadata.directory {
 
                 fileNameNew = fileNameNoExtensionNew
-                renameMetadata(metadata, fileNameNew: fileNameNew)
+                renameMetadata(metadata, fileNameNew: fileNameNew, indexPath: indexPath)
 
             } else {
 
@@ -193,7 +194,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
                     alertController.addAction(UIAlertAction(title: title, style: .default, handler: { _ in
 
                         fileNameNew = fileNameNoExtensionNew + "." + extNew
-                        self.renameMetadata(metadata, fileNameNew: fileNameNew)
+                        self.renameMetadata(metadata, fileNameNew: fileNameNew, indexPath: self.indexPath)
                     }))
 
                     title = NSLocalizedString("_keep_", comment: "") + " ." + extCurrent
@@ -206,7 +207,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
                 } else {
 
                     fileNameNew = fileNameNoExtensionNew + "." + extNew
-                    renameMetadata(metadata, fileNameNew: fileNameNew)
+                    renameMetadata(metadata, fileNameNew: fileNameNew, indexPath: indexPath)
                 }
             }
 
@@ -229,7 +230,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
 
     // MARK: - Networking
 
-    func renameMetadata(_ metadata: tableMetadata, fileNameNew: String) {
+    func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath) {
 
         // verify if already exists
         if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, fileNameNew)) != nil {
@@ -239,7 +240,7 @@ class NCRenameFile: UIViewController, UITextFieldDelegate {
 
         NCActivityIndicator.shared.start()
 
-        NCNetworking.shared.renameMetadata(metadata, fileNameNew: fileNameNew, viewController: self) { error in
+        NCNetworking.shared.renameMetadata(metadata, fileNameNew: fileNameNew, indexPath: indexPath, viewController: self) { error in
 
             NCActivityIndicator.shared.stop()
 

+ 2 - 0
iOSClient/Scan document/NCScan+CollectionView.swift

@@ -48,6 +48,7 @@ extension NCScan: UICollectionViewDataSource {
                 image = image.resizeImage(size: CGSize(width: 595, height: 842)) ?? image
             }
 
+            cell.indexPath = indexPath
             cell.customImageView?.image = image
             cell.delete.action(for: .touchUpInside) { sender in
 
@@ -69,6 +70,7 @@ extension NCScan: UICollectionViewDataSource {
             let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath) as? NCScanCell)!
             cell.delegate = self
             cell.index = indexPath.row
+            cell.indexPath = indexPath
 
             var image = imagesDestination[indexPath.row]
 

+ 1 - 0
iOSClient/Scan document/NCScanCell.swift

@@ -32,6 +32,7 @@ class NCScanCell: UICollectionViewCell {
 
     weak var delegate: NCScanCellCellDelegate?
     var index = 0
+    var indexPath = IndexPath()
 
     @IBAction func touchUpInsideDelete(_ sender: Any) {
         delegate?.delete(with: index, sender: sender)

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

@@ -326,7 +326,7 @@ class NCUploadScanDocument: ObservableObject {
 
 extension NCUploadScanDocument: NCSelectDelegate {
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         if let serverUrl = serverUrl {
             CCUtility.setDirectoryScanDocument(serverUrl)

+ 87 - 291
iOSClient/Select/NCSelect.swift

@@ -26,7 +26,7 @@ import SwiftUI
 import NextcloudKit
 
 @objc protocol NCSelectDelegate {
-    @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool)
+    @objc func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool)
 }
 
 class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresentationControllerDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, NCEmptyDataSetDelegate {
@@ -53,6 +53,7 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
     @objc var enableSelectFile = false
     @objc var type = ""
     @objc var items: [tableMetadata] = []
+    @objc var selectIndexPath: [IndexPath] = []
 
     var titleCurrentFolder = NCBrandOptions.shared.brand
     var serverUrl = ""
@@ -60,28 +61,20 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
 
     private var emptyDataSet: NCEmptyDataSet?
 
-    private let layoutKey = NCGlobal.shared.layoutViewMove
     private var serverUrlPush = ""
     private var metadataFolder = tableMetadata()
 
-    private var isEditMode = false
-    private var isSearching = false
     private var networkInProgress = false
-    private var selectOcId: [String] = []
     private var overwrite = true
 
     private var dataSource = NCDataSource()
     internal var richWorkspaceText: String?
 
-    private var layoutForView: NCDBLayoutForView?
     internal var headerMenu: NCSectionHeaderMenu?
 
     private var autoUploadFileName = ""
     private var autoUploadDirectory = ""
 
-    private var listLayout: NCListLayout!
-    private var gridLayout: NCGridLayout!
-
     private var backgroundImageView = UIImageView()
 
     private var activeAccount: tableAccount!
@@ -102,7 +95,7 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
 
         // Cell
         collectionView.register(UINib(nibName: "NCListCell", bundle: nil), forCellWithReuseIdentifier: "listCell")
-        collectionView.register(UINib(nibName: "NCGridCell", bundle: nil), forCellWithReuseIdentifier: "gridCell")
+        collectionView.collectionViewLayout = NCListLayout()
 
         // Header
         collectionView.register(UINib(nibName: "NCSectionHeaderMenu", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "sectionHeaderMenu")
@@ -112,9 +105,6 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
         collectionView.alwaysBounceVertical = true
         collectionView.backgroundColor = .systemBackground
 
-        listLayout = NCListLayout()
-        gridLayout = NCGridLayout()
-
         buttonCancel.title = NSLocalizedString("_cancel_", comment: "")
 
         bottomContraint?.constant = window?.rootViewController?.view.safeAreaInsets.bottom ?? 0
@@ -176,15 +166,6 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
         autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName()
         autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, userId: activeAccount.userId, account: activeAccount.account)
 
-        layoutForView = NCManageDatabase.shared.getLayoutForView(account: activeAccount.account, key: layoutKey, serverUrl: serverUrl)
-        gridLayout.itemForLine = CGFloat(layoutForView?.itemForLine ?? 3)
-
-        if layoutForView?.layout == NCGlobal.shared.layoutList {
-            collectionView.collectionViewLayout = listLayout
-        } else {
-            collectionView.collectionViewLayout = gridLayout
-        }
-
         loadDatasource(withLoadFolder: true)
     }
 
@@ -240,17 +221,17 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
     }
 
     func selectButtonPressed(_ sender: UIButton) {
-        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, overwrite: overwrite, copy: false, move: false)
+        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, indexPath: selectIndexPath, overwrite: overwrite, copy: false, move: false)
         self.dismiss(animated: true, completion: nil)
     }
 
     func copyButtonPressed(_ sender: UIButton) {
-        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, overwrite: overwrite, copy: true, move: false)
+        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, indexPath: selectIndexPath, overwrite: overwrite, copy: true, move: false)
         self.dismiss(animated: true, completion: nil)
     }
 
     func moveButtonPressed(_ sender: UIButton) {
-        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, overwrite: overwrite, copy: false, move: true)
+        delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadataFolder, type: type, items: items, indexPath: selectIndexPath, overwrite: overwrite, copy: false, move: true)
         self.dismiss(animated: true, completion: nil)
     }
 
@@ -263,40 +244,6 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
         overwrite = sender.isOn
     }
 
-    // MARK: TAP EVENT
-
-    func tapButtonSwitch(_ sender: Any) {
-
-        if layoutForView?.layout == NCGlobal.shared.layoutGrid {
-
-            // list layout
-            headerMenu?.buttonSwitch.accessibilityLabel = NSLocalizedString("_grid_view_", comment: "")
-            layoutForView?.layout = NCGlobal.shared.layoutList
-            NCManageDatabase.shared.setLayoutForView(account: activeAccount.account, key: layoutKey, serverUrl: serverUrl, layout: layoutForView?.layout)
-
-            self.collectionView.reloadData()
-            self.collectionView.collectionViewLayout.invalidateLayout()
-            self.collectionView.setCollectionViewLayout(self.listLayout, animated: true)
-
-        } else {
-
-            // grid layout
-            headerMenu?.buttonSwitch.accessibilityLabel = NSLocalizedString("_list_view_", comment: "")
-            layoutForView?.layout = NCGlobal.shared.layoutGrid
-            NCManageDatabase.shared.setLayoutForView(account: activeAccount.account, key: layoutKey, serverUrl: serverUrl, layout: layoutForView?.layout)
-
-            self.collectionView.reloadData()
-            self.collectionView.collectionViewLayout.invalidateLayout()
-            self.collectionView.setCollectionViewLayout(self.gridLayout, animated: true)
-        }
-    }
-
-    func tapButtonOrder(_ sender: Any) {
-
-        let sortMenu = NCSortMenu()
-        sortMenu.toggleMenu(viewController: self, account: activeAccount.account, key: layoutKey, sortButton: sender as? UIButton, serverUrl: serverUrl)
-    }
-
     // MARK: - Push metadata
 
     func pushMetadata(_ metadata: tableMetadata) {
@@ -314,6 +261,7 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent
         viewController.type = type
         viewController.overwrite = overwrite
         viewController.items = items
+        viewController.selectIndexPath = selectIndexPath
 
         viewController.titleCurrentFolder = metadata.fileNameView
         viewController.serverUrl = serverUrlPush
@@ -330,23 +278,13 @@ extension NCSelect: UICollectionViewDelegate {
 
         guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return }
 
-        if isEditMode {
-            if let index = selectOcId.firstIndex(of: metadata.ocId) {
-                selectOcId.remove(at: index)
-            } else {
-                selectOcId.append(metadata.ocId)
-            }
-            collectionView.reloadItems(at: [indexPath])
-            return
-        }
-
         if metadata.directory {
 
             pushMetadata(metadata)
 
         } else {
 
-            delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadata, type: type, items: items, overwrite: overwrite, copy: false, move: false)
+            delegate?.dismissSelect(serverUrl: serverUrl, metadata: metadata, type: type, items: items, indexPath: selectIndexPath, overwrite: overwrite, copy: false, move: false)
             self.dismiss(animated: true, completion: nil)
         }
     }
@@ -393,11 +331,7 @@ extension NCSelect: UICollectionViewDataSource {
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 
         guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else {
-            if layoutForView?.layout == NCGlobal.shared.layoutList {
-                return collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
-            } else {
-                return collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
-            }
+            return collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
         }
 
         var isShare = false
@@ -406,227 +340,105 @@ extension NCSelect: UICollectionViewDataSource {
         isShare = metadata.permissions.contains(NCGlobal.shared.permissionShared) && !metadataFolder.permissions.contains(NCGlobal.shared.permissionShared)
         isMounted = metadata.permissions.contains(NCGlobal.shared.permissionMounted) && !metadataFolder.permissions.contains(NCGlobal.shared.permissionMounted)
 
-        // LAYOUT LIST
-
-        if layoutForView?.layout == NCGlobal.shared.layoutList {
-
-            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
-            cell.delegate = self
-
-            cell.fileObjectId = metadata.ocId
-            cell.fileUser = metadata.ownerId
-            cell.labelTitle.text = metadata.fileNameView
-            cell.labelTitle.textColor = .label
-
-            cell.imageSelect.image = nil
-            cell.imageStatus.image = nil
-            cell.imageLocal.image = nil
-            cell.imageFavorite.image = nil
-            cell.imageShared.image = nil
-            cell.imageMore.image = nil
-
-            cell.imageItem.image = nil
-            cell.imageItem.backgroundColor = nil
-
-            cell.progressView.progress = 0.0
-
-            if metadata.directory {
-
-                if metadata.e2eEncrypted {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
-                } else if isShare {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if !metadata.shareType.isEmpty {
-                    metadata.shareType.contains(3) ?
-                    (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
-                    (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
-                } else if metadata.mountType == "group" {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
-                } else if isMounted {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderExternal
-                } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderAutomaticUpload
-                } else {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folder
-                }
-                cell.imageItem.image = cell.imageItem.image?.colorizeFolder(metadata: metadata)
-
-                cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date)
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
+        cell.delegate = self
 
-            } else {
+        cell.fileObjectId = metadata.ocId
+        cell.fileUser = metadata.ownerId
+        cell.labelTitle.text = metadata.fileNameView
+        cell.labelTitle.textColor = .label
 
-                cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date) + " · " + CCUtility.transformedSize(metadata.size)
+        cell.imageSelect.image = nil
+        cell.imageStatus.image = nil
+        cell.imageLocal.image = nil
+        cell.imageFavorite.image = nil
+        cell.imageShared.image = nil
+        cell.imageMore.image = nil
 
-                // image local
-                if dataSource.metadatasForSection[indexPath.section].metadataOffLine.contains(metadata.ocId) {
-                    cell.imageLocal.image = NCBrandColor.cacheImages.offlineFlag
-                } else if CCUtility.fileProviderStorageExists(metadata) {
-                    cell.imageLocal.image = NCBrandColor.cacheImages.local
-                }
-            }
+        cell.imageItem.image = nil
+        cell.imageItem.backgroundColor = nil
 
-            // image Favorite
-            if metadata.favorite {
-                cell.imageFavorite.image = NCBrandColor.cacheImages.favorite
-            }
+        cell.progressView.progress = 0.0
 
-            // Share image
-            if isShare {
-                cell.imageShared.image = NCBrandColor.cacheImages.shared
+        if metadata.directory {
+
+            if metadata.e2eEncrypted {
+                cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
+            } else if isShare {
+                cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
             } else if !metadata.shareType.isEmpty {
                 metadata.shareType.contains(3) ?
-                (cell.imageShared.image = NCBrandColor.cacheImages.shareByLink) :
-                (cell.imageShared.image = NCBrandColor.cacheImages.shared)
+                (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
+                (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
+            } else if metadata.mountType == "group" {
+                cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
+            } else if isMounted {
+                cell.imageItem.image = NCBrandColor.cacheImages.folderExternal
+            } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory {
+                cell.imageItem.image = NCBrandColor.cacheImages.folderAutomaticUpload
             } else {
-                cell.imageShared.image = NCBrandColor.cacheImages.canShare
+                cell.imageItem.image = NCBrandColor.cacheImages.folder
             }
+            cell.imageItem.image = cell.imageItem.image?.colorizeFolder(metadata: metadata)
 
-            cell.imageSelect.isHidden = true
-            cell.backgroundView = nil
-            cell.hideButtonMore(true)
-            cell.hideButtonShare(true)
-            cell.selectMode(false)
-
-            // Live Photo
-            if metadata.livePhoto {
-                cell.imageStatus.image = NCBrandColor.cacheImages.livePhoto
-            }
+            cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date)
 
-            // Remove last separator
-            if collectionView.numberOfItems(inSection: indexPath.section) == indexPath.row + 1 {
-                cell.separator.isHidden = true
-            } else {
-                cell.separator.isHidden = false
-            }
-
-            // Add TAGS
-            cell.setTags(tags: Array(metadata.tags))
-
-            return cell
-        }
-
-        // LAYOUT GRID
-
-        if layoutForView?.layout == NCGlobal.shared.layoutGrid {
-
-            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
-            cell.delegate = self
-
-            cell.fileObjectId = metadata.ocId
-            cell.fileUser = metadata.ownerId
-            cell.labelTitle.text = metadata.fileNameView
-            cell.labelTitle.textColor = .label
-
-            cell.imageSelect.image = nil
-            cell.imageStatus.image = nil
-            cell.imageLocal.image = nil
-            cell.imageFavorite.image = nil
-
-            cell.imageItem.image = nil
-            cell.imageItem.backgroundColor = nil
-
-            cell.progressView.progress = 0.0
-
-            if metadata.directory {
-
-                if metadata.e2eEncrypted {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderEncrypted
-                } else if isShare {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe
-                } else if !metadata.shareType.isEmpty {
-                    metadata.shareType.contains(3) ?
-                    (cell.imageItem.image = NCBrandColor.cacheImages.folderPublic) :
-                    (cell.imageItem.image = NCBrandColor.cacheImages.folderSharedWithMe)
-                } else if metadata.mountType == "group" {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderGroup
-                } else if isMounted {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderExternal
-                } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folderAutomaticUpload
-                } else {
-                    cell.imageItem.image = NCBrandColor.cacheImages.folder
-                }
-                cell.imageItem.image = cell.imageItem.image?.colorizeFolder(metadata: metadata)
+        } else {
 
-            } else {
+            cell.labelInfo.text = CCUtility.dateDiff(metadata.date as Date) + " · " + CCUtility.transformedSize(metadata.size)
 
-                // image Local
-                if dataSource.metadatasForSection[indexPath.section].metadataOffLine.contains(metadata.ocId) {
-                    cell.imageLocal.image = NCBrandColor.cacheImages.offlineFlag
-                } else if CCUtility.fileProviderStorageExists(metadata) {
-                    cell.imageLocal.image = NCBrandColor.cacheImages.local
-                }
+            // image local
+            if NCManageDatabase.shared.getTableLocalFile(ocId: metadata.ocId) != nil {
+                cell.imageLocal.image = NCBrandColor.cacheImages.offlineFlag
+            } else if CCUtility.fileProviderStorageExists(metadata) {
+                cell.imageLocal.image = NCBrandColor.cacheImages.local
             }
+        }
 
-            // image Favorite
-            if metadata.favorite {
-                cell.imageFavorite.image = NCBrandColor.cacheImages.favorite
-            }
+        // image Favorite
+        if metadata.favorite {
+            cell.imageFavorite.image = NCBrandColor.cacheImages.favorite
+        }
 
-            cell.imageSelect.isHidden = true
-            cell.backgroundView = nil
-            cell.hideButtonMore(true)
+        cell.imageSelect.isHidden = true
+        cell.backgroundView = nil
+        cell.hideButtonMore(true)
+        cell.hideButtonShare(true)
+        cell.selectMode(false)
 
-            // Live Photo
-            if metadata.livePhoto {
-                cell.imageStatus.image = NCBrandColor.cacheImages.livePhoto
-            }
+        // Live Photo
+        if metadata.livePhoto {
+            cell.imageStatus.image = NCBrandColor.cacheImages.livePhoto
+        }
 
-            return cell
+        // Remove last separator
+        if collectionView.numberOfItems(inSection: indexPath.section) == indexPath.row + 1 {
+            cell.separator.isHidden = true
+        } else {
+            cell.separator.isHidden = false
         }
 
-        return collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
+        // Add TAGS
+        cell.setTags(tags: Array(metadata.tags))
+
+        return cell
     }
 
     func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
 
         if kind == UICollectionView.elementKindSectionHeader {
 
-            if indexPath.section == 0 {
-
-                let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as! NCSectionHeaderMenu
-                let (_, heightHeaderRichWorkspace, heightHeaderSection) = getHeaderHeight(section: indexPath.section)
-
-                self.headerMenu = header
+            let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as! NCSectionHeaderMenu
+            let (_, heightHeaderRichWorkspace, _) = getHeaderHeight(section: indexPath.section)
 
-                if layoutForView?.layout == NCGlobal.shared.layoutGrid  {
-                    header.setImageSwitchList()
-                    header.buttonSwitch.accessibilityLabel = NSLocalizedString("_list_view_", comment: "")
-                } else {
-                    header.setImageSwitchGrid()
-                    header.buttonSwitch.accessibilityLabel = NSLocalizedString("_grid_view_", comment: "")
-                }
+            self.headerMenu = header
 
-                header.delegate = self
-
-                header.setButtonsView(height: NCGlobal.shared.heightButtonsView)
-                header.setStatusButtonsView(enable: !dataSource.getMetadataSourceForAllSections().isEmpty)
-                header.setSortedTitle(layoutForView?.titleButtonHeader ?? "")
-
-                header.setRichWorkspaceHeight(heightHeaderRichWorkspace)
-                header.setRichWorkspaceText(richWorkspaceText)
-
-                header.setViewTransfer(isHidden: true)
-
-                header.setSectionHeight(heightHeaderSection)
-                if heightHeaderSection == 0 {
-                    header.labelSection.text = ""
-                } else {
-                    header.labelSection.text = self.dataSource.getSectionValueLocalization(indexPath: indexPath)
-                }
-                header.labelSection.textColor = .label
-
-                return header
-
-            } else {
-
-                let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeader", for: indexPath) as! NCSectionHeader
-
-                header.labelSection.text = self.dataSource.getSectionValueLocalization(indexPath: indexPath)
-                header.labelSection.textColor = NCBrandColor.shared.brandElement
-
-                return header
-            }
+            header.delegate = self
+            header.setButtonsView(height: 0)
+            header.setRichWorkspaceHeight(heightHeaderRichWorkspace)
+            header.setRichWorkspaceText(richWorkspaceText)
+            header.setViewTransfer(isHidden: true)
+            return header
 
         } else {
 
@@ -657,20 +469,12 @@ extension NCSelect: UICollectionViewDelegateFlowLayout {
 
         if let richWorkspaceText = richWorkspaceText {
             let trimmed = richWorkspaceText.trimmingCharacters(in: .whitespaces)
-            if trimmed.count > 0 && !isSearching {
+            if trimmed.count > 0  {
                 headerRichWorkspace = UIScreen.main.bounds.size.height / 6
             }
         }
 
-        if isSearching || layoutForView?.layout == NCGlobal.shared.layoutGrid  || dataSource.numberOfSections() > 1 {
-            if section == 0 {
-                return (NCGlobal.shared.heightButtonsView, headerRichWorkspace, NCGlobal.shared.heightSection)
-            } else {
-                return (0, 0, NCGlobal.shared.heightSection)
-            }
-        } else {
-            return (NCGlobal.shared.heightButtonsView, headerRichWorkspace, 0)
-        }
+        return (0, headerRichWorkspace, 0)
     }
 
     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
@@ -704,14 +508,6 @@ extension NCSelect {
     @objc func loadDatasource(withLoadFolder: Bool) {
 
         var predicate: NSPredicate?
-        var groupByField = "name"
-        
-        layoutForView = NCManageDatabase.shared.getLayoutForView(account: activeAccount.account, key: layoutKey, serverUrl: serverUrl)
-
-        // set GroupField for Grid
-        if layoutForView?.layout == NCGlobal.shared.layoutGrid {
-            groupByField = "classFile"
-        }
 
         if includeDirectoryE2EEncryption {
 
@@ -735,12 +531,12 @@ extension NCSelect {
         let metadatas = NCManageDatabase.shared.getMetadatas(predicate: predicate!)
         self.dataSource = NCDataSource(metadatas: metadatas,
                                        account: activeAccount.account,
-                                       sort: layoutForView?.sort,
-                                       ascending: layoutForView?.ascending,
-                                       directoryOnTop: layoutForView?.directoryOnTop,
+                                       sort: "fileName",
+                                       ascending: true,
+                                       directoryOnTop: true,
                                        favoriteOnTop: true,
                                        filterLivePhoto: true,
-                                       groupByField: groupByField)
+                                       groupByField: "none")
 
         if withLoadFolder {
             loadFolder()
@@ -880,7 +676,7 @@ struct SelectView: UIViewControllerRepresentable {
             self.parent = parent
         }
 
-        func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+        func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
             if let serverUrl = serverUrl {
                 self.parent.serverUrl = serverUrl
             }

+ 2 - 0
iOSClient/Share/NCShare.swift

@@ -335,6 +335,7 @@ extension NCShare: UITableViewDataSource {
         // LINK
         if tableShare.shareType == NCShareCommon.shared.SHARE_TYPE_LINK {
             if let cell = tableView.dequeueReusableCell(withIdentifier: "cellLink", for: indexPath) as? NCShareLinkCell {
+                cell.indexPath = indexPath
                 cell.tableShare = tableShare
                 cell.delegate = self
                 cell.setupCellUI()
@@ -343,6 +344,7 @@ extension NCShare: UITableViewDataSource {
         } else {
         // USER / GROUP etc.
             if let cell = tableView.dequeueReusableCell(withIdentifier: "cellUser", for: indexPath) as? NCShareUserCell {
+                cell.indexPath = indexPath
                 cell.tableShare = tableShare
                 cell.delegate = self
                 cell.setupCellUI(userId: appDelegate.userId)

+ 6 - 0
iOSClient/Share/NCShareCommentsCell.swift

@@ -34,9 +34,15 @@ class NCShareCommentsCell: UITableViewCell, NCCellProtocol {
     @IBOutlet weak var labelDate: UILabel!
     @IBOutlet weak var labelMessage: UILabel!
 
+    private var index = IndexPath()
+
     var tableComments: tableComments?
     weak var delegate: NCShareCommentsCellDelegate?
 
+    var indexPath: IndexPath {
+        get { return index }
+        set { index = newValue }
+    }
     var fileAvatarImageView: UIImageView? {
         return imageItem
     }

+ 1 - 0
iOSClient/Share/NCShareLinkCell.swift

@@ -33,6 +33,7 @@ class NCShareLinkCell: UITableViewCell {
     var tableShare: tableShare?
     weak var delegate: NCShareLinkCellDelegate?
     var isInternalLink = false
+    var indexPath = IndexPath()
 
     override func prepareForReuse() {
         super.prepareForReuse()

+ 11 - 0
iOSClient/Share/NCShareUserCell.swift

@@ -35,9 +35,15 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol {
     @IBOutlet weak var labelQuickStatus: UILabel!
     @IBOutlet weak var imageDownArrow: UIImageView!
 
+    private var index = IndexPath()
+
     var tableShare: tableShare?
     weak var delegate: NCShareUserCellDelegate?
 
+    var indexPath: IndexPath {
+        get { return index }
+        set { index = newValue }
+    }
     var fileAvatarImageView: UIImageView? {
         return imageItem
     }
@@ -132,7 +138,12 @@ class NCSearchUserDropDownCell: DropDownCell, NCCellProtocol {
     @IBOutlet weak var centerTitle: NSLayoutConstraint!
 
     private var user: String = ""
+    private var index = IndexPath()
 
+    var indexPath: IndexPath {
+        get { return index }
+        set { index = newValue }
+    }
     var fileAvatarImageView: UIImageView? {
         return imageItem
     }

+ 15 - 6
iOSClient/Shares/NCShares.swift

@@ -49,11 +49,11 @@ class NCShares: NCCollectionViewCommon {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
-        super.reloadDataSource()
+    override func queryDB(isForced: Bool) {
 
         let sharess = NCManageDatabase.shared.getTableShares(account: self.appDelegate.account)
         var metadatas: [tableMetadata] = []
+
         for share in sharess {
             if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", self.appDelegate.account, share.serverUrl, share.fileName)) {
                 if !(metadatas.contains { $0.ocId == metadata.ocId }) {
@@ -61,6 +61,7 @@ class NCShares: NCCollectionViewCommon {
                 }
             }
         }
+
         self.dataSource = NCDataSource(metadatas: metadatas,
                                        account: self.appDelegate.account,
                                        sort: self.layoutForView?.sort,
@@ -71,14 +72,22 @@ class NCShares: NCCollectionViewCommon {
                                        groupByField: self.groupByField,
                                        providers: self.providers,
                                        searchResults: self.searchResults)
+    }
 
+    override func reloadDataSource(isForced: Bool = true) {
+        super.reloadDataSource()
 
-        self.refreshControl.endRefreshing()
-        self.collectionView.reloadData()
+        DispatchQueue.global().async {
+            self.queryDB(isForced: isForced)
+            DispatchQueue.main.async {
+                self.refreshControl.endRefreshing()
+                self.collectionView.reloadData()
+            }
+        }
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
 
         isReloadDataSourceNetworkInProgress = true
         collectionView?.reloadData()

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

@@ -945,6 +945,9 @@
 "_play_from_files_"         = "Play movie by Files";
 "_play_from_url_"           = "Play movie by URL";
 "_valid_video_url_"         = "Insert a valid URL";
+"_deletion_progess_"        = "Deletion in progress";
+"_copying_progess_"         = "Copying in progress";
+"_moving_progess_"          = "Moving in progress";
 
 // Video
 "_select_trace_"            = "Select the trace";

+ 10 - 10
iOSClient/Transfers/NCTransferCell.swift

@@ -38,9 +38,9 @@ class NCTransferCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellP
 
     private var objectId = ""
     private var user = ""
-
-    weak var delegate: NCTransferCellDelegate?
     var indexPath = IndexPath()
+    
+    weak var delegate: NCTransferCellDelegate?
     var namedButtonMore = ""
 
     var fileObjectId: String? {
@@ -109,19 +109,19 @@ class NCTransferCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellP
     }
 
     @IBAction func touchUpInsideShare(_ sender: Any) {
-        delegate?.tapShareListItem(with: objectId, sender: sender)
+        delegate?.tapShareListItem(with: objectId, indexPath: indexPath, sender: sender)
     }
 
     @IBAction func touchUpInsideMore(_ sender: Any) {
-        delegate?.tapMoreListItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, sender: sender)
+        delegate?.tapMoreListItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender)
     }
 
     @objc func longPressInsideMore(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressMoreListItem(with: objectId, namedButtonMore: namedButtonMore, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressMoreListItem(with: objectId, namedButtonMore: namedButtonMore, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     @objc func longPress(gestureRecognizer: UILongPressGestureRecognizer) {
-        delegate?.longPressListItem(with: objectId, gestureRecognizer: gestureRecognizer)
+        delegate?.longPressListItem(with: objectId, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
     }
 
     func hideButtonMore(_ status: Bool) {
@@ -146,8 +146,8 @@ class NCTransferCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellP
 }
 
 protocol NCTransferCellDelegate: AnyObject {
-    func tapShareListItem(with objectId: String, sender: Any)
-    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, sender: Any)
-    func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer)
-    func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer)
+    func tapShareListItem(with objectId: String, indexPath: IndexPath, sender: Any)
+    func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any)
+    func longPressMoreListItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
+    func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
 }

+ 11 - 7
iOSClient/Transfers/NCTransfers.swift

@@ -98,7 +98,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate {
 
     // MARK: TAP EVENT
 
-    override func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    override func longPressMoreListItem(with objectId: String, namedButtonMore: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
 
         if gestureRecognizer.state != .began { return }
 
@@ -114,7 +114,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate {
         self.present(alertController, animated: true, completion: nil)
     }
 
-    override func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {
+    override func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
 
         if gestureRecognizer.state != .began { return }
 
@@ -178,6 +178,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate {
         cell.delegate = self
 
         cell.fileObjectId = metadata.ocId
+        cell.indexPath = indexPath
         cell.fileUser = metadata.ownerId
         cell.indexPath = indexPath
         cell.imageItem.image = NCBrandColor.cacheImages.file
@@ -258,19 +259,22 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate {
 
     // MARK: - DataSource + NC Endpoint
 
-    override func reloadDataSource(forced: Bool = true) {
-        super.reloadDataSource()
+    override func queryDB(isForced: Bool) {
 
         let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "status != %i && status != %i", NCGlobal.shared.metadataStatusNormal, NCGlobal.shared.metadataStatusDownloadError), page: 1, limit: 50, sorted: "sessionTaskIdentifier", ascending: false)
         self.dataSource = NCDataSource(metadatas: metadatas, account: self.appDelegate.account)
+    }
 
+    override func reloadDataSource(isForced: Bool = true) {
+        super.reloadDataSource()
+
+        self.queryDB(isForced: isForced)
         self.refreshControl.endRefreshing()
         self.collectionView.reloadData()
     }
 
-    override func reloadDataSourceNetwork(forced: Bool = false) {
-        super.reloadDataSourceNetwork(forced: forced)
-
+    override func reloadDataSourceNetwork(isForced: Bool = false) {
+        super.reloadDataSourceNetwork(isForced: isForced)
         reloadDataSource()
     }
 }

+ 2 - 0
iOSClient/Trash/Cell/NCTrashListCell+NCTrashCellProtocol.swift

@@ -46,6 +46,7 @@ class NCTrashListCell: UICollectionViewCell, NCTrashCellProtocol {
     weak var delegate: NCTrashListCellDelegate?
 
     var objectId = ""
+    var indexPath = IndexPath()
 
     override func awakeFromNib() {
         super.awakeFromNib()
@@ -137,6 +138,7 @@ protocol NCTrashCellProtocol {
     var labelTitle: UILabel! { get set }
     var labelInfo: UILabel! { get set }
     var imageItem: UIImageView! { get set }
+    var indexPath: IndexPath { get set }
 
     func selectMode(_ status: Bool)
     func selected(_ status: Bool)

+ 1 - 0
iOSClient/Trash/NCTrash+CollectionView.swift

@@ -90,6 +90,7 @@ extension NCTrash: UICollectionViewDataSource {
             cell = gridCell
         }
 
+        cell.indexPath = indexPath
         cell.setupCellUI(tableTrash: tableTrash, image: image)
         cell.selectMode(isEditMode)
         if isEditMode {

+ 2 - 1
iOSClient/Trash/NCTrash.swift

@@ -41,6 +41,7 @@ class NCTrash: UIViewController, NCSelectableNavigationView, NCTrashListCellDele
 
     internal var isEditMode = false
     internal var selectOcId: [String] = []
+    internal var selectIndexPath: [IndexPath] = []
 
     var datasource: [tableTrash] = []
     var layoutForView: NCDBLayoutForView?
@@ -231,7 +232,7 @@ class NCTrash: UIViewController, NCSelectableNavigationView, NCTrashListCellDele
 
     // MARK: - DataSource
 
-    @objc func reloadDataSource(forced: Bool = true) {
+    @objc func reloadDataSource(isForced: Bool = true) {
 
         layoutForView = NCManageDatabase.shared.getLayoutForView(account: appDelegate.account, key: NCGlobal.shared.layoutViewTrash, serverUrl: "")
         datasource.removeAll()

+ 5 - 5
iOSClient/Viewer/NCViewer.swift

@@ -248,20 +248,20 @@ class NCViewer: NSObject {
 // MARK: - SELECT
 
 extension NCViewer: NCSelectDelegate {
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
         if let serverUrl = serverUrl {
             let metadata = items[0] as! tableMetadata
             if move {
-                NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite) { error in
+                Task {
+                    let error = await NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite)
                     if error != .success {
-
                         NCContentPresenter.shared.showError(error: error)
                     }
                 }
             } else if copy {
-                NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite) { error in
+                Task {
+                    let error = await NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrl, overwrite: overwrite)
                     if error != .success {
-
                         NCContentPresenter.shared.showError(error: error)
                     }
                 }

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

@@ -452,7 +452,7 @@ extension NCPlayerToolBar {
 
 extension NCPlayerToolBar: NCSelectDelegate {
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         if let metadata = metadata, let viewerMediaPage = viewerMediaPage {
 

+ 13 - 24
iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift

@@ -364,14 +364,11 @@ class NCViewerMediaPage: UIViewController {
 
     @objc func deleteFile(_ notification: NSNotification) {
 
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let appDelegate = UIApplication.shared.delegate as? AppDelegate,
-              let account = userInfo["account"] as? String,
-              let ocId = userInfo["ocId"] as? [String],
-              let error = userInfo["error"] as? NKError
-        else { return }
+        guard let userInfo = notification.userInfo as NSDictionary? else { return }
+
+        if let ocIds = userInfo["ocId"] as? [String],
+           let ocId = ocIds.first {
 
-        if error == .success, let ocId = ocId.first, account == appDelegate.account {
             // Stop media
             if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
                 ncplayer.playerPause()
@@ -380,11 +377,19 @@ class NCViewerMediaPage: UIViewController {
             let metadatas = self.metadatas.filter { $0.ocId != ocId }
             if self.metadatas.count == metadatas.count { return }
             self.metadatas = metadatas
-            
+
             if ocId == currentViewController.metadata.ocId {
                 shiftCurrentPage()
             }
         }
+
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
+        }
+    }
+
+    @objc func moveFile(_ notification: NSNotification) {
+        deleteFile(notification)
     }
 
     @objc func renameFile(_ notification: NSNotification) {
@@ -408,22 +413,6 @@ class NCViewerMediaPage: UIViewController {
         }
     }
 
-    @objc func moveFile(_ notification: NSNotification) {
-
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? String
-        else { return }
-
-        // Stop media
-        if let ncplayer = currentViewController.ncplayer, ncplayer.isPlay() {
-            ncplayer.playerPause()
-        }
-
-        if metadatas.firstIndex(where: {$0.ocId == ocId}) != nil {
-            deleteFile(notification)
-        }
-    }
-
     @objc func applicationDidBecomeActive(_ notification: NSNotification) {
 
         progressView.progress = 0

+ 23 - 17
iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift

@@ -25,6 +25,7 @@ import UIKit
 import PDFKit
 import EasyTipView
 import NextcloudKit
+import JGProgressHUD
 
 class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
 
@@ -353,32 +354,37 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
         self.metadata = metadata
     }
 
-    @objc func moveFile(_ notification: NSNotification) {
-
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? String,
-              ocId == self.metadata?.ocId,
-              let ocIdNew = userInfo["ocIdNew"] as? String,
-              let metadataNew = NCManageDatabase.shared.getMetadataFromOcId(ocIdNew)
-        else { return }
-
-        self.metadata = metadataNew
-    }
-
     @objc func deleteFile(_ notification: NSNotification) {
 
-        guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? [String],
-              let error = userInfo["error"] as? NKError
-        else { return }
+        guard let userInfo = notification.userInfo as NSDictionary? else { return }
 
-        if error == .success,
+        if let ocId = userInfo["ocId"] as? [String],
            let ocId = ocId.first,
            metadata?.ocId == ocId {
             viewUnload()
         }
+
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
+        }
     }
 
+    @objc func moveFile(_ notification: NSNotification) {
+
+        guard let userInfo = notification.userInfo as NSDictionary? else { return }
+
+        if let ocIds = userInfo["ocId"] as? [String],
+           let ocId = ocIds.first,
+           let metadataNew = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
+            self.metadata = metadataNew
+        }
+
+        if let hud = userInfo["hud"] as? JGProgressHUD {
+            hud.dismiss()
+        }
+    }
+
+
     @objc func renameFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,

+ 1 - 1
iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift

@@ -286,7 +286,7 @@ class NCViewerRichdocument: UIViewController, WKNavigationDelegate, WKScriptMess
 
     // MARK: -
 
-    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) {
+    func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], indexPath: [IndexPath], overwrite: Bool, copy: Bool, move: Bool) {
 
         if serverUrl != nil && metadata != nil {