Browse Source

Merge branch 'develop'

marinofaggiana 4 years ago
parent
commit
47c5c18e59
100 changed files with 2364 additions and 2429 deletions
  1. 4 4
      File Provider Extension/FileProviderData.swift
  2. 2 2
      File Provider Extension/FileProviderEnumerator.swift
  3. 1 1
      File Provider Extension/FileProviderExtension+Actions.swift
  4. 1 1
      File Provider Extension/FileProviderExtension+Thumbnail.swift
  5. 0 1
      File Provider Extension/FileProviderExtension-Bridging-Header.h
  6. 11 11
      File Provider Extension/FileProviderExtension.swift
  7. 6 6
      File Provider Extension/FileProviderItem.swift
  8. 1 1
      File Provider Extension/FileProviderUtility.swift
  9. 100 139
      Nextcloud.xcodeproj/project.pbxproj
  10. 7 7
      Nextcloud.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  11. 1 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme
  12. 1 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme
  13. 1 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Share.xcscheme
  14. 4 4
      Share/NCSelectDestination.m
  15. 0 2
      Share/ShareViewController.h
  16. 6 5
      Share/ShareViewController.m
  17. 3 19
      iOSClient/Activity/NCActivity.storyboard
  18. 5 5
      iOSClient/Activity/NCActivity.swift
  19. 6 32
      iOSClient/AppDelegate.h
  20. 51 273
      iOSClient/AppDelegate.m
  21. 1 1
      iOSClient/AudioRecorder/NCAudioRecorderViewController.swift
  22. 22 22
      iOSClient/AutoUpload/NCAutoUpload.m
  23. 2 2
      iOSClient/Brand/Intro/NCIntroViewController.swift
  24. 276 9
      iOSClient/Brand/NCBrand.swift
  25. 0 33
      iOSClient/Brand/iOSClient.plist
  26. 0 337
      iOSClient/CCGlobal.h
  27. 0 40
      iOSClient/CryptoCloud.pch
  28. 2 2
      iOSClient/Data/NCDataSource.swift
  29. 11 13
      iOSClient/Data/NCDatabase.swift
  30. 77 31
      iOSClient/Data/NCManageDatabase.swift
  31. 20 20
      iOSClient/Diagnostics/NCCapabilitiesViewController.swift
  32. 1 1
      iOSClient/EmptyView/NCEmptyDataSet.swift
  33. 0 0
      iOSClient/Extensions/NSNotificationCenter+MainThread.h
  34. 0 0
      iOSClient/Extensions/NSNotificationCenter+MainThread.m
  35. 0 0
      iOSClient/Extensions/NotificationCenter+MainThread.swift
  36. 17 9
      iOSClient/Extensions/String+Extensions.swift
  37. 52 2
      iOSClient/Extensions/UIColor+Extensions.swift
  38. 48 27
      iOSClient/Extensions/UIImage+Extensions.swift
  39. 0 0
      iOSClient/Extensions/UIImage+animatedGIF.h
  40. 0 0
      iOSClient/Extensions/UIImage+animatedGIF.m
  41. 57 0
      iOSClient/Extensions/UIImageView+Extensions.swift
  42. 7 17
      iOSClient/Favorites/NCFavorite.swift
  43. 6 7
      iOSClient/FileViewInFolder/NCFileViewInFolder.swift
  44. 11 12
      iOSClient/Files/NCFiles.swift
  45. 0 23
      iOSClient/Images.xcassets/CryptoCloud.imageset/Contents.json
  46. BIN
      iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud.png
  47. BIN
      iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud@2x.png
  48. BIN
      iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud@3x.png
  49. 0 23
      iOSClient/Images.xcassets/avatar.imageset/Contents.json
  50. BIN
      iOSClient/Images.xcassets/avatar.imageset/avatar.png
  51. BIN
      iOSClient/Images.xcassets/avatar.imageset/avatar@2x.png
  52. BIN
      iOSClient/Images.xcassets/avatar.imageset/avatar@3x.png
  53. BIN
      iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf
  54. 12 0
      iOSClient/Images.xcassets/avatarCredentials.imageset/Contents.json
  55. BIN
      iOSClient/Images.xcassets/avatarCredentials.imageset/account-circle-outline.pdf
  56. 1 1
      iOSClient/Images.xcassets/copy.imageset/Contents.json
  57. 1 0
      iOSClient/Images.xcassets/copy.imageset/copy.svg
  58. 1 1
      iOSClient/Images.xcassets/offline.imageset/Contents.json
  59. 1 0
      iOSClient/Images.xcassets/offline.imageset/archive-arrow-down-outline.svg
  60. BIN
      iOSClient/Images.xcassets/offline.imageset/offline.pdf
  61. 0 2
      iOSClient/Login/CCLogin.h
  62. 12 11
      iOSClient/Login/CCLogin.m
  63. 6 6
      iOSClient/Login/NCAppConfigView.swift
  64. 6 6
      iOSClient/Login/NCLoginWeb.swift
  65. 1 1
      iOSClient/Main/ActionSheetHeaderView/NCActionSheetHeader.swift
  66. 280 26
      iOSClient/Main/Colleaction Common/NCCollectionCommon.swift
  67. 143 304
      iOSClient/Main/Colleaction Common/NCCollectionViewCommon.swift
  68. 8 1
      iOSClient/Main/Colleaction Common/NCListCell.swift
  69. 5 5
      iOSClient/Main/Colleaction Common/NCListCell.xib
  70. 27 27
      iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift
  71. 17 13
      iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift
  72. 24 24
      iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift
  73. 13 23
      iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift
  74. 13 23
      iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift
  75. 39 64
      iOSClient/Main/Menu/AppDelegate+Menu.swift
  76. 132 56
      iOSClient/Main/Menu/NCCollectionViewCommon+Menu.swift
  77. 8 8
      iOSClient/Main/Menu/NCSortMenu.swift
  78. 105 74
      iOSClient/Main/Menu/NCViewer+Menu.swift
  79. 17 1
      iOSClient/Main/NCMainNavigationController.swift
  80. 42 12
      iOSClient/Main/NCMainTabBar.swift
  81. 9 9
      iOSClient/Main/NCPickerViewController.swift
  82. 4 4
      iOSClient/Main/Section Header Footer/NCSectionHeaderFooter.swift
  83. 58 68
      iOSClient/Media/NCMedia.swift
  84. 11 11
      iOSClient/More/NCMore.swift
  85. 121 107
      iOSClient/Networking/NCNetworking.swift
  86. 40 12
      iOSClient/Networking/NCNetworkingAutoUpload.swift
  87. 4 4
      iOSClient/Networking/NCNetworkingCheckRemoteUser.swift
  88. 27 27
      iOSClient/Networking/NCNetworkingE2EE.swift
  89. 32 52
      iOSClient/Networking/NCNetworkingNotificationCenter.swift
  90. 25 31
      iOSClient/Networking/NCOperationQueue.swift
  91. 24 26
      iOSClient/Networking/NCService.swift
  92. 2 2
      iOSClient/Nextcloud-Bridging-Header.h
  93. 5 14
      iOSClient/Notification/NCNotification.storyboard
  94. 7 7
      iOSClient/Notification/NCNotification.swift
  95. 4 5
      iOSClient/Offline/NCOffline.swift
  96. 0 39
      iOSClient/PeekPop/CCPeekPop.h
  97. 0 117
      iOSClient/PeekPop/CCPeekPop.m
  98. 0 58
      iOSClient/PeekPop/CCPeekPop.storyboard
  99. 41 0
      iOSClient/PushNotification/NCPushNotification.h
  100. 215 0
      iOSClient/PushNotification/NCPushNotification.m

+ 4 - 4
File Provider Extension/FileProviderData.swift

@@ -80,11 +80,11 @@ class fileProviderData: NSObject {
             
             guard let accountActive = NCManageDatabase.shared.getAccountActive() else { return nil }
             let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: accountActive.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-            let webDav = NCUtility.shared.getWebDAV(account: accountActive.account)
+            let webDav = NCUtilityFileSystem.shared.getWebDAV(account: accountActive.account)
             
             account = accountActive.account
             accountUrlBase = accountActive.urlBase
-            homeServerUrl = NCUtility.shared.getHomeServer(urlBase: accountActive.urlBase, account: accountActive.account)
+            homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: accountActive.urlBase, account: accountActive.account)
                         
             NCCommunicationCommon.shared.setup(account: accountActive.account, user: accountActive.user, userId: accountActive.userID, password: CCUtility.getPassword(accountActive.account), urlBase: accountActive.urlBase, userAgent: CCUtility.getUserAgent(), webDav: webDav, dav: nil, nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
             NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
@@ -103,11 +103,11 @@ class fileProviderData: NSObject {
             if accountDomain == domain!.identifier.rawValue {
                 
                 let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: accountActive.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-                let webDav = NCUtility.shared.getWebDAV(account: accountActive.account)
+                let webDav = NCUtilityFileSystem.shared.getWebDAV(account: accountActive.account)
                 
                 account = accountActive.account
                 accountUrlBase = accountActive.urlBase
-                homeServerUrl = NCUtility.shared.getHomeServer(urlBase: accountActive.urlBase, account: accountActive.account)
+                homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: accountActive.urlBase, account: accountActive.account)
                 
                 NCCommunicationCommon.shared.setup(account: accountActive.account, user: accountActive.user, userId: accountActive.userID, password: CCUtility.getPassword(accountActive.account), urlBase: accountActive.urlBase, userAgent: CCUtility.getUserAgent(), webDav: webDav, dav: nil, nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
                 NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate

+ 2 - 2
File Provider Extension/FileProviderEnumerator.swift

@@ -232,7 +232,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
                     if errorCode == 0 {
                         DispatchQueue.global().async {
                             NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in
-                                let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
+                                let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCBrandGlobal.shared.metadataStatusNormal))
                                 NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
                                 for metadata in metadatasFolder {
                                     let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView
@@ -284,7 +284,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
                     if errorCode == 0 {
                         DispatchQueue.global().async {
                             NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: account) { (metadataFolder, metadatasFolder, metadatas) in
-                                let metadatasResult = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", fileProviderData.shared.account, serverUrl, k_metadataStatusNormal), page: page, limit: fileProviderData.shared.itemForPage, sorted: "fileName", ascending: true)
+                                let metadatasResult = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", fileProviderData.shared.account, serverUrl, NCBrandGlobal.shared.metadataStatusNormal), page: page, limit: fileProviderData.shared.itemForPage, sorted: "fileName", ascending: true)
                                 NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
                                 for metadata in metadatasFolder {
                                     let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView

+ 1 - 1
File Provider Extension/FileProviderExtension+Actions.swift

@@ -33,7 +33,7 @@ extension FileProviderExtension {
             return
         }
         
-        let directoryName = NCUtility.shared.createFileName(directoryName, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
+        let directoryName = NCUtilityFileSystem.shared.createFileName(directoryName, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
         let serverUrlFileName = tableDirectory.serverUrl + "/" + directoryName
         
         NCCommunication.shared.createFolder(serverUrlFileName) { (account, ocId, date, errorCode, errorDescription) in

+ 1 - 1
File Provider Extension/FileProviderExtension+Thumbnail.swift

@@ -44,7 +44,7 @@ extension FileProviderExtension {
                 let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
                 let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
                     
-                NCCommunication.shared.getPreview(fileNamePath: fileNamePath, widthPreview: CGFloat(k_sizeIcon), heightPreview: CGFloat(k_sizeIcon)) { (account, data, errorCode, errorDescription) in
+                NCCommunication.shared.getPreview(fileNamePath: fileNamePath, widthPreview: NCBrandGlobal.shared.sizeIcon, heightPreview: NCBrandGlobal.shared.sizeIcon) { (account, data, errorCode, errorDescription) in
                     if errorCode == 0 && data != nil {
                         do {
                             try data!.write(to: URL.init(fileURLWithPath: fileNameIconLocalPath), options: .atomic)

+ 0 - 1
File Provider Extension/FileProviderExtension-Bridging-Header.h

@@ -21,5 +21,4 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-#import "CCGlobal.h"
 #import "CCUtility.h"

+ 11 - 11
File Provider Extension/FileProviderExtension.swift

@@ -118,7 +118,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             metadata.fileName = "root"
             metadata.fileNameView = "root"
             metadata.serverUrl = fileProviderData.shared.homeServerUrl
-            metadata.typeFile = k_metadataTypeFile_directory
+            metadata.typeFile = NCBrandGlobal.shared.metadataTypeFileDirectory
             
             return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue))
             
@@ -208,7 +208,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)!
         
         // Update status
-        NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: Int(k_metadataStatusDownloading))
+        NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCBrandGlobal.shared.metadataStatusDownloading)
         fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, update: true)
         
         NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath,  requestHandler: { (request) in
@@ -231,7 +231,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             
             if errorCode == 0  {
                 
-                metadata.status = Int(k_metadataStatusNormal)
+                metadata.status = NCBrandGlobal.shared.metadataStatusNormal
                 metadata.date = date ?? NSDate()
                 metadata.etag = etag ?? ""
                 
@@ -242,13 +242,13 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
                 
             } else if errorCode == 200 {
                 
-                NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: Int(k_metadataStatusNormal))
+                NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCBrandGlobal.shared.metadataStatusNormal)
                 
                 completionHandler(nil)
 
             } else {
                 
-                metadata.status = Int(k_metadataStatusDownloadError)
+                metadata.status = NCBrandGlobal.shared.metadataStatusDownloadError
                 metadata.sessionError = errorDescription
                 NCManageDatabase.shared.addMetadata(metadata)
 
@@ -316,7 +316,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             
             autoreleasepool {
             
-                var size = 0 as Double
+                var size = 0 as Int64
                 var error: NSError?
                 
                 guard let tableDirectory = fileProviderUtility.shared.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.account, homeServerUrl: fileProviderData.shared.homeServerUrl) else {
@@ -329,7 +329,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
                 // typefile directory ? (NOT PERMITTED)
                 do {
                     let attributes = try fileProviderUtility.shared.fileManager.attributesOfItem(atPath: fileURL.path)
-                    size = attributes[FileAttributeKey.size] as! Double
+                    size = attributes[FileAttributeKey.size] as! Int64
                     let typeFile = attributes[FileAttributeKey.type] as! FileAttributeType
                     if typeFile == FileAttributeType.typeDirectory {
                         completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -340,7 +340,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
                     return
                 }
         
-                let fileName = NCUtility.shared.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
+                let fileName = NCUtilityFileSystem.shared.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
                 let ocIdTemp = NSUUID().uuidString.lowercased()
                 
                 NSFileCoordinator().coordinate(readingItemAt: fileURL, options: .withoutChanges, error: &error) { (url) in
@@ -352,7 +352,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
                 let metadata = NCManageDatabase.shared.createMetadata(account: fileProviderData.shared.account, fileName: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, urlBase: fileProviderData.shared.accountUrlBase, url: "", contentType: "", livePhoto: false)
                 metadata.session = NCNetworking.shared.sessionIdentifierBackgroundExtension
                 metadata.size = size
-                metadata.status = Int(k_metadataStatusUploading)
+                metadata.status = NCBrandGlobal.shared.metadataStatusUploading
                 
                 NCManageDatabase.shared.addMetadata(metadata)
                 
@@ -400,8 +400,8 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             if let date = date { metadata.date = date }
             metadata.permissions = "RGDNVW"
             metadata.session = ""
-            metadata.size = Double(size)
-            metadata.status = Int(k_metadataStatusNormal)
+            metadata.size = size
+            metadata.status = NCBrandGlobal.shared.metadataStatusNormal
                   
             NCManageDatabase.shared.addMetadata(metadata)
             NCManageDatabase.shared.addLocalFile(metadata: metadata)

+ 6 - 6
File Provider Extension/FileProviderItem.swift

@@ -42,8 +42,8 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     
     var typeIdentifier: String {
-        let results = NCCommunicationCommon.shared.getInternalContenType(fileName: metadata.fileNameView, contentType: "", directory: metadata.directory)
-        return results.typeIdentifier
+        let results = NCCommunicationCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: "", directory: metadata.directory)
+        return results.uniformTypeIdentifier
     }
     
     var contentModificationDate: Date? {
@@ -107,7 +107,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     
     var isDownloading: Bool {
-        if metadata.status == Int(k_metadataStatusDownloading) {
+        if metadata.status == NCBrandGlobal.shared.metadataStatusDownloading {
             return true
         } else {
             return false
@@ -115,7 +115,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     
     var downloadingError: Error? {
-        if metadata.status == Int(k_metadataStatusDownloadError) {
+        if metadata.status == NCBrandGlobal.shared.metadataStatusDownloadError {
             return fileProviderData.FileProviderError.downloadError
         } else {
             return nil
@@ -131,7 +131,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     
     var isUploading: Bool {
-        if metadata.status == Int(k_metadataStatusUploading) {
+        if metadata.status == NCBrandGlobal.shared.metadataStatusUploading {
             return true
         } else {
             return false
@@ -139,7 +139,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     
     var uploadingError: Error? {
-        if metadata.status == Int(k_metadataStatusUploadError) {
+        if metadata.status == NCBrandGlobal.shared.metadataStatusUploadError {
             return fileProviderData.FileProviderError.uploadError
         } else {
             return nil

+ 1 - 1
File Provider Extension/FileProviderUtility.swift

@@ -59,7 +59,7 @@ class fileProviderUtility: NSObject {
     
     func getParentItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier? {
         
-        let homeServerUrl = NCUtility.shared.getHomeServer(urlBase: metadata.urlBase, account: metadata.account)
+        let homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: metadata.urlBase, account: metadata.account)
         if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl))  {
             if directory.serverUrl == homeServerUrl {
                 return NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue)

+ 100 - 139
Nextcloud.xcodeproj/project.pbxproj

@@ -46,7 +46,7 @@
 		F70BFC7420E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; };
 		F70BFC7520E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; };
 		F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; };
-		F70CEF5623E9C7E50007035B /* UIColor+adjust.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+adjust.swift */; };
+		F70CEF5623E9C7E50007035B /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; };
 		F70D8D8124A4A9BF000A5756 /* NCNetworkingAutoUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70D8D8024A4A9BF000A5756 /* NCNetworkingAutoUpload.swift */; };
 		F70F2BA5225F2D8900EBB73E /* ZIPFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F70F2BA4225F2D8900EBB73E /* ZIPFoundation.framework */; };
 		F710D1F52405770F00A6033D /* NCViewerPDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D1F42405770F00A6033D /* NCViewerPDF.swift */; };
@@ -55,12 +55,11 @@
 		F710D20024057E5E00A6033D /* NCActionSheetHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */; };
 		F710D2022405826100A6033D /* NCViewer+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D2012405826100A6033D /* NCViewer+Menu.swift */; };
 		F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */; };
+		F7134186259747BA00768D21 /* NCPushNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = F7134185259747BA00768D21 /* NCPushNotification.m */; };
 		F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */ = {isa = PBXBuildFile; fileRef = F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */; };
-		F71459BA1D12E3B700CAFEEC /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
 		F71459C21D12E3B700CAFEEC /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C0F46F1C8880540059EC54 /* ShareViewController.m */; };
 		F71459D21D12E3B700CAFEEC /* CCUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F7053E3D1C639DF500741EA5 /* CCUtility.m */; };
 		F71459E11D12E3B700CAFEEC /* CCHud.m in Sources */ = {isa = PBXBuildFile; fileRef = F7514EDB1C7B1336008F3338 /* CCHud.m */; };
-		F71459F71D12E3B700CAFEEC /* CCGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F76C3B841C6388BC00DC4301 /* CCGraphics.m */; };
 		F7145A041D12E3B700CAFEEC /* CCloadItemData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7296A661C8880ED001A7809 /* CCloadItemData.swift */; };
 		F7145A1A1D12E3B700CAFEEC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7F67BB81A24D27800EE80DA /* Images.xcassets */; };
 		F7145A231D12E3B700CAFEEC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F7E70DE91A24DE4100E1B66A /* Localizable.strings */; };
@@ -185,27 +184,19 @@
 		F77444F522281649000D5EB0 /* NCGridMediaCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77444F322281649000D5EB0 /* NCGridMediaCell.swift */; };
 		F77444F622281649000D5EB0 /* NCGridMediaCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F77444F422281649000D5EB0 /* NCGridMediaCell.xib */; };
 		F77444F8222816D5000D5EB0 /* NCPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77444F7222816D5000D5EB0 /* NCPickerViewController.swift */; };
-		F774DF0F1FCC26BE002AF9FC /* iTunesArtwork@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = F774DF0C1FCC26BD002AF9FC /* iTunesArtwork@1x.png */; };
-		F774DF101FCC26BE002AF9FC /* iTunesArtwork@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F774DF0D1FCC26BD002AF9FC /* iTunesArtwork@2x.png */; };
-		F774DF111FCC26BE002AF9FC /* iTunesArtwork@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F774DF0E1FCC26BE002AF9FC /* iTunesArtwork@3x.png */; };
 		F77A697D250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77A697C250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift */; };
-		F77B0DF21D118A16002130FE /* CCUploadFromOtherUpp.m in Sources */ = {isa = PBXBuildFile; fileRef = F7956FCA1B4886E60085DEA3 /* CCUploadFromOtherUpp.m */; };
 		F77B0DF51D118A16002130FE /* CCUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F7053E3D1C639DF500741EA5 /* CCUtility.m */; };
-		F77B0E1B1D118A16002130FE /* CCGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F76C3B841C6388BC00DC4301 /* CCGraphics.m */; };
 		F77B0E221D118A16002130FE /* CCManageLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = F7BFCCC11B68C21900548E76 /* CCManageLocation.m */; };
 		F77B0E301D118A16002130FE /* CCHud.m in Sources */ = {isa = PBXBuildFile; fileRef = F7514EDB1C7B1336008F3338 /* CCHud.m */; };
 		F77B0E4F1D118A16002130FE /* CCManageAutoUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F7ACE42F1BAC0268006C0017 /* CCManageAutoUpload.m */; };
 		F77B0E5F1D118A16002130FE /* NCSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = F7ACE4311BAC0268006C0017 /* NCSettings.m */; };
 		F77B0E981D118A16002130FE /* CCManageAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = F7ACE42D1BAC0268006C0017 /* CCManageAccount.m */; };
-		F77B0EA61D118A16002130FE /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
 		F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */ = {isa = PBXBuildFile; fileRef = F7ACE42A1BAC0268006C0017 /* Acknowledgements.m */; };
 		F77B0ED51D118A16002130FE /* PHAsset+Utility.m in Sources */ = {isa = PBXBuildFile; fileRef = F777F0311C29717F00CE81CB /* PHAsset+Utility.m */; };
 		F77B0ED91D118A16002130FE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F67BAD1A24D27800EE80DA /* main.m */; };
-		F77B0EFE1D118A16002130FE /* CCUploadFromOtherUpp.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7956FCB1B4886E60085DEA3 /* CCUploadFromOtherUpp.storyboard */; };
 		F77B0F611D118A16002130FE /* Acknowledgements.rtf in Resources */ = {isa = PBXBuildFile; fileRef = F7ACE42B1BAC0268006C0017 /* Acknowledgements.rtf */; };
 		F77B0F631D118A16002130FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F7E70DE91A24DE4100E1B66A /* Localizable.strings */; };
 		F77B0F7D1D118A16002130FE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7F67BB81A24D27800EE80DA /* Images.xcassets */; };
-		F77D49A91DC238E500CDC568 /* loading.gif in Resources */ = {isa = PBXBuildFile; fileRef = F77D49A71DC238E500CDC568 /* loading.gif */; };
 		F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F780710A1EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F78295311F962EFA00A572F5 /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; };
@@ -249,16 +240,21 @@
 		F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */; };
 		F79728D422F96F2E003CACA7 /* NCShareLinkFolderMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F79728D322F96F2D003CACA7 /* NCShareLinkFolderMenuView.xib */; };
 		F79728D622F9A0B1003CACA7 /* NCShareUserFolderMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F79728D522F9A0B0003CACA7 /* NCShareUserFolderMenuView.xib */; };
+		F798F0E225880608000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; };
+		F798F0E725880609000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; };
+		F798F0EC2588060A000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; };
 		F79918A221997FA300C2E308 /* UICKeyChainStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F79918A021997F9000C2E308 /* UICKeyChainStore.framework */; };
 		F79A65C32191D90F00FF6DCC /* NCSelect.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F79A65C22191D90F00FF6DCC /* NCSelect.storyboard */; };
 		F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79A65C52191D95E00FF6DCC /* NCSelect.swift */; };
+		F7A0D1352591FBC5008F8A13 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */; };
+		F7A0D1362591FBC5008F8A13 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */; };
+		F7A0D1372591FBC5008F8A13 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */; };
+		F7A0D1382591FBC5008F8A13 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */; };
+		F7A0D1462592256F008F8A13 /* UIImageView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */; };
+		F7A0D1472592256F008F8A13 /* UIImageView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */; };
+		F7A0D1482592256F008F8A13 /* UIImageView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */; };
+		F7A0D1492592256F008F8A13 /* UIImageView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */; };
 		F7A321AD1E9E6AD50069AD1B /* CCAdvanced.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */; };
-		F7A76DAA256A607100119AB3 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A76DA9256A607100119AB3 /* String+Extensions.swift */; };
-		F7A76DAF256A654D00119AB3 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A76DA9256A607100119AB3 /* String+Extensions.swift */; };
-		F7A76DB4256A654E00119AB3 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A76DA9256A607100119AB3 /* String+Extensions.swift */; };
-		F7A76DB9256A654E00119AB3 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A76DA9256A607100119AB3 /* String+Extensions.swift */; };
-		F7A76DBE256A679400119AB3 /* CCGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F76C3B841C6388BC00DC4301 /* CCGraphics.m */; };
-		F7A76DC3256A679400119AB3 /* CCGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F76C3B841C6388BC00DC4301 /* CCGraphics.m */; };
 		F7A76DC8256A71CD00119AB3 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B7504A2397D38E004E13EC /* UIImage+Extensions.swift */; };
 		F7A76DCD256A71CE00119AB3 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B7504A2397D38E004E13EC /* UIImage+Extensions.swift */; };
 		F7A76DCE256A71CF00119AB3 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B7504A2397D38E004E13EC /* UIImage+Extensions.swift */; };
@@ -301,6 +297,7 @@
 		F7E0E1DC22327885006B0911 /* NCAudioRecorderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */; };
 		F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */; };
 		F7E4D9C422ED929B003675FD /* NCShareComments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E4D9C322ED929B003675FD /* NCShareComments.swift */; };
+		F7EFA47825ADBA500083159A /* NCViewerProviderContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EFA47725ADBA500083159A /* NCViewerProviderContextMenu.swift */; };
 		F7EFC0C6256BC77700461AAD /* NCMoreUserCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7EFC0C5256BC77700461AAD /* NCMoreUserCell.xib */; };
 		F7EFC0CD256BF8DD00461AAD /* NCUserStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7EFC0CC256BF8DD00461AAD /* NCUserStatus.swift */; };
 		F7F1E54C2492369A00E42386 /* NCMediaCommandView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7F1E54B2492369A00E42386 /* NCMediaCommandView.xib */; };
@@ -311,8 +308,6 @@
 		F7F8D71D1ED6183000E711F3 /* CCCellShareExt.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7F8D71B1ED6183000E711F3 /* CCCellShareExt.xib */; };
 		F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */; };
 		F7FAC2672549E1B5008EE2C4 /* NCKTVHTTPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7FAC2662549E1B5008EE2C4 /* NCKTVHTTPCache.swift */; };
-		F7FCFFD81D70798C000E6E29 /* CCPeekPop.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7FCFFD61D70798C000E6E29 /* CCPeekPop.storyboard */; };
-		F7FCFFE01D707B83000E6E29 /* CCPeekPop.m in Sources */ = {isa = PBXBuildFile; fileRef = F7FCFFDE1D707B83000E6E29 /* CCPeekPop.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -398,7 +393,7 @@
 		F70BFC7320E0FA7C00C67599 /* NCUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCUtility.swift; sourceTree = "<group>"; };
 		F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCEndToEndEncryption.h; sourceTree = "<group>"; };
 		F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCEndToEndEncryption.m; sourceTree = "<group>"; };
-		F70CEF5523E9C7E50007035B /* UIColor+adjust.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+adjust.swift"; sourceTree = "<group>"; };
+		F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extensions.swift"; sourceTree = "<group>"; };
 		F70D8D8024A4A9BF000A5756 /* NCNetworkingAutoUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingAutoUpload.swift; sourceTree = "<group>"; };
 		F70F2BA4225F2D8900EBB73E /* ZIPFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZIPFoundation.framework; path = Carthage/Build/iOS/ZIPFoundation.framework; sourceTree = "<group>"; };
 		F710C5EF2471A6D1009AD8B7 /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = Carthage/Build/iOS/Sentry.framework; sourceTree = "<group>"; };
@@ -408,6 +403,8 @@
 		F710D1FD24057E5E00A6033D /* NCActionSheetHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCActionSheetHeaderView.xib; sourceTree = "<group>"; };
 		F710D2012405826100A6033D /* NCViewer+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCViewer+Menu.swift"; sourceTree = "<group>"; };
 		F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ImagesIntro.xcassets; sourceTree = "<group>"; };
+		F7134184259747BA00768D21 /* NCPushNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NCPushNotification.h; sourceTree = "<group>"; };
+		F7134185259747BA00768D21 /* NCPushNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NCPushNotification.m; sourceTree = "<group>"; };
 		F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+animatedGIF.h"; sourceTree = "<group>"; };
 		F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+animatedGIF.m"; sourceTree = "<group>"; };
 		F7151A811D477A4B00E6AF45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -432,7 +429,6 @@
 		F718C24D254D507B00C5C256 /* NCViewerImageDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerImageDetailView.swift; sourceTree = "<group>"; };
 		F7226EDB1EE4089300EBECB1 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
 		F722814223C8C34500C41898 /* NCRichWorkspace.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCRichWorkspace.xib; sourceTree = "<group>"; };
-		F7229B491DF71BB300E8C4E7 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS; sourceTree = SOURCE_ROOT; };
 		F723985B253C95CE00257F49 /* NCViewerRichdocument.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewerRichdocument.storyboard; sourceTree = "<group>"; };
 		F7239870253D86B600257F49 /* NCEmptyDataSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEmptyDataSet.swift; sourceTree = "<group>"; };
 		F7239876253D86D300257F49 /* NCEmptyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCEmptyView.xib; sourceTree = "<group>"; };
@@ -448,8 +444,6 @@
 		F72D1006210B6882009C96B7 /* NCPushNotificationEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCPushNotificationEncryption.h; sourceTree = "<group>"; };
 		F72D404823D2082500A97FD0 /* NCViewerNextcloudText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerNextcloudText.swift; sourceTree = "<group>"; };
 		F72E0B9C21AD60BC00898D7B /* WeScan.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WeScan.framework; path = Carthage/Build/iOS/WeScan.framework; sourceTree = "<group>"; };
-		F73049B81CB567F000C7C320 /* NSString+TruncateToWidth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+TruncateToWidth.h"; sourceTree = "<group>"; };
-		F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+TruncateToWidth.m"; sourceTree = "<group>"; };
 		F7320934201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F732093B201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F733B65121997CC1001C1FFA /* TLPhotoPicker.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TLPhotoPicker.framework; path = Carthage/Build/iOS/TLPhotoPicker.framework; sourceTree = "<group>"; };
@@ -508,7 +502,6 @@
 		F75B91F71ECAE26300199C96 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F75B923D1ECAE55E00199C96 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F75C0C4723D1FAE300163CC8 /* NCRichWorkspaceCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCRichWorkspaceCommon.swift; sourceTree = "<group>"; };
-		F75CDBF51DF063AD00116AD0 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = "<group>"; };
 		F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };
 		F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
 		F760329D252F0F8E0015A421 /* NCTransferCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NCTransferCell.swift; path = iOSClient/Transfers/NCTransferCell.swift; sourceTree = SOURCE_ROOT; };
@@ -533,8 +526,6 @@
 		F769454522E9F1B0000A798A /* NCShareCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCommon.swift; sourceTree = "<group>"; };
 		F769454722E9F20D000A798A /* NCShareNetworking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareNetworking.swift; sourceTree = "<group>"; };
 		F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCBrand.swift; sourceTree = "<group>"; };
-		F76C3B831C6388BC00DC4301 /* CCGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGraphics.h; sourceTree = "<group>"; };
-		F76C3B841C6388BC00DC4301 /* CCGraphics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCGraphics.m; sourceTree = "<group>"; };
 		F76D3CF02428B40E005DFA87 /* NCViewerPDFSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerPDFSearch.swift; sourceTree = "<group>"; };
 		F76D3CF22428B94E005DFA87 /* NCViewerPDFSearchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCViewerPDFSearchCell.xib; sourceTree = "<group>"; };
 		F76D3CF42428D0C0005DFA87 /* NCViewerPDF.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCViewerPDF.storyboard; sourceTree = "<group>"; };
@@ -575,13 +566,9 @@
 		F77444F322281649000D5EB0 /* NCGridMediaCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCGridMediaCell.swift; sourceTree = "<group>"; };
 		F77444F422281649000D5EB0 /* NCGridMediaCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCGridMediaCell.xib; sourceTree = "<group>"; };
 		F77444F7222816D5000D5EB0 /* NCPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPickerViewController.swift; sourceTree = "<group>"; };
-		F774DF0C1FCC26BD002AF9FC /* iTunesArtwork@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork@1x.png"; sourceTree = "<group>"; };
-		F774DF0D1FCC26BD002AF9FC /* iTunesArtwork@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork@2x.png"; sourceTree = "<group>"; };
-		F774DF0E1FCC26BE002AF9FC /* iTunesArtwork@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "iTunesArtwork@3x.png"; sourceTree = "<group>"; };
 		F777F0301C29717F00CE81CB /* PHAsset+Utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PHAsset+Utility.h"; sourceTree = "<group>"; };
 		F777F0311C29717F00CE81CB /* PHAsset+Utility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PHAsset+Utility.m"; sourceTree = "<group>"; };
 		F77A697C250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+Menu.swift"; sourceTree = "<group>"; };
-		F77D49A71DC238E500CDC568 /* loading.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = loading.gif; sourceTree = "<group>"; };
 		F78071071EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+MainThread.h"; sourceTree = "<group>"; };
 		F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNotificationCenter+MainThread.m"; sourceTree = "<group>"; };
 		F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EE.swift; sourceTree = "<group>"; };
@@ -610,19 +597,17 @@
 		F78F74352163781100C2ADAD /* NCTrash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrash.swift; sourceTree = "<group>"; };
 		F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerRichdocument.swift; sourceTree = "<group>"; };
 		F79018A424092EF4007C9B6D /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; };
-		F7956FC91B4886E60085DEA3 /* CCUploadFromOtherUpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCUploadFromOtherUpp.h; sourceTree = "<group>"; };
-		F7956FCA1B4886E60085DEA3 /* CCUploadFromOtherUpp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCUploadFromOtherUpp.m; sourceTree = "<group>"; };
-		F7956FCB1B4886E60085DEA3 /* CCUploadFromOtherUpp.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CCUploadFromOtherUpp.storyboard; sourceTree = "<group>"; };
 		F79728D322F96F2D003CACA7 /* NCShareLinkFolderMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareLinkFolderMenuView.xib; sourceTree = "<group>"; };
 		F79728D522F9A0B0003CACA7 /* NCShareUserFolderMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareUserFolderMenuView.xib; sourceTree = "<group>"; };
 		F79918A021997F9000C2E308 /* UICKeyChainStore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UICKeyChainStore.framework; path = Carthage/Build/iOS/UICKeyChainStore.framework; sourceTree = "<group>"; };
 		F79918A72199840500C2E308 /* Sheeeeeeeeet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sheeeeeeeeet.framework; path = Carthage/Build/iOS/Sheeeeeeeeet.framework; sourceTree = "<group>"; };
 		F79A65C22191D90F00FF6DCC /* NCSelect.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCSelect.storyboard; sourceTree = "<group>"; };
 		F79A65C52191D95E00FF6DCC /* NCSelect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSelect.swift; sourceTree = "<group>"; };
+		F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
+		F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+Extensions.swift"; sourceTree = "<group>"; };
 		F7A321AB1E9E6AD50069AD1B /* CCAdvanced.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAdvanced.h; sourceTree = "<group>"; };
 		F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCAdvanced.m; sourceTree = "<group>"; };
 		F7A582D71A24DAB500E903D7 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = "<group>"; };
-		F7A76DA9256A607100119AB3 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
 		F7A80BC8252624C100C7CD01 /* NCFileViewInFolder.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCFileViewInFolder.storyboard; sourceTree = "<group>"; };
 		F7A80BC9252624C100C7CD01 /* NCFileViewInFolder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCFileViewInFolder.swift; sourceTree = "<group>"; };
 		F7ACE4291BAC0268006C0017 /* Acknowledgements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Acknowledgements.h; sourceTree = "<group>"; };
@@ -671,7 +656,6 @@
 		F7C742C01E7BD01F00D9C973 /* iOSClient.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = iOSClient.entitlements; sourceTree = "<group>"; };
 		F7C742D01E7BD35B00D9C973 /* Share.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Share.entitlements; sourceTree = "<group>"; };
 		F7C7B488245EBA4100D93E60 /* NCViewerQuickLook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerQuickLook.swift; sourceTree = "<group>"; };
-		F7C8C1901B482CEA0048180E /* CCGlobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGlobal.h; sourceTree = "<group>"; };
 		F7C9555221F0C4CA0024296E /* NCActivity.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCActivity.storyboard; sourceTree = "<group>"; };
 		F7C9555421F0C5470024296E /* NCActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivity.swift; sourceTree = "<group>"; };
 		F7CB68992541676B0050EC94 /* NCMore.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCMore.storyboard; sourceTree = "<group>"; };
@@ -700,9 +684,9 @@
 		F7E45E6D21E75BF200579249 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7E4D9C322ED929B003675FD /* NCShareComments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareComments.swift; sourceTree = "<group>"; };
 		F7E856182351D7BE009A3330 /* SwiftyXMLParser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyXMLParser.framework; path = Carthage/Build/iOS/SwiftyXMLParser.framework; sourceTree = "<group>"; };
+		F7EFA47725ADBA500083159A /* NCViewerProviderContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerProviderContextMenu.swift; sourceTree = "<group>"; };
 		F7EFC0C5256BC77700461AAD /* NCMoreUserCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCMoreUserCell.xib; sourceTree = "<group>"; };
 		F7EFC0CC256BF8DD00461AAD /* NCUserStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCUserStatus.swift; sourceTree = "<group>"; };
-		F7F0617A1BAACDD300846525 /* CryptoCloud.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoCloud.pch; sourceTree = "<group>"; };
 		F7F1E54B2492369A00E42386 /* NCMediaCommandView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCMediaCommandView.xib; sourceTree = "<group>"; };
 		F7F35B592578FB63003F5589 /* CollaboraOnlineWebViewKeyboardManager.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CollaboraOnlineWebViewKeyboardManager.framework; path = Carthage/Build/iOS/CollaboraOnlineWebViewKeyboardManager.framework; sourceTree = "<group>"; };
 		F7F4B1D723C74B3E00D82A6E /* NCRichWorkspace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCRichWorkspace.swift; sourceTree = "<group>"; };
@@ -715,9 +699,6 @@
 		F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewer.swift; sourceTree = "<group>"; };
 		F7FAC2662549E1B5008EE2C4 /* NCKTVHTTPCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCKTVHTTPCache.swift; sourceTree = "<group>"; };
 		F7FC7D551DC1F93800BB2C6A /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
-		F7FCFFD61D70798C000E6E29 /* CCPeekPop.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CCPeekPop.storyboard; sourceTree = "<group>"; };
-		F7FCFFDD1D707B83000E6E29 /* CCPeekPop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPeekPop.h; sourceTree = "<group>"; };
-		F7FCFFDE1D707B83000E6E29 /* CCPeekPop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCPeekPop.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -849,16 +830,6 @@
 			path = Imagemeter;
 			sourceTree = "<group>";
 		};
-		F70784811A2C8A0D00AC9FFF /* UploadFromOtherUpp */ = {
-			isa = PBXGroup;
-			children = (
-				F7956FC91B4886E60085DEA3 /* CCUploadFromOtherUpp.h */,
-				F7956FCA1B4886E60085DEA3 /* CCUploadFromOtherUpp.m */,
-				F7956FCB1B4886E60085DEA3 /* CCUploadFromOtherUpp.storyboard */,
-			);
-			path = UploadFromOtherUpp;
-			sourceTree = "<group>";
-		};
 		F70F02A81C889183008DAB36 /* Libraries external */ = {
 			isa = PBXGroup;
 			children = (
@@ -890,6 +861,15 @@
 			path = Intro;
 			sourceTree = "<group>";
 		};
+		F713418B2597513800768D21 /* PushNotification */ = {
+			isa = PBXGroup;
+			children = (
+				F7134184259747BA00768D21 /* NCPushNotification.h */,
+				F7134185259747BA00768D21 /* NCPushNotification.m */,
+			);
+			path = PushNotification;
+			sourceTree = "<group>";
+		};
 		F7169A161EE590930086BD69 /* Shares */ = {
 			isa = PBXGroup;
 			children = (
@@ -996,7 +976,6 @@
 		F74D3DB81BAC1941000BAE4B /* Networking */ = {
 			isa = PBXGroup;
 			children = (
-				F7C5259A1E3B441D00FFE02C /* Notification */,
 				F75A9EE523796C6F0044CFCE /* NCNetworking.swift */,
 				F70D8D8024A4A9BF000A5756 /* NCNetworkingAutoUpload.swift */,
 				F7D96FCB246ED7E100536D73 /* NCNetworkingCheckRemoteUser.swift */,
@@ -1131,6 +1110,7 @@
 			isa = PBXGroup;
 			children = (
 				F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */,
+				F7EFA47725ADBA500083159A /* NCViewerProviderContextMenu.swift */,
 				F79018B1240962C7007C9B6D /* NCViewerImage */,
 				F7A5281B254834500039CA15 /* NCViewerVideo */,
 				F723986A253C9C0E00257F49 /* NCViewerQuickLook */,
@@ -1150,6 +1130,22 @@
 			path = Select;
 			sourceTree = "<group>";
 		};
+		F7A0D14E259229FA008F8A13 /* Extensions */ = {
+			isa = PBXGroup;
+			children = (
+				F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */,
+				F78071071EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.h */,
+				F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */,
+				F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */,
+				F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */,
+				F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */,
+				F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */,
+				F7B7504A2397D38E004E13EC /* UIImage+Extensions.swift */,
+				F7A0D1452592256F008F8A13 /* UIImageView+Extensions.swift */,
+			);
+			path = Extensions;
+			sourceTree = "<group>";
+		};
 		F7A3214D1E9E2A070069AD1B /* Favorites */ = {
 			isa = PBXGroup;
 			children = (
@@ -1283,28 +1279,16 @@
 		F7BFFA991A24D7BB0044ED85 /* Utility */ = {
 			isa = PBXGroup;
 			children = (
-				F76C3B831C6388BC00DC4301 /* CCGraphics.h */,
-				F76C3B841C6388BC00DC4301 /* CCGraphics.m */,
 				F7514EDA1C7B1336008F3338 /* CCHud.h */,
 				F7514EDB1C7B1336008F3338 /* CCHud.m */,
 				F7053E3C1C639DF500741EA5 /* CCUtility.h */,
 				F7053E3D1C639DF500741EA5 /* CCUtility.m */,
 				F78E7064219F096B006F23E4 /* NCAvatar.swift */,
 				F765608E23BF813500765969 /* NCContentPresenter.swift */,
-				F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */,
 				F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */,
 				F707C26421A2DC5200F6181E /* NCStoreReview.swift */,
 				F70BFC7320E0FA7C00C67599 /* NCUtility.swift */,
 				F74AF3A3247FB6AE00AC767B /* NCUtilityFileSystem.swift */,
-				F78071071EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.h */,
-				F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */,
-				F73049B81CB567F000C7C320 /* NSString+TruncateToWidth.h */,
-				F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */,
-				F70CEF5523E9C7E50007035B /* UIColor+adjust.swift */,
-				F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */,
-				F713FEFF2472764100214AF6 /* UIImage+animatedGIF.m */,
-				F7B7504A2397D38E004E13EC /* UIImage+Extensions.swift */,
-				F7A76DA9256A607100119AB3 /* String+Extensions.swift */,
 			);
 			path = Utility;
 			sourceTree = "<group>";
@@ -1348,7 +1332,6 @@
 				F73B422A2476764F00A30FD3 /* NCNotification.swift */,
 			);
 			name = Notification;
-			path = ..;
 			sourceTree = "<group>";
 		};
 		F7C742D31E7BD36600D9C973 /* Supporting Files */ = {
@@ -1468,7 +1451,6 @@
 				F70211F31BAC56E9003FC03E /* Main */,
 				F7A582D71A24DAB500E903D7 /* AppDelegate.h */,
 				F7B174C722FAC0A8000B7579 /* AppDelegate.m */,
-				F7C8C1901B482CEA0048180E /* CCGlobal.h */,
 				F7F67BB81A24D27800EE80DA /* Images.xcassets */,
 				F7A321621E9E37960069AD1B /* Activity */,
 				F7E0E1DA22327885006B0911 /* AudioRecorder */,
@@ -1485,8 +1467,9 @@
 				F7EC9CB921185F2000F1C5CE /* Media */,
 				F7CB68942541670D0050EC94 /* More */,
 				F74D3DB81BAC1941000BAE4B /* Networking */,
+				F7C5259A1E3B441D00FFE02C /* Notification */,
 				F7381ED9218218A4000B1560 /* Offline */,
-				F7FCFFD51D70798C000E6E29 /* PeekPop */,
+				F713418B2597513800768D21 /* PushNotification */,
 				F765F72E25237E3F00391DBE /* Recent */,
 				F7CADB3D23CCDDA1000EEC78 /* RichWorkspace */,
 				F758B41E212C516300515F55 /* ScanDocument */,
@@ -1497,8 +1480,8 @@
 				F7169A161EE590930086BD69 /* Shares */,
 				F7E9C41320F4CA870040CF18 /* Transfers */,
 				F78F74322163753B00C2ADAD /* Trash */,
-				F70784811A2C8A0D00AC9FFF /* UploadFromOtherUpp */,
 				F7EFC0CB256BF89300461AAD /* UserStatus */,
+				F7A0D14E259229FA008F8A13 /* Extensions */,
 				F7BFFA991A24D7BB0044ED85 /* Utility */,
 				F79630EC215526B60015EEA5 /* Viewer */,
 			);
@@ -1509,13 +1492,6 @@
 			isa = PBXGroup;
 			children = (
 				F72B60941A24F04E004EF66F /* Localizations */,
-				F75CDBF51DF063AD00116AD0 /* .gitignore */,
-				F774DF0C1FCC26BD002AF9FC /* iTunesArtwork@1x.png */,
-				F774DF0D1FCC26BD002AF9FC /* iTunesArtwork@2x.png */,
-				F774DF0E1FCC26BE002AF9FC /* iTunesArtwork@3x.png */,
-				F7229B491DF71BB300E8C4E7 /* AUTHORS */,
-				F7F0617A1BAACDD300846525 /* CryptoCloud.pch */,
-				F77D49A71DC238E500CDC568 /* loading.gif */,
 				F7F67BAD1A24D27800EE80DA /* main.m */,
 				F7D154271E2392A300202FD9 /* Nextcloud-Bridging-Header.h */,
 			);
@@ -1602,16 +1578,6 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
-		F7FCFFD51D70798C000E6E29 /* PeekPop */ = {
-			isa = PBXGroup;
-			children = (
-				F7FCFFDD1D707B83000E6E29 /* CCPeekPop.h */,
-				F7FCFFDE1D707B83000E6E29 /* CCPeekPop.m */,
-				F7FCFFD61D70798C000E6E29 /* CCPeekPop.storyboard */,
-			);
-			path = PeekPop;
-			sourceTree = "<group>";
-		};
 		F7FE125B1BAC03FB0041924B /* Security */ = {
 			isa = PBXGroup;
 			children = (
@@ -1728,7 +1694,7 @@
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 1130;
-				LastUpgradeCheck = 1200;
+				LastUpgradeCheck = 1230;
 				ORGANIZATIONNAME = "Marino Faggiana";
 				TargetAttributes = {
 					2C33C47E23E2C475005F963B = {
@@ -1872,7 +1838,6 @@
 				F79728D422F96F2E003CACA7 /* NCShareLinkFolderMenuView.xib in Resources */,
 				F7362A1F220C853A005101B5 /* LaunchScreen.storyboard in Resources */,
 				F75ADF451DC75FFE008A7347 /* CCLogin.storyboard in Resources */,
-				F77D49A91DC238E500CDC568 /* loading.gif in Resources */,
 				F77444F622281649000D5EB0 /* NCGridMediaCell.xib in Resources */,
 				F78ACD4421903CF20088454D /* NCListCell.xib in Resources */,
 				F78ACD4621903D010088454D /* NCGridCell.xib in Resources */,
@@ -1884,8 +1849,6 @@
 				F723985C253C95CE00257F49 /* NCViewerRichdocument.storyboard in Resources */,
 				F758B45A212C564000515F55 /* Scan.storyboard in Resources */,
 				F765F73225237E3F00391DBE /* NCRecent.storyboard in Resources */,
-				F77B0EFE1D118A16002130FE /* CCUploadFromOtherUpp.storyboard in Resources */,
-				F7FCFFD81D70798C000E6E29 /* CCPeekPop.storyboard in Resources */,
 				F78F74342163757000C2ADAD /* NCTrash.storyboard in Resources */,
 				F79A65C32191D90F00FF6DCC /* NCSelect.storyboard in Resources */,
 				F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */,
@@ -1919,7 +1882,6 @@
 				F79728D622F9A0B1003CACA7 /* NCShareUserFolderMenuView.xib in Resources */,
 				F7DFAA8A22E22EF100FC4527 /* NCShareLinkMenuView.xib in Resources */,
 				F7C9555321F0C4CA0024296E /* NCActivity.storyboard in Resources */,
-				F774DF0F1FCC26BE002AF9FC /* iTunesArtwork@1x.png in Resources */,
 				F78ACD54219047D40088454D /* NCSectionFooter.xib in Resources */,
 				F704B5E32430AA6F00632F5F /* NCCreateFormUploadConflict.storyboard in Resources */,
 				F77B0F611D118A16002130FE /* Acknowledgements.rtf in Resources */,
@@ -1935,10 +1897,8 @@
 				F73CB3B222E072A000AD728E /* NCShareHeaderView.xib in Resources */,
 				F7AE00FA230E81EB007ACF8A /* NCBrowserWeb.storyboard in Resources */,
 				F78ACD58219048040088454D /* NCSectionHeaderMenu.xib in Resources */,
-				F774DF101FCC26BE002AF9FC /* iTunesArtwork@2x.png in Resources */,
 				F7501C322212E57500FB1415 /* NCMedia.storyboard in Resources */,
 				F74DE14425135B6800917068 /* NCTransfers.storyboard in Resources */,
-				F774DF111FCC26BE002AF9FC /* iTunesArtwork@3x.png in Resources */,
 				F7CB68A0254169530050EC94 /* NCSettings.storyboard in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1987,17 +1947,18 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				F7A76DB9256A654E00119AB3 /* String+Extensions.swift in Sources */,
+				F7A0D1492592256F008F8A13 /* UIImageView+Extensions.swift in Sources */,
 				F785EEA52461A4CF00B3F945 /* CCUtility.m in Sources */,
 				2C1D5D7923E2DE9100334ABB /* NCBrand.swift in Sources */,
 				F7A76DCE256A71CF00119AB3 /* UIImage+Extensions.swift in Sources */,
 				2C1D5D7523E2DE3300334ABB /* NCDatabase.swift in Sources */,
+				F7A0D1382591FBC5008F8A13 /* String+Extensions.swift in Sources */,
 				2C1D5D7623E2DE3300334ABB /* NCManageDatabase.swift in Sources */,
 				2C33C48223E2C475005F963B /* NotificationService.swift in Sources */,
 				F73D5E4A246DE09200DF6467 /* NCElementsJSON.swift in Sources */,
+				F798F0EC2588060A000DAFFD /* UIColor+Extensions.swift in Sources */,
 				F74AF3A7247FB6AE00AC767B /* NCUtilityFileSystem.swift in Sources */,
 				2CB7D1CA23E2EDCB00376EF9 /* NCPushNotificationEncryption.m in Sources */,
-				F7A76DC3256A679400119AB3 /* CCGraphics.m in Sources */,
 				F782FDC424E6933900666099 /* NCUtility.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -2006,12 +1967,13 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				F71459BA1D12E3B700CAFEEC /* NSString+TruncateToWidth.m in Sources */,
-				F7A76DAF256A654D00119AB3 /* String+Extensions.swift in Sources */,
 				F73D5E48246DE09200DF6467 /* NCElementsJSON.swift in Sources */,
+				F7A0D1362591FBC5008F8A13 /* String+Extensions.swift in Sources */,
+				F7A0D1472592256F008F8A13 /* UIImageView+Extensions.swift in Sources */,
 				F70460532499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
 				F71459C21D12E3B700CAFEEC /* ShareViewController.m in Sources */,
 				F70BFC7520E0FA7D00C67599 /* NCUtility.swift in Sources */,
+				F798F0E225880608000DAFFD /* UIColor+Extensions.swift in Sources */,
 				F78295311F962EFA00A572F5 /* NCEndToEndEncryption.m in Sources */,
 				F74AF3A5247FB6AE00AC767B /* NCUtilityFileSystem.swift in Sources */,
 				F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */,
@@ -2020,7 +1982,6 @@
 				F71459E11D12E3B700CAFEEC /* CCHud.m in Sources */,
 				F765609023BF813600765969 /* NCContentPresenter.swift in Sources */,
 				F75A9EE723796C6F0044CFCE /* NCNetworking.swift in Sources */,
-				F71459F71D12E3B700CAFEEC /* CCGraphics.m in Sources */,
 				F7A76DC8256A71CD00119AB3 /* UIImage+Extensions.swift in Sources */,
 				F7BAADC91ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
 				F780710A1EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */,
@@ -2039,16 +2000,17 @@
 				F76673F022C90434007ED366 /* FileProviderUtility.swift in Sources */,
 				F7434B3420E23FD700417916 /* NCDatabase.swift in Sources */,
 				F7434B3820E2400600417916 /* NCBrand.swift in Sources */,
-				F7A76DBE256A679400119AB3 /* CCGraphics.m in Sources */,
 				F785EE9E2461A09900B3F945 /* NCNetworking.swift in Sources */,
 				F771E3D320E2392D00AFB62D /* FileProviderExtension.swift in Sources */,
 				F73D5E49246DE09200DF6467 /* NCElementsJSON.swift in Sources */,
 				F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */,
 				F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */,
+				F798F0E725880609000DAFFD /* UIColor+Extensions.swift in Sources */,
+				F7A0D1482592256F008F8A13 /* UIImageView+Extensions.swift in Sources */,
 				F70460542499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
 				F785EEA42461A4A600B3F945 /* NCUtility.swift in Sources */,
 				F771E3F320E239A600AFB62D /* FileProviderData.swift in Sources */,
-				F7A76DB4256A654E00119AB3 /* String+Extensions.swift in Sources */,
+				F7A0D1372591FBC5008F8A13 /* String+Extensions.swift in Sources */,
 				F771E3D720E2392D00AFB62D /* FileProviderEnumerator.swift in Sources */,
 				F74AF3A6247FB6AE00AC767B /* NCUtilityFileSystem.swift in Sources */,
 				F7A76DCD256A71CE00119AB3 /* UIImage+Extensions.swift in Sources */,
@@ -2061,7 +2023,6 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				F77B0DF21D118A16002130FE /* CCUploadFromOtherUpp.m in Sources */,
 				F77444F522281649000D5EB0 /* NCGridMediaCell.swift in Sources */,
 				F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */,
 				F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */,
@@ -2089,13 +2050,11 @@
 				F70753F12542A9A200972D44 /* NCViewerImageZoom.swift in Sources */,
 				F7A80BCB252624C100C7CD01 /* NCFileViewInFolder.swift in Sources */,
 				F78A18B823CDE2B300F681F3 /* NCViewerRichWorkspace.swift in Sources */,
-				F7A76DAA256A607100119AB3 /* String+Extensions.swift in Sources */,
 				F78A18B623CDD07D00F681F3 /* NCViewerRichWorkspaceWebView.swift in Sources */,
 				F75A9EE623796C6F0044CFCE /* NCNetworking.swift in Sources */,
 				F758B460212C56A400515F55 /* ScanCollectionView.swift in Sources */,
 				F78ACD52219046DC0088454D /* NCSectionHeaderFooter.swift in Sources */,
 				F749C10C23C4A5340027D966 /* NCIntroViewController.swift in Sources */,
-				F77B0E1B1D118A16002130FE /* CCGraphics.m in Sources */,
 				F710D2022405826100A6033D /* NCViewer+Menu.swift in Sources */,
 				3757A35523D9D76300EC369E /* NCMenuPanelController.swift in Sources */,
 				F77A697D250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift in Sources */,
@@ -2112,12 +2071,12 @@
 				F76673ED22C901F6007ED366 /* FileProviderDomain.swift in Sources */,
 				F7A321AD1E9E6AD50069AD1B /* CCAdvanced.m in Sources */,
 				F77B0E4F1D118A16002130FE /* CCManageAutoUpload.m in Sources */,
-				F7FCFFE01D707B83000E6E29 /* CCPeekPop.m in Sources */,
 				F7BAADC81ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
 				F75C0C4823D1FAE300163CC8 /* NCRichWorkspaceCommon.swift in Sources */,
 				F78ACD4A21903F850088454D /* NCTrashListCell.swift in Sources */,
 				F760329F252F0F8E0015A421 /* NCTransferCell.swift in Sources */,
 				F7682FE023C36B0500983A04 /* NCMainTabBar.swift in Sources */,
+				F7A0D1352591FBC5008F8A13 /* String+Extensions.swift in Sources */,
 				F77B0E5F1D118A16002130FE /* NCSettings.m in Sources */,
 				F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */,
 				F70460522499061800BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
@@ -2136,6 +2095,7 @@
 				F7C1EEA525053A9C00866ACC /* NCDataSource.swift in Sources */,
 				F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */,
 				F7B174C822FAC0A8000B7579 /* AppDelegate.m in Sources */,
+				F7A0D1462592256F008F8A13 /* UIImageView+Extensions.swift in Sources */,
 				F749C10B23C4A5340027D966 /* NCIntroCollectionViewCell.swift in Sources */,
 				F718C24E254D507B00C5C256 /* NCViewerImageDetailView.swift in Sources */,
 				F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */,
@@ -2145,13 +2105,14 @@
 				F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */,
 				F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */,
 				F77B0E981D118A16002130FE /* CCManageAccount.m in Sources */,
+				F7EFA47825ADBA500083159A /* NCViewerProviderContextMenu.swift in Sources */,
 				F755BD9B20594AC7008C5FBB /* NCService.swift in Sources */,
 				F7B7504B2397D38F004E13EC /* UIImage+Extensions.swift in Sources */,
-				F77B0EA61D118A16002130FE /* NSString+TruncateToWidth.m in Sources */,
 				F7EFC0CD256BF8DD00461AAD /* NCUserStatus.swift in Sources */,
 				F7DFB7F4219C5CA800680748 /* NCCreateFormUploadScanDocument.swift in Sources */,
 				F710D1FF24057E5E00A6033D /* NCActionSheetHeaderView.swift in Sources */,
 				F7020FCE2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift in Sources */,
+				F7134186259747BA00768D21 /* NCPushNotification.m in Sources */,
 				F7F4B1D823C74B3E00D82A6E /* NCRichWorkspace.swift in Sources */,
 				F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */,
 				F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */,
@@ -2173,7 +2134,7 @@
 				F7725A60251F33BB00D125E0 /* NCFiles.swift in Sources */,
 				F704B5E52430AA8000632F5F /* NCCreateFormUploadConflict.swift in Sources */,
 				F765608F23BF813600765969 /* NCContentPresenter.swift in Sources */,
-				F70CEF5623E9C7E50007035B /* UIColor+adjust.swift in Sources */,
+				F70CEF5623E9C7E50007035B /* UIColor+Extensions.swift in Sources */,
 				F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */,
 				F7C7B489245EBA4100D93E60 /* NCViewerQuickLook.swift in Sources */,
 				F758B45E212C569D00515F55 /* ScanCell.swift in Sources */,
@@ -2281,7 +2242,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2289,7 +2250,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu11;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2297,14 +2258,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/Notification_Service_Extension.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
@@ -2336,7 +2297,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2344,7 +2305,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu11;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2352,14 +2313,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/Notification_Service_Extension.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.Notification-Service-Extension";
@@ -2383,7 +2344,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2391,7 +2352,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2399,14 +2360,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/Share.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2431,7 +2392,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2439,7 +2400,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2447,14 +2408,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/Share.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2485,7 +2446,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2493,7 +2454,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu11;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2501,14 +2462,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/File_Provider_Extension.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2539,7 +2500,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2547,7 +2508,7 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_C_LANGUAGE_STANDARD = gnu11;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"$(inherited)",
 					EXTENSION,
@@ -2555,14 +2516,14 @@
 				);
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/File_Provider_Extension.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2585,7 +2546,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/iOSClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2593,19 +2554,19 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/iOSClient.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				OTHER_SWIFT_FLAGS = "";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)";
@@ -2634,7 +2595,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 30;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2642,18 +2603,18 @@
 					"$(PROJECT_DIR)/Carthage/Build/iOS",
 				);
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
-				GCC_PREFIX_HEADER = iOSClient/CryptoCloud.pch;
+				GCC_PREFIX_HEADER = "";
 				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
 				HEADER_SEARCH_PATHS = "\"Libraries external\"/**";
 				INFOPLIST_FILE = "$(SRCROOT)/iOSClient/Brand/iOSClient.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
 				LIBRARY_SEARCH_PATHS = "";
-				MARKETING_VERSION = 3.1.0;
+				MARKETING_VERSION = 3.2.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2718,7 +2679,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = (
@@ -2777,7 +2738,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_LDFLAGS = (
 					"-Obj-C",
@@ -2848,7 +2809,7 @@
 			repositoryURL = "https://github.com/realm/realm-cocoa";
 			requirement = {
 				kind = exactVersion;
-				version = 10.2.0;
+				version = 10.5.1;
 			};
 		};
 		F786D58B253454BF00E3DD7B /* XCRemoteSwiftPackageReference "ios-communication-library" */ = {
@@ -2856,7 +2817,7 @@
 			repositoryURL = "https://github.com/nextcloud/ios-communication-library/";
 			requirement = {
 				kind = exactVersion;
-				version = 0.85.0;
+				version = 0.89.0;
 			};
 		};
 		F7C4D88B2534887E00C142DA /* XCRemoteSwiftPackageReference "Parchment" */ = {

+ 7 - 7
Nextcloud.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -15,8 +15,8 @@
         "repositoryURL": "https://github.com/nextcloud/ios-communication-library/",
         "state": {
           "branch": null,
-          "revision": "2adb1b594afd7c48eea57b30c987297c1fe7b8bc",
-          "version": "0.85.0"
+          "revision": "20718e68531d8c96fad838a1794a14996064e34d",
+          "version": "0.89.0"
         }
       },
       {
@@ -33,17 +33,17 @@
         "repositoryURL": "https://github.com/realm/realm-cocoa",
         "state": {
           "branch": null,
-          "revision": "7094961907423ae3f0050c21b91d871393cb3f1f",
-          "version": "10.2.0"
+          "revision": "4274b9c8ba717d7a81c953c34b715d5f587fa92f",
+          "version": "10.5.1"
         }
       },
       {
-        "package": "RealmCore",
+        "package": "RealmDatabase",
         "repositoryURL": "https://github.com/realm/realm-core",
         "state": {
           "branch": null,
-          "revision": "596fe8985a2bcdf3c6ecb0a7a8712b9ac5480c79",
-          "version": "10.1.3"
+          "revision": "8af0f8d609491986b49f2c986e771d9dc445664d",
+          "version": "10.3.3"
         }
       },
       {

+ 1 - 1
Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1200"
+   LastUpgradeVersion = "1230"
    wasCreatedForAppExtension = "YES"
    version = "2.0">
    <BuildAction

+ 1 - 1
Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1200"
+   LastUpgradeVersion = "1230"
    version = "1.7">
    <BuildAction
       parallelizeBuildables = "YES"

+ 1 - 1
Nextcloud.xcodeproj/xcshareddata/xcschemes/Share.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1200"
+   LastUpgradeVersion = "1230"
    wasCreatedForAppExtension = "YES"
    version = "2.0">
    <BuildAction

+ 4 - 4
Share/NCSelectDestination.m

@@ -69,7 +69,7 @@
     
     if (![_serverUrl length]) {
                 
-        _serverUrl = [[NCUtility shared] getHomeServerWithUrlBase:urlBase account:account];
+        _serverUrl = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:urlBase account:account];
         
         [self.navigationController.navigationBar.topItem setTitleView:[[UIImageView alloc] initWithImage: [UIImage imageNamed:@"themingLogo"]]];
         self.title = @"Home";
@@ -255,11 +255,11 @@
     if (metadata.directory) {
     
         if (metadata.e2eEncrypted)
-            cell.imageView.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"folderEncrypted"] multiplier:2 color:NCBrandColor.shared.brandElement];
+            cell.imageView.image = [[UIImage imageNamed:@"folderEncrypted"] imageWithColor:NCBrandColor.shared.brandElement size:50];
         else if ([metadata.fileName isEqualToString:_autoUploadFileName] && [self.serverUrl isEqualToString:_autoUploadDirectory])
-            cell.imageView.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"folderAutomaticUpload"] multiplier:2 color:NCBrandColor.shared.brandElement];
+            cell.imageView.image = [[UIImage imageNamed:@"folderAutomaticUpload"] imageWithColor:NCBrandColor.shared.brandElement size:50];
         else
-            cell.imageView.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"folder"] multiplier:2 color:NCBrandColor.shared.brandElement];
+            cell.imageView.image = [[UIImage imageNamed:@"folder"] imageWithColor:NCBrandColor.shared.brandElement size:50];
         
     } else {
         

+ 0 - 2
Share/ShareViewController.h

@@ -23,8 +23,6 @@
 
 #import <MBProgressHUD/MBProgressHUD.h>
 
-#import "CCGlobal.h"
-#import "CCGraphics.h"
 #import "CCCellShareExt.h"
 #import "NCSelectDestination.h"
 #import "CCHud.h"

+ 6 - 5
Share/ShareViewController.m

@@ -62,7 +62,7 @@
     } else {
         
         NSInteger serverVersionMajor = [[NCManageDatabase shared] getCapabilitiesServerIntWithAccount:tableAccount.account elements:NCElementsJSON.shared.capabilitiesVersionMajor];
-        NSString *webDav = [[NCUtility shared] getWebDAVWithAccount:tableAccount.account];
+        NSString *webDav = [[NCUtilityFileSystem shared] getWebDAVWithAccount:tableAccount.account];
         
         // Networking
         [[NCCommunicationCommon shared] setupWithAccount:tableAccount.account user:tableAccount.user userId:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] urlBase:tableAccount.urlBase userAgent:[CCUtility getUserAgent] webDav:webDav dav:nil nextcloudVersion:serverVersionMajor delegate:[NCNetworking shared]];
@@ -84,7 +84,7 @@
             
             [CCUtility setAccountExt:self.account];
 
-            _serverUrl  = [[NCUtility shared] getHomeServerWithUrlBase:tableAccount.urlBase account:tableAccount.account];
+            _serverUrl  = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:tableAccount.urlBase account:tableAccount.account];
             [CCUtility setServerUrlExt:_serverUrl];
 
             _destinyFolderButton.title = [NSString stringWithFormat:NSLocalizedString(@"_destiny_folder_", nil), NSLocalizedString(@"_home_", nil)];
@@ -180,8 +180,9 @@
         NSString *themingColor = [[NCManageDatabase shared] getCapabilitiesServerStringWithAccount:self.account elements:NCElementsJSON.shared.capabilitiesThemingColor];
         NSString *themingColorElement = [[NCManageDatabase shared] getCapabilitiesServerStringWithAccount:self.account elements:NCElementsJSON.shared.capabilitiesThemingColorElement];
         NSString *themingColorText = [[NCManageDatabase shared] getCapabilitiesServerStringWithAccount:self.account elements:NCElementsJSON.shared.capabilitiesThemingColorText];
-        [CCGraphics settingThemingColor:themingColor themingColorElement:themingColorElement themingColorText:themingColorText];
+        [NCBrandColor.shared settingBrandColor:themingColor themingColorElement:themingColorElement themingColorText:themingColorText];
     }
+    
     self.navigationController.navigationBar.barTintColor = NCBrandColor.shared.brand;
     self.navigationController.navigationBar.tintColor = NCBrandColor.shared.brandText;
     
@@ -269,7 +270,7 @@
         
         // <--
         
-        NSString *fileNameForUpload = [[NCUtility shared] createFileName:fileName serverUrl:self.serverUrl account:self.account];
+        NSString *fileNameForUpload = [[NCUtilityFileSystem shared] createFileName:fileName serverUrl:self.serverUrl account:self.account];
         NSString *fileNameServer = [NSString stringWithFormat:@"%@/%@", self.serverUrl, fileNameForUpload];
         
         [[NCCommunication shared] uploadWithServerUrlFileName:fileNameServer fileNameLocalPath:fileNameLocal dateCreationFile:nil dateModificationFile:nil customUserAgent:nil addCustomHeaders:nil taskHandler:^(NSURLSessionTask *task) {
@@ -411,7 +412,7 @@
     else if (UTTypeConformsTo(fileUTI, kUTTypeImage)) {
         image = [UIImage imageWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingString:fileName]];
         if (image) {
-            image = [NCUtility.shared resizeImageWithImage:image toHeight:cell.frame.size.width];
+            image = [image resizeImageWithSize:CGSizeMake(100, 100) isAspectRation:true];
         } else {
             image = [UIImage imageNamed:@"file_photo"];
         }

+ 3 - 19
iOSClient/Activity/NCActivity.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX">
     <device id="retina5_9" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -33,20 +33,12 @@
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
-                                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="LQ8-cO-794" userLabel="avatar" customClass="NCAvatar" customModule="Nextcloud" customModuleProvider="target">
+                                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LQ8-cO-794" userLabel="avatar" customClass="NCAvatar" customModule="Nextcloud" customModuleProvider="target">
                                                     <rect key="frame" x="50" y="0.0" width="30" height="30"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="30" id="OKz-e8-DzD"/>
                                                         <constraint firstAttribute="height" constant="30" id="fwd-J4-5uY"/>
                                                     </constraints>
-                                                    <userDefinedRuntimeAttributes>
-                                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                                            <integer key="value" value="1"/>
-                                                        </userDefinedRuntimeAttribute>
-                                                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                                            <color key="value" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                                        </userDefinedRuntimeAttribute>
-                                                    </userDefinedRuntimeAttributes>
                                                 </imageView>
                                                 <imageView userInteractionEnabled="NO" alpha="0.59999999999999998" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xNG-sf-PnA">
                                                     <rect key="frame" x="20" y="5" width="20" height="20"/>
@@ -139,12 +131,4 @@
             <point key="canvasLocation" x="-330.39999999999998" y="139.65517241379311"/>
         </scene>
     </scenes>
-    <designables>
-        <designable name="LQ8-cO-794">
-            <size key="intrinsicContentSize" width="25" height="25"/>
-        </designable>
-    </designables>
-    <resources>
-        <image name="avatar" width="25" height="25"/>
-    </resources>
 </document>

+ 5 - 5
iOSClient/Activity/NCActivity.swift

@@ -60,7 +60,7 @@ class NCActivity: UIViewController, NCEmptyDataSetDelegate {
         tableView.tableFooterView = UIView()
         tableView.contentInset = insets
         
-        NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
@@ -94,7 +94,7 @@ class NCActivity: UIViewController, NCEmptyDataSetDelegate {
     
     func emptyDataSetView(_ view: NCEmptyView) {
         
-        view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "activity"), width: 300, height: 300, color: .gray)
+        view.emptyImage.image = UIImage.init(named: "activity")?.image(color: .gray, size: UIScreen.main.bounds.width)
         view.emptyTitle.text = NSLocalizedString("_no_activity_", comment: "")
         view.emptyDescription.text = ""
     }
@@ -228,7 +228,7 @@ extension NCActivity: UITableViewDataSource {
                     }
                 } else {
                     DispatchQueue.global().async {
-                        NCCommunication.shared.downloadAvatar(userID: activity.user, fileNameLocalPath: fileNameLocalPath, size: Int(k_avatar_size)) { (account, data, errorCode, errorMessage) in
+                        NCCommunication.shared.downloadAvatar(userID: activity.user, fileNameLocalPath: fileNameLocalPath, size: NCBrandGlobal.shared.avatarSize) { (account, data, errorCode, errorMessage) in
                             if errorCode == 0 && account == self.appDelegate.account && UIImage(data: data!) != nil {
                                 cell.avatar.image = UIImage(data: data!)
                             }
@@ -348,7 +348,7 @@ extension activityTableViewCell: UICollectionViewDelegate {
                         viewController.trashPath = result.filePath
                         (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
                     } else {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                     }
                 }
             }
@@ -382,7 +382,7 @@ extension activityTableViewCell: UICollectionViewDelegate {
             var pathComponents = activityPreview.link.components(separatedBy: "?")
             pathComponents = pathComponents[1].components(separatedBy: "&")
             var serverUrlFileName = pathComponents[0].replacingOccurrences(of: "dir=", with: "").removingPercentEncoding!
-            serverUrlFileName = appDelegate.urlBase + "/" + NCUtility.shared.getWebDAV(account: activityPreview.account) + serverUrlFileName + "/" + activitySubjectRich.name
+            serverUrlFileName = appDelegate.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: activityPreview.account) + serverUrlFileName + "/" + activitySubjectRich.name
             
             let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(activitySubjectRich.id, fileNameView: activitySubjectRich.name)!
             

+ 6 - 32
iOSClient/AppDelegate.h

@@ -23,12 +23,9 @@
 
 #import <Foundation/Foundation.h>
 #import <UserNotifications/UserNotifications.h>
-#import <PushKit/PushKit.h>
 #import <AVKit/AVKit.h>
 #import <LocalAuthentication/LocalAuthentication.h>
 #import <TOPasscodeViewController/TOPasscodeViewController.h>
-
-#import "CCUtility.h"
 #import "CCLogin.h"
 
 @class NCFiles;
@@ -50,12 +47,8 @@
 
 @interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
 
-// Timer Process
-@property (nonatomic, strong) NSTimer *timerUpdateApplicationIconBadgeNumber;
-@property (nonatomic, strong) NSTimer *timerErrorNetworking;
-
 @property (nonatomic, strong) UIWindow *window;
-@property (nonatomic, strong) NCDocumentPickerViewController *documentPickerViewController;
+@property (nonatomic, copy) void (^backgroundSessionCompletionHandler)(void);
 
 // Parameter account
 @property (nonatomic, strong) NSString *account;
@@ -64,20 +57,6 @@
 @property (nonatomic, strong) NSString *userID;
 @property (nonatomic, strong) NSString *password;
 
-// Networking 
-@property (nonatomic, copy) void (^backgroundSessionCompletionHandler)(void);
-
-// UploadFromOtherUpp
-@property (nonatomic, strong) NSString *fileNameUpload;
-
-// Passcode lockDirectory
-@property (nonatomic, strong) NSDate *sessionePasscodeLock;
-
-// Push Norification Token
-@property (nonatomic, strong) NSString *pushKitToken;
-
-@property (nonatomic, retain) TOPasscodeViewController *passcodeViewController;
-
 @property (nonatomic, retain) NSString *activeServerUrl;
 @property (nonatomic, retain) UIViewController *activeViewController;
 
@@ -102,17 +81,16 @@
 @property (nonatomic, strong) NSMutableDictionary *listOfflineVC;
 @property (nonatomic, strong) NSMutableDictionary *listProgressMetadata;
 
+@property (nonatomic, strong) NSTimer *timerErrorNetworking;
+@property (nonatomic, strong) NCDocumentPickerViewController *documentPickerViewController;
 @property (nonatomic) UIUserInterfaceStyle preferredUserInterfaceStyle API_AVAILABLE(ios(12.0));
-
-// Shares
 @property (nonatomic, strong) NSArray *shares;
 @property BOOL disableSharesView;
-
-// UserDefaults
 @property (nonatomic, strong) NSUserDefaults *ncUserDefaults;
-
-// Network Auto Upload
 @property (nonatomic, strong) NCNetworkingAutoUpload *networkingAutoUpload;
+@property (nonatomic, retain) TOPasscodeViewController *passcodeViewController;
+
+@property (nonatomic, strong) NSMutableArray *pasteboardOcIds;
 
 // Login
 - (void)startTimerErrorNetworking;
@@ -121,10 +99,6 @@
 // Setting Account & Communication
 - (void)settingAccount:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user userID:(NSString *)userID password:(NSString *)password;
 - (void)deleteAccount:(NSString *)account wipe:(BOOL)wipe;
-- (void)settingSetupCommunication:(NSString *)account;
-
-// Push Notification
-- (void)pushNotification;
 
 @end
 

+ 51 - 273
iOSClient/AppDelegate.m

@@ -22,10 +22,10 @@
 //
 
 #import "AppDelegate.h"
-#import "CCGraphics.h"
 #import "NCBridgeSwift.h"
 #import "NCAutoUpload.h"
-#import "NCPushNotificationEncryption.h"
+#import "NSNotificationCenter+MainThread.h"
+#import "NCPushNotification.h"
 #import <QuartzCore/QuartzCore.h>
 
 @import Firebase;
@@ -67,8 +67,7 @@
         [[NCCommunicationCommon shared] writeLog:[NSString stringWithFormat:@"Start session with level %lu %@", (unsigned long)logLevel, versionNextcloudiOS]];
     }
     
-    //
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initializeMain:) name:k_notificationCenter_initializeMain object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initializeMain:) name:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil];
     
     // Set account, if no exists clear all
     tableAccount *tableAccount = [[NCManageDatabase shared] getAccountActive];
@@ -100,6 +99,8 @@
     self.listFilesVC = [NSMutableDictionary new];
     self.listFavoriteVC = [NSMutableDictionary new];
     self.listOfflineVC = [NSMutableDictionary new];
+    
+    self.pasteboardOcIds = [NSMutableArray new];
 
     // Push Notification
     [application registerForRemoteNotifications];
@@ -114,7 +115,6 @@
     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
     
     // Start Timer
-    self.timerUpdateApplicationIconBadgeNumber = [NSTimer scheduledTimerWithTimeInterval:k_timerUpdateApplicationIconBadgeNumber target:self selector:@selector(updateApplicationIconBadgeNumber) userInfo:nil repeats:YES];
     [self startTimerErrorNetworking];
 
     // Store review
@@ -138,8 +138,8 @@
     if ([NCBrandOptions shared].disable_intro) {
         [CCUtility setIntro:YES];
         
-        if (self.account.length == 0) {
-            [self openLoginView:nil selector:k_intro_login openLoginWeb:false];
+        if (self.account == nil || self.account.length == 0) {
+            [self openLoginView:nil selector:NCBrandGlobal.shared.introLogin openLoginWeb:false];
         }
         
     } else {
@@ -154,7 +154,7 @@
     }
 
     // init home
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
 
     // Passcode
     dispatch_async(dispatch_get_main_queue(), ^{
@@ -172,7 +172,7 @@
 //
 - (void)applicationWillResignActive:(UIApplication *)application
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
     
     // Dismiss FileViewInFolder
     if (self.activeFileViewInFolder != nil ) {
@@ -180,8 +180,6 @@
             self.activeFileViewInFolder = nil;
         }];
     }
-    
-    [self updateApplicationIconBadgeNumber];
 }
 
 //
@@ -189,9 +187,9 @@
 //
 - (void)applicationWillEnterForeground:(UIApplication *)application
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
     
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_applicationWillEnterForeground object:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterApplicationWillEnterForeground object:nil];
     
     // Request Passcode
     [self passcodeWithAutomaticallyPromptForBiometricValidation:true];
@@ -200,13 +198,13 @@
     [[NCAutoUpload shared] initStateAutoUpload];
     
     // Read active directory
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_reloadDataSourceNetworkForced object:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterReloadDataSourceNetworkForced object:nil];
     
     // Required unsubscribing / subscribing
-    [self pushNotification];
+    [[NCPushNotification shared] pushNotification];
     
     // RichDocument
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_richdocumentGrabFocus object:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterRichdocumentGrabFocus object:nil];
     
     // Request Service Server Nextcloud
     [[NCService shared] startRequestServicesServer];
@@ -217,7 +215,7 @@
 //
 - (void)applicationDidBecomeActive:(UIApplication *)application
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
         
     // Brand
     #if defined(HC)
@@ -239,9 +237,9 @@
 //
 - (void)applicationDidEnterBackground:(UIApplication *)application
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
 
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_applicationDidEnterBackground object:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterApplicationDidEnterBackground object:nil];
     
     [self passcodeWithAutomaticallyPromptForBiometricValidation:false];
 }
@@ -257,7 +255,7 @@
 // NotificationCenter
 - (void)initializeMain:(NSNotification *)notification
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
     
     // Clear error certificate
     [CCUtility setCertificateError:self.account error:NO];
@@ -266,7 +264,7 @@
     [[NCBrandColor shared] settingThemingColorWithAccount:self.account];
     
     // close detail
-    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_menuDetailClose object:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterMenuDetailClose object:nil];
     
     // Not Photos Video in library ? then align and Init Auto Upload
     NSArray *recordsPhotoLibrary = [[NCManageDatabase shared] getPhotoLibraryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", self.account]];
@@ -281,7 +279,7 @@
     [[NCService shared] startRequestServicesServer];
     
     // Registeration push notification
-    [self pushNotification];
+    [[NCPushNotification shared] pushNotification];
     
     // Registeration domain File Provider
     //FileProviderDomain *fileProviderDomain = [FileProviderDomain new];
@@ -291,18 +289,16 @@
     [[NCCommunicationCommon shared] writeLog:@"initialize Main"];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Login / checkErrorNetworking =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark Login / checkErrorNetworking
 
 - (void)checkErrorNetworking
 {
-    if (self.account.length == 0) { return; }
+    if (self.account == nil || self.account.length == 0) { return; }
     
     // check unauthorized server (401)
     if ([CCUtility getPassword:self.account].length == 0) {
         
-        [self openLoginView:self.window.rootViewController selector:k_intro_login openLoginWeb:true];
+        [self openLoginView:self.window.rootViewController selector:NCBrandGlobal.shared.introLogin openLoginWeb:true];
     }
     
     // check certificate untrusted (-1202)
@@ -354,13 +350,13 @@
     }
     
     // normal login
-    if (selector == k_intro_signup) {
+    if (selector == NCBrandGlobal.shared.introSignup) {
         
         if (!(_activeLoginWeb.isViewLoaded && _activeLoginWeb.view.window)) {
             
             self.activeLoginWeb = [[UIStoryboard storyboardWithName:@"CCLogin" bundle:nil] instantiateViewControllerWithIdentifier:@"NCLoginWeb"];
             
-            if (selector == k_intro_signup) {
+            if (selector == NCBrandGlobal.shared.introSignup) {
                 self.activeLoginWeb.urlBase = [[NCBrandOptions shared] linkloginPreferredProviders];
             } else {
                 self.activeLoginWeb.urlBase = self.urlBase;
@@ -429,12 +425,10 @@
 
 - (void)startTimerErrorNetworking
 {
-    self.timerErrorNetworking = [NSTimer scheduledTimerWithTimeInterval:k_timerErrorNetworking target:self selector:@selector(checkErrorNetworking) userInfo:nil repeats:YES];
+    self.timerErrorNetworking = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(checkErrorNetworking) userInfo:nil repeats:YES];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Account & Communication =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark Account & Communication
 
 - (void)settingAccount:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user userID:(NSString *)userID password:(NSString *)password
 {
@@ -447,14 +441,21 @@
     (void)[NCNetworkingNotificationCenter shared];
 
     [[NCCommunicationCommon shared] setupWithAccount:account user:user userId:userID password:password urlBase:urlBase];
-    [self settingSetupCommunication:account];
+    
+    NSInteger serverVersionMajor = [[NCManageDatabase shared] getCapabilitiesServerIntWithAccount:account elements:NCElementsJSON.shared.capabilitiesVersionMajor];
+    if (serverVersionMajor > 0) {
+        [[NCCommunicationCommon shared] setupWithNextcloudVersion:serverVersionMajor];
+    }
+    
+    [[NCCommunicationCommon shared] setupWithWebDav:[[NCUtilityFileSystem shared] getWebDAVWithAccount:account]];
+    [[NCCommunicationCommon shared] setupWithDav:[[NCUtilityFileSystem shared] getDAV]];
 }
 
 - (void)deleteAccount:(NSString *)account wipe:(BOOL)wipe
 {
     // Push Notification
     tableAccount *accountPN = [[NCManageDatabase shared] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", account]];
-    [self unsubscribingNextcloudServerPushNotification:accountPN.account urlBase:accountPN.urlBase user:accountPN.user withSubscribing:false];
+    [[NCPushNotification shared] unsubscribingNextcloudServerPushNotification:accountPN.account urlBase:accountPN.urlBase user:accountPN.user withSubscribing:false];
 
     [self settingAccount:nil urlBase:nil user:nil userID:nil password:nil];
     
@@ -477,112 +478,17 @@
             NSString *newAccount = listAccount[0];
             tableAccount *tableAccount = [[NCManageDatabase shared] setAccountActive:newAccount];
             [self settingAccount:newAccount urlBase:tableAccount.urlBase user:tableAccount.user userID:tableAccount.userID password:[CCUtility getPassword:tableAccount.account]];
-            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
         } else {
-            [self openLoginView:self.window.rootViewController selector:k_intro_login openLoginWeb:false];
+            [self openLoginView:self.window.rootViewController selector:NCBrandGlobal.shared.introLogin openLoginWeb:false];
         }
     }
 }
 
-- (void)settingSetupCommunication:(NSString *)account
-{
-    NSInteger serverVersionMajor = [[NCManageDatabase shared] getCapabilitiesServerIntWithAccount:account elements:NCElementsJSON.shared.capabilitiesVersionMajor];
-    if (serverVersionMajor > 0) {
-        [[NCCommunicationCommon shared] setupWithNextcloudVersion:serverVersionMajor];
-    }
-    
-    [[NCCommunicationCommon shared] setupWithWebDav:[[NCUtility shared] getWebDAVWithAccount:account]];
-    [[NCCommunicationCommon shared] setupWithDav:[[NCUtility shared] getDAV]];
-}
-
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Push Notifications =====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)pushNotification
-{
-    if (self.account.length == 0 || self.pushKitToken.length == 0) { return; }
-    
-    for (tableAccount *result in [[NCManageDatabase shared] getAllAccount]) {
-        
-        NSString *token = [CCUtility getPushNotificationToken:result.account];
-        
-        if (![token isEqualToString:self.pushKitToken]) {
-            if (token != nil) {
-                // unsubscribing + subscribing
-                [self unsubscribingNextcloudServerPushNotification:result.account urlBase:result.urlBase user:result.user withSubscribing:true];
-            } else {
-                [self subscribingNextcloudServerPushNotification:result.account urlBase:result.urlBase user:result.user];
-            }
-        }
-    }
-}
-
-- (void)subscribingNextcloudServerPushNotification:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user
-{
-    if (self.account.length == 0 || self.pushKitToken.length == 0) { return; }
-    
-    [[NCPushNotificationEncryption shared] generatePushNotificationsKeyPair:account];
-
-    NSString *pushTokenHash = [[NCEndToEndEncryption sharedManager] createSHA512:self.pushKitToken];
-    NSData *pushPublicKey = [CCUtility getPushNotificationPublicKey:account];
-    NSString *pushDevicePublicKey = [[NSString alloc] initWithData:pushPublicKey encoding:NSUTF8StringEncoding];
-    NSString *proxyServerPath = [NCBrandOptions shared].pushNotificationServerProxy;
-    
-    [[NCCommunication shared] subscribingPushNotificationWithServerUrl:urlBase account:account user:user password:[CCUtility getPassword:account] pushTokenHash:pushTokenHash devicePublicKey:pushDevicePublicKey proxyServerUrl:proxyServerPath customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSString *deviceIdentifier, NSString *signature, NSString *publicKey, NSInteger errorCode, NSString *errorDescription) {
-        if (errorCode == 0) {
-            NSString *userAgent = [NSString stringWithFormat:@"%@  (Strict VoIP)", [CCUtility getUserAgent]];
-            [[NCCommunication shared] subscribingPushProxyWithProxyServerUrl:proxyServerPath pushToken:self.pushKitToken deviceIdentifier:deviceIdentifier signature:signature publicKey:publicKey userAgent:userAgent completionHandler:^(NSInteger errorCode, NSString *errorDescription) {
-                if (errorCode == 0) {
-                    
-                    [[NCCommunicationCommon shared] writeLog:@"Subscribed to Push Notification server & proxy successfully"];
-
-                    [CCUtility setPushNotificationToken:account token:self.pushKitToken];
-                    [CCUtility setPushNotificationDeviceIdentifier:account deviceIdentifier:deviceIdentifier];
-                    [CCUtility setPushNotificationDeviceIdentifierSignature:account deviceIdentifierSignature:signature];
-                    [CCUtility setPushNotificationSubscribingPublicKey:account publicKey:publicKey];
-                }
-            }];
-        }
-    }];
-}
-
-- (void)unsubscribingNextcloudServerPushNotification:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user withSubscribing:(BOOL)subscribing
-{
-    if (self.account.length == 0) { return; }
-    
-    NSString *deviceIdentifier = [CCUtility getPushNotificationDeviceIdentifier:account];
-    NSString *signature = [CCUtility getPushNotificationDeviceIdentifierSignature:account];
-    NSString *publicKey = [CCUtility getPushNotificationSubscribingPublicKey:account];
-
-    [[NCCommunication shared] unsubscribingPushNotificationWithServerUrl:urlBase account:account user:user password:[CCUtility getPassword:account] customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) {
-        if (errorCode == 0) {
-            NSString *userAgent = [NSString stringWithFormat:@"%@  (Strict VoIP)", [CCUtility getUserAgent]];
-            NSString *proxyServerPath = [NCBrandOptions shared].pushNotificationServerProxy;
-            [[NCCommunication shared] unsubscribingPushProxyWithProxyServerUrl:proxyServerPath deviceIdentifier:deviceIdentifier signature:signature publicKey:publicKey userAgent:userAgent completionHandler:^(NSInteger errorCode, NSString *errorDescription) {
-                if (errorCode == 0) {
-                
-                    [[NCCommunicationCommon shared] writeLog:@"Unsubscribed to Push Notification server & proxy successfully."];
-                    
-                    [CCUtility setPushNotificationPublicKey:account data:nil];
-                    [CCUtility setPushNotificationSubscribingPublicKey:account publicKey:nil];
-                    [CCUtility setPushNotificationPrivateKey:account data:nil];
-                    [CCUtility setPushNotificationToken:account token:nil];
-                    [CCUtility setPushNotificationDeviceIdentifier:account deviceIdentifier:nil];
-                    [CCUtility setPushNotificationDeviceIdentifierSignature:account deviceIdentifierSignature:nil];
-                    
-                    if (self.pushKitToken != nil && subscribing) {
-                        [self subscribingNextcloudServerPushNotification:account urlBase:urlBase user:user];
-                    }
-                }
-            }];
-        }
-    }];
-}
+#pragma mark Push Notifications
 
 -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
 {
-    //Called when a notification is delivered to a foreground app.
     completionHandler(UNNotificationPresentationOptionAlert);
 }
 
@@ -593,121 +499,21 @@
 
 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
 {
-    self.pushKitToken = [self stringWithDeviceToken:deviceToken];
-
-    [self pushNotification];
+    [[NCPushNotification shared] registerForRemoteNotificationsWithDeviceToken:deviceToken];
 }
 
 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
 {
-    NSString *message = [userInfo objectForKey:@"subject"];
-    if (message) {
-        NSArray *results = [[NCManageDatabase shared] getAllAccount];
-        for (tableAccount *result in results) {
-            if ([CCUtility getPushNotificationPrivateKey:result.account]) {
-                NSData *decryptionKey = [CCUtility getPushNotificationPrivateKey:result.account];
-                NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:decryptionKey];
-                if (decryptedMessage) {
-                    NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
-                    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
-                    NSInteger nid = [[json objectForKey:@"nid"] integerValue];
-                    BOOL delete = [[json objectForKey:@"delete"] boolValue];
-                    BOOL deleteAll = [[json objectForKey:@"delete-all"] boolValue];
-                    if (delete) {
-                        [self removeNotificationWithNotificationId:nid usingDecryptionKey:decryptionKey];
-                    } else if (deleteAll) {
-                        [self cleanAllNotifications];
-                    }
-                }
-            }
-        }
-    }
-    completionHandler(UIBackgroundFetchResultNoData);
-}
-
-- (void)cleanAllNotifications
-{
-    [[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
-}
-
-- (void)removeNotificationWithNotificationId:(NSInteger)notificationId usingDecryptionKey:(NSData *)key
-{
-    // Check in pending notifications
-    [[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
-        for (UNNotificationRequest *notificationRequest in requests) {
-            NSString *message = [notificationRequest.content.userInfo objectForKey:@"subject"];
-            NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:key];
-            if (decryptedMessage) {
-                NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
-                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
-                NSInteger nid = [[json objectForKey:@"nid"] integerValue];
-                if (nid == notificationId) {
-                    [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[notificationRequest.identifier]];
-                }
-            }
-        }
-    }];
-    // Check in delivered notifications
-    [[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
-        for (UNNotification *notification in notifications) {
-            NSString *message = [notification.request.content.userInfo objectForKey:@"subject"];
-            NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:key];
-            if (decryptedMessage) {
-                NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
-                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
-                NSInteger nid = [[json objectForKey:@"nid"] integerValue];
-                if (nid == notificationId) {
-                    [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notification.request.identifier]];
-                }
-            }
-        }
+    [[NCPushNotification shared] applicationdidReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+        completionHandler(result);
     }];
 }
 
-- (NSString *)stringWithDeviceToken:(NSData *)deviceToken
-{
-    const char *data = [deviceToken bytes];
-    NSMutableString *token = [NSMutableString string];
-    
-    for (NSUInteger i = 0; i < [deviceToken length]; i++) {
-        [token appendFormat:@"%02.2hhX", data[i]];
-    }
-    
-    return [token copy];
-}
-
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== ApplicationIconBadgeNumber =====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)updateApplicationIconBadgeNumber
-{
-    if (self.account.length == 0) { return; }
-            
-    NSInteger counterDownload = [[NCOperationQueue shared] downloadCount];
-    NSInteger counterUpload = [[NCManageDatabase shared] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d OR status == %d OR status == %d", k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading]].count;
-    NSInteger total = counterDownload + counterUpload;
-    
-    [UIApplication sharedApplication].applicationIconBadgeNumber = total;
-    
-    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
-    if ([tabBarController isKindOfClass:[UITabBarController class]]) {
-        UITabBarItem *tabBarItem = [tabBarController.tabBar.items objectAtIndex:0];
-        if (total > 0) {
-            [tabBarItem setBadgeValue:[NSString stringWithFormat:@"%li", (unsigned long)total]];
-        } else {
-            [tabBarItem setBadgeValue:nil];
-        }
-    }
-}
-
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Fetch =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark Fetch
 
 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
 {
-    if (self.account.length == 0) {
+    if (self.account == nil || self.account.length == 0) {
         completionHandler(UIBackgroundFetchResultNoData);
         return;
     }
@@ -724,9 +530,7 @@
     });
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Operation Networking & Session =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark Operation Networking & Session
 
 //
 // Method called by the system when all the background task has end
@@ -734,9 +538,7 @@
 - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler
 {
     [[NCCommunicationCommon shared] writeLog:[NSString stringWithFormat:@"Start handle Events For Background URLSession: %@", identifier]];
-    
-    [self updateApplicationIconBadgeNumber];
-    
+        
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
         self.backgroundSessionCompletionHandler = completionHandler;
         void (^completionHandler)() = self.backgroundSessionCompletionHandler;
@@ -745,14 +547,11 @@
     });
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== OpenURL  =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark OpenURL
 
-// Method called from iOS system to send a file from other app.
 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
 {
-    if (self.account.length == 0) { return YES; }
+    if (self.account == nil || self.account.length == 0) { return YES; }
     
     NSString *scheme = url.scheme;
     NSString *fileName;
@@ -794,14 +593,14 @@
                             if ([link containsString:accountURL.host] && [user isEqualToString:accountUser]) {
                                 matchedAccount = [[NCManageDatabase shared] setAccountActive:account.account];
                                 [self settingAccount:matchedAccount.account urlBase:matchedAccount.urlBase user:matchedAccount.user userID:matchedAccount.userID password:[CCUtility getPassword:matchedAccount.account]];
-                                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+                                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
                             }
                         }
                     }
                     
                     if (matchedAccount) {
                         
-                        NSString *webDAV = [[NCUtility shared] getWebDAVWithAccount:self.account];
+                        NSString *webDAV = [[NCUtilityFileSystem shared] getWebDAVWithAccount:self.account];
 
                         if ([path containsString:@"/"]) {
 
@@ -834,31 +633,10 @@
         return YES;
     }
     
-    NSError *error;
-    NSLog(@"[LOG] the path is: %@", url.path);
-        
-    NSArray *splitedUrl = [url.path componentsSeparatedByString:@"/"];
-    self.fileNameUpload = [NSString stringWithFormat:@"%@",[splitedUrl objectAtIndex:([splitedUrl count]-1)]];
-    
-    if (self.account && [[NSFileManager defaultManager] fileExistsAtPath:url.path]) {
-        
-        [[NSFileManager defaultManager] removeItemAtPath:[NSTemporaryDirectory() stringByAppendingString:self.fileNameUpload] error:nil];
-        [[NSFileManager defaultManager] moveItemAtPath:url.path toPath:[NSTemporaryDirectory() stringByAppendingString:self.fileNameUpload] error:&error];
-        
-        if (error == nil) {
-            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
-                UIViewController *uploadNavigationViewController = [[UIStoryboard storyboardWithName:@"CCUploadFromOtherUpp" bundle:nil] instantiateViewControllerWithIdentifier:@"CCUploadNavigationViewController"];
-                [self.window.rootViewController presentViewController:uploadNavigationViewController animated:YES completion:nil];
-            });
-        }
-    }
-    
     return YES;
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Passcode + Delegate =====
-#pragma --------------------------------------------------------------------------------------------
+#pragma mark Passcode + Delegate
 
 - (void)passcodeWithAutomaticallyPromptForBiometricValidation:(BOOL)automaticallyPromptForBiometricValidation
 {

+ 1 - 1
iOSClient/AudioRecorder/NCAudioRecorderViewController.swift

@@ -131,7 +131,7 @@ class NCAudioRecorderViewController: UIViewController , NCAudioRecorderDelegate
         voiceRecordHUD.update(CGFloat(rate))
         voiceRecordHUD.fillColor = UIColor.green
         recordDuration += 1
-        durationLabel.text = NCUtility.shared.formatSecondsToString(recordDuration/60)
+        durationLabel.text =  String.init().formatSecondsToString(recordDuration/60)
     }
 }
 

+ 22 - 22
iOSClient/AutoUpload/NCAutoUpload.m

@@ -321,14 +321,14 @@
 - (void)uploadNewAssets
 {
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
-        [self uploadAssetsNewAndFull:selectorUploadAutoUpload];
+        [self uploadAssetsNewAndFull:NCBrandGlobal.shared.selectorUploadAutoUpload];
     });
 }
 
 - (void)uploadFullAssets
 {
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
-        [self uploadAssetsNewAndFull:selectorUploadAutoUploadAll];
+        [self uploadAssetsNewAndFull:NCBrandGlobal.shared.selectorUploadAutoUploadAll];
     });
 }
 
@@ -361,19 +361,19 @@
     }
     
     dispatch_async(dispatch_get_main_queue(), ^{
-        if ([selector isEqualToString:selectorUploadAutoUploadAll]) {
+        if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
             if (!_hud)
                 _hud = [[CCHud alloc] initWithView:[[[UIApplication sharedApplication] delegate] window]];
         
-            [[NCContentPresenter shared] messageNotification:@"_attention_" description:@"_create_full_upload_" delay:k_dismissAfterSecondLong type:messageTypeInfo errorCode:0 forced:true];
+            [[NCContentPresenter shared] messageNotification:@"_attention_" description:@"_create_full_upload_" delay:[[NCBrandGlobal shared] dismissAfterSecondLong] type:messageTypeInfo errorCode:0 forced:true];
             [_hud visibleHudTitle:NSLocalizedString(@"_wait_", nil) mode:MBProgressHUDModeIndeterminate color:nil];
         }
     });
     
     // Create the folder for auto upload & if request the subfolders
     if ([[NCNetworking shared] createFolderWithAssets:newAssetToUpload selector:selector useSubFolder:tableAccount.autoUploadCreateSubfolder account:appDelegate.account urlBase:appDelegate.urlBase]) {
-        if ([selector isEqualToString:selectorUploadAutoUploadAll]) {        
-            [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_error_createsubfolders_upload_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true];
+        if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
+            [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_error_createsubfolders_upload_" delay:[[NCBrandGlobal shared] dismissAfterSecond] type:messageTypeError errorCode:NCBrandGlobal.shared.ErrorInternalError forced:true];
             dispatch_async(dispatch_get_main_queue(), ^{
                 [_hud hideHud];
             });
@@ -389,7 +389,7 @@
         NSDate *assetDate = asset.creationDate;
         PHAssetMediaType assetMediaType = asset.mediaType;
         NSString *session;
-        NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameAutoUploadMask keyFileNameType:k_keyFileNameAutoUploadType keyFileNameOriginal:k_keyFileNameOriginalAutoUpload];
+        NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:NCBrandGlobal.shared.keyFileNameAutoUploadMask keyFileNameType:NCBrandGlobal.shared.keyFileNameAutoUploadType keyFileNameOriginal:NCBrandGlobal.shared.keyFileNameOriginalAutoUpload];
 
         // Detect LivePhoto Upload
         if ((asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive || asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive+PHAssetMediaSubtypePhotoHDR) && CCUtility.getLivePhoto) {
@@ -397,7 +397,7 @@
         }
         
         // Select type of session
-        if ([selector isEqualToString:selectorUploadAutoUploadAll]) {
+        if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
             session = NCCommunicationCommon.shared.sessionIdentifierUpload;
         } else {
             if (assetMediaType == PHAssetMediaTypeImage && tableAccount.autoUploadWWAnPhoto == NO) session = NCNetworking.shared.sessionIdentifierBackground;
@@ -423,7 +423,7 @@
         tableMetadata *metadata = [[NCManageDatabase shared] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView == %@", appDelegate.account, serverUrl, fileName]];
         if (metadata) {
             
-            if ([selector isEqualToString:selectorUploadAutoUpload]) {
+            if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUpload]) {
                 [[NCManageDatabase shared] addPhotoLibrary:@[asset] account:appDelegate.account];
             }
             
@@ -437,20 +437,20 @@
             metadataForUpload.session = session;
             metadataForUpload.sessionSelector = selector;
             metadataForUpload.size = [[NCUtilityFileSystem shared] getFileSizeWithAsset:asset];
-            metadataForUpload.status = k_metadataStatusWaitUpload;
+            metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload;
             if (assetMediaType == PHAssetMediaTypeVideo) {
-                metadataForUpload.typeFile = k_metadataTypeFile_video;
+                metadataForUpload.typeFile = NCBrandGlobal.shared.metadataTypeFileVideo;
             } else if (assetMediaType == PHAssetMediaTypeImage) {
-                metadataForUpload.typeFile = k_metadataTypeFile_image;
+                metadataForUpload.typeFile = NCBrandGlobal.shared.metadataTypeFileImage;
             }
             
-            if ([selector isEqualToString:selectorUploadAutoUpload]) {
+            if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUpload]) {
                
                 [[NCManageDatabase shared] addMetadataForAutoUpload:metadataForUpload];
                 [[NCCommunicationCommon shared] writeLog:[NSString stringWithFormat:@"Automatic upload added %@ (%lu bytes) with Identifier %@", metadata.fileNameView, (unsigned long)metadata.size, metadata.assetLocalIdentifier]];
                 [[NCManageDatabase shared] addPhotoLibrary:@[asset] account:appDelegate.account];
                 
-            } else if ([selector isEqualToString:selectorUploadAutoUploadAll]) {
+            } else if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
                 
                 [metadataFull addObject:metadataForUpload];
             }
@@ -473,22 +473,22 @@
                         metadataMOVForUpload.session = session;
                         metadataMOVForUpload.sessionSelector = selector;
                         metadataMOVForUpload.size = fileSize;
-                        metadataMOVForUpload.status = k_metadataStatusWaitUpload;
-                        metadataMOVForUpload.typeFile = k_metadataTypeFile_video;
+                        metadataMOVForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload;
+                        metadataMOVForUpload.typeFile = NCBrandGlobal.shared.metadataTypeFileVideo;
 
-                        if ([selector isEqualToString:selectorUploadAutoUpload]) {
+                        if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUpload]) {
                             
                             [[NCManageDatabase shared] addMetadataForAutoUpload:metadataMOVForUpload];
                             [[NCCommunicationCommon shared] writeLog:[NSString stringWithFormat:@"Automatic upload added Live Photo %@ (%llu bytes)", fileNameMove, fileSize]];
                             
-                        } else if ([selector isEqualToString:selectorUploadAutoUploadAll]) {
+                        } else if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
                             
                             [metadataFull addObject:metadataMOVForUpload];
                         }
                     }
                     counterLivePhoto--;
                     dispatch_async(dispatch_get_main_queue(), ^{
-                        if (endForAssetToUpload && counterLivePhoto == 0 && [selector isEqualToString:selectorUploadAutoUploadAll]) {
+                        if (endForAssetToUpload && counterLivePhoto == 0 && [selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
                             [[NCManageDatabase shared] addMetadatas:metadataFull];
                             [_hud hideHud];
                         }
@@ -500,7 +500,7 @@
     endForAssetToUpload = true;
     
     dispatch_async(dispatch_get_main_queue(), ^{
-        if (counterLivePhoto == 0 && [selector isEqualToString:selectorUploadAutoUploadAll]) {
+        if (counterLivePhoto == 0 && [selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUploadAll]) {
             [[NCManageDatabase shared] addMetadatas:metadataFull];
             [_hud hideHud];
         }
@@ -552,7 +552,7 @@
             
             PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
             
-            if ([selector isEqualToString:selectorUploadAutoUpload]) {
+            if ([selector isEqualToString:NCBrandGlobal.shared.selectorUploadAutoUpload]) {
             
                 NSString *creationDate;
                 NSString *idAsset;
@@ -589,7 +589,7 @@
 {
     tableAccount *account = [[NCManageDatabase shared] getAccountActive];
 
-    NSArray *assets = [self getCameraRollAssets:account selector:selectorUploadAutoUploadAll alignPhotoLibrary:YES];
+    NSArray *assets = [self getCameraRollAssets:account selector:NCBrandGlobal.shared.selectorUploadAutoUploadAll alignPhotoLibrary:YES];
    
     [[NCManageDatabase shared] clearTable:[tablePhotoLibrary class] account:appDelegate.account];
     if (assets != nil) {

+ 2 - 2
iOSClient/Brand/Intro/NCIntroViewController.swift

@@ -163,11 +163,11 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
     }
 
     @IBAction func login(_ sender: Any) {
-        (UIApplication.shared.delegate as! AppDelegate).openLoginView(navigationController, selector: Int(k_intro_login), openLoginWeb: false)
+        (UIApplication.shared.delegate as! AppDelegate).openLoginView(navigationController, selector: NCBrandGlobal.shared.introLogin, openLoginWeb: false)
     }
 
     @IBAction func signup(_ sender: Any) {
-        (UIApplication.shared.delegate as! AppDelegate).openLoginView(navigationController, selector: Int(k_intro_signup), openLoginWeb: false)
+        (UIApplication.shared.delegate as! AppDelegate).openLoginView(navigationController, selector: NCBrandGlobal.shared.introSignup, openLoginWeb: false)
     }
 
     @IBAction func host(_ sender: Any) {

+ 276 - 9
iOSClient/Brand/NCBrand.swift

@@ -126,6 +126,7 @@ class NCBrandColor: NSObject {
     @objc public let yellowFavorite:        UIColor = UIColor(red: 248.0/255.0, green: 205.0/255.0, blue: 70.0/255.0, alpha: 1.0)
     @objc public let textInfo:              UIColor = UIColor(red: 153.0/255.0, green: 153.0/255.0, blue: 153.0/255.0, alpha: 1.0)
     @objc public var select:                UIColor = .white
+    @objc public var avatarBorder:          UIColor = .white
 
     override init() {
         self.brand = self.customer
@@ -143,6 +144,7 @@ class NCBrandColor: NSObject {
             textView = .white
             separator = UIColor(red: 60.0/255.0, green: 60.0/255.0, blue: 60.0/255.0, alpha: 1.0)
             select = UIColor.white.withAlphaComponent(0.2)
+            avatarBorder = .black
         } else {
             tabBar = .white
             backgroundView = .white
@@ -151,6 +153,7 @@ class NCBrandColor: NSObject {
             textView = .black
             separator = UIColor(red: 235.0/255.0, green: 235.0/255.0, blue: 235.0/255.0, alpha: 1.0)
             select = self.brandElement.withAlphaComponent(0.1)
+            avatarBorder = .white
         }
     }
     
@@ -168,7 +171,7 @@ class NCBrandColor: NSObject {
             
             let themingColorText = NCManageDatabase.shared.getCapabilitiesServerString(account: account, elements: NCElementsJSON.shared.capabilitiesThemingColorText)
             
-            CCGraphics.settingThemingColor(themingColor, themingColorElement: themingColorElement, themingColorText: themingColorText)
+            settingBrandColor(themingColor, themingColorElement: themingColorElement, themingColorText: themingColorText)
                         
             if NCBrandColor.shared.brandElement.isTooLight() {
                 if let color = NCBrandColor.shared.brandElement.darker(by: darker) {
@@ -202,10 +205,46 @@ class NCBrandColor: NSObject {
         
         DispatchQueue.main.async {
             NCCollectionCommon.shared.createImagesThemingColor()
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_changeTheming)
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterChangeTheming)
         }
     }
 #endif
+    
+    @objc func settingBrandColor(_ themingColor: String?, themingColorElement: String?, themingColorText: String?) {
+                
+        // COLOR
+        if themingColor?.first == "#" {
+            if let color = UIColor(hex: themingColor!) {
+                NCBrandColor.shared.brand = color
+            } else {
+                NCBrandColor.shared.brand = NCBrandColor.shared.customer
+            }
+        } else {
+            NCBrandColor.shared.brand = NCBrandColor.shared.customer
+        }
+        
+        // COLOR TEXT
+        if themingColorText?.first == "#" {
+            if let color = UIColor(hex: themingColorText!) {
+                NCBrandColor.shared.brandText = color
+            } else {
+                NCBrandColor.shared.brandText = NCBrandColor.shared.customerText
+            }
+        } else {
+            NCBrandColor.shared.brandText = NCBrandColor.shared.customerText
+        }
+        
+        // COLOR ELEMENT
+        if themingColorElement?.first == "#" {
+            if let color = UIColor(hex: themingColorElement!) {
+                NCBrandColor.shared.brandElement = color
+            } else {
+                NCBrandColor.shared.brandElement = NCBrandColor.shared.brand
+            }
+        } else {
+            NCBrandColor.shared.brandElement = NCBrandColor.shared.brand
+        }
+    }
 }
 
 //MARK: - Global
@@ -217,17 +256,245 @@ class NCBrandColor: NSObject {
     }()
 
     // Directory on Group
-    @objc public let appDatabaseNextcloud: String   = "Library/Application Support/Nextcloud"
+    @objc let appDatabaseNextcloud                  = "Library/Application Support/Nextcloud"
+    @objc let appApplicationSupport                 = "Library/Application Support"
+    @objc let appUserData                           = "Library/Application Support/UserData"
+    @objc let appCertificates                       = "Library/Application Support/Certificates"
+    @objc let appScan                               = "Library/Application Support/Scan"
+    @objc let directoryProviderStorage              = "File Provider Storage"
+
+    // Service Key Share
+    @objc let serviceShareKeyChain                  = "Crypto Cloud"
+    @objc let metadataKeyedUnarchiver               = "it.twsweb.nextcloud.metadata"
+
+    // Nextcloud version
+    @objc let nextcloudVersion12: Int               =  12
+    let nextcloudVersion15: Int                     =  15
+    let nextcloudVersion17: Int                     =  17
+    let nextcloudVersion18: Int                     =  18
+    let nextcloudVersion20: Int                     =  20
 
     // Database Realm
-    public let databaseDefault: String              = "nextcloud.realm"
-    public let databaseSchemaVersion: UInt64        = 153
+    let databaseDefault                             = "nextcloud.realm"
+    let databaseSchemaVersion: UInt64               = 161
+    
+    // Intro selector
+    @objc let introLogin: Int                       = 0
+    @objc let introSignup: Int                      = 1
+    
+    // Avatar & Preview
+    let avatarSize: CGFloat                         = 512
+    @objc let sizePreview: CGFloat                  = 1024
+    @objc let sizeIcon: CGFloat                     = 512
+    
+    // E2EE
+    let e2eeMaxFileSize: UInt64                     = 524288000   // 500 MB
+    let e2eePassphraseTest                          = "more over television factory tendency independence international intellectual impress interest sentence pony"
+    @objc let e2eeVersion                           = "1.1"
+    
+    // Max Size Upload
+    let uploadMaxFileSize: UInt64                   = 524288000   // 500 MB
+    
+    // Max Cache Proxy Video
+    let maxHTTPCache: Int64                         = 10737418240 // 10 GB
     
     // NCSharePaging
-    public let indexPageActivity: Int               = 0
-    public let indexPageComments: Int               = 1
-    public let indexPageSharing: Int                = 2
+    let indexPageActivity: Int                      = 0
+    let indexPageComments: Int                      = 1
+    let indexPageSharing: Int                       = 2
     
+    // NCViewerProviderContextMenu
+    let maxAutoDownload: UInt64                     = 104857600 // 100MB
+    let maxAutoDownloadCellular: UInt64             = 10485760  // 10MB
+
     // Nextcloud unsupported
-    public let nextcloud_unsupported_version: Int   = 13
+    let nextcloud_unsupported_version: Int          = 13
+    
+    // Layout
+    let layoutList                                  = "typeLayoutList"
+    let layoutGrid                                  = "typeLayoutGrid"
+    
+    let layoutViewMove                              = "LayoutMove"
+    let layoutViewTrash                             = "LayoutTrash"
+    let layoutViewOffline                           = "LayoutOffline"
+    let layoutViewFavorite                          = "LayoutFavorite"
+    let layoutViewFiles                             = "LayoutFiles"
+    let layoutViewViewInFolder                      = "ViewInFolder"
+    let layoutViewTransfers                         = "LayoutTransfers"
+    let layoutViewRecent                            = "LayoutRecent"
+    let layoutViewShares                            = "LayoutShares"
+    
+    // Button Type in Cell list/grid
+    let buttonMoreMore                              = "more"
+    let buttonMoreStop                              = "stop"
+    
+    // Text -  OnlyOffice - Collabora
+    let editorText                                  = "text"
+    let editorOnlyoffice                            = "onlyoffice"
+    let editorCollabora                             = "collabora"
+
+    let onlyofficeDocx                              = "onlyoffice_docx"
+    let onlyofficeXlsx                              = "onlyoffice_xlsx"
+    let onlyofficePptx                              = "onlyoffice_pptx"
+
+    // Template
+    let templateDocument                            = "document"
+    let templateSpreadsheet                         = "spreadsheet"
+    let templatePresentation                        = "presentation"
+    
+    // Rich Workspace
+    let fileNameRichWorkspace                       = "Readme.md"
+    
+    @objc let dismissAfterSecond: TimeInterval      = 4
+    @objc let dismissAfterSecondLong: TimeInterval  = 10
+    
+    // Error
+    @objc let ErrorBadRequest: Int                  = 400
+    @objc let ErrorResourceNotFound: Int            = 404
+    @objc let ErrorConflict: Int                    = 409
+    @objc let ErrorBadServerResponse: Int           = -1011
+    @objc let ErrorInternalError: Int               = -99999
+    @objc let ErrorFileNotSaved: Int                = -99998
+    @objc let ErrorDecodeMetadata: Int              = -99997
+    @objc let ErrorE2EENotEnabled: Int              = -99996
+    @objc let ErrorOffline: Int                     = -99994
+    @objc let ErrorCharactersForbidden: Int         = -99993
+    @objc let ErrorCreationFile: Int                = -99992
+    
+    // Constants to identify the different permissions of a file
+    @objc let permissionShared                      = "S"
+    @objc let permissionCanShare                    = "R"
+    @objc let permissionMounted                     = "M"
+    @objc let permissionFileCanWrite                = "W"
+    @objc let permissionCanCreateFile               = "C"
+    @objc let permissionCanCreateFolder             = "K"
+    @objc let permissionCanDelete                   = "D"
+    @objc let permissionCanRename                   = "N"
+    @objc let permissionCanMove                     = "V"
+    
+    //Share permission
+    //permissions - (int) 1 = read; 2 = update; 4 = create; 8 = delete; 16 = share; 31 = all (default: 31, for public shares: 1)
+    @objc let permissionReadShare: Int              = 1
+    @objc let permissionUpdateShare: Int            = 2
+    @objc let permissionCreateShare: Int            = 4
+    @objc let permissionDeleteShare: Int            = 8
+    @objc let permissionShareShare: Int             = 16
+    
+    @objc let permissionMinFileShare: Int           = 1
+    @objc let permissionMaxFileShare: Int           = 19
+    @objc let permissionMinFolderShare: Int         = 1
+    @objc let permissionMaxFolderShare: Int         = 31
+    @objc let permissionDefaultFileRemoteShareNoSupportShareOption: Int     = 3
+    @objc let permissionDefaultFolderRemoteShareNoSupportShareOption: Int   = 15
+    
+    // Metadata : FileType
+    @objc let metadataTypeFileAudio                 = "audio"
+    @objc let metadataTypeFileCompress              = "compress"
+    @objc let metadataTypeFileDirectory             = "directory"
+    @objc let metadataTypeFileDocument              = "document"
+    @objc let metadataTypeFileImage                 = "image"
+    @objc let metadataTypeFileUnknown               = "unknow"
+    @objc let metadataTypeFileVideo                 = "video"
+    @objc let metadataTypeFileImagemeter            = "imagemeter"
+    
+    // Filename Mask and Type
+    @objc let keyFileNameMask                       = "fileNameMask"
+    @objc let keyFileNameType                       = "fileNameType"
+    @objc let keyFileNameAutoUploadMask             = "fileNameAutoUploadMask"
+    @objc let keyFileNameAutoUploadType             = "fileNameAutoUploadType"
+    @objc let keyFileNameOriginal                   = "fileNameOriginal"
+    @objc let keyFileNameOriginalAutoUpload         = "fileNameOriginalAutoUpload"
+
+    // Selector
+    @objc let selectorDownloadFile                  = "downloadFile"
+    @objc let selectorDownloadAllFile               = "downloadAllFile"
+    @objc let selectorReadFile                      = "readFile"
+    @objc let selectorListingFavorite               = "listingFavorite"
+    @objc let selectorLoadFileView                  = "loadFileView"
+    @objc let selectorLoadFileQuickLook             = "loadFileQuickLook"
+    @objc let selectorLoadCopy                      = "loadCopy"
+    @objc let selectorLoadOffline                   = "loadOffline"
+    @objc let selectorOpenIn                        = "openIn"
+    @objc let selectorUploadAutoUpload              = "uploadAutoUpload"
+    @objc let selectorUploadAutoUploadAll           = "uploadAutoUploadAll"
+    @objc let selectorUploadFile                    = "uploadFile"
+    @objc let selectorSaveAlbum                     = "saveAlbum"
+    @objc let selectorSaveAlbumLivePhotoIMG         = "saveAlbumLivePhotoIMG"
+    @objc let selectorSaveAlbumLivePhotoMOV         = "saveAlbumLivePhotoMOV"
+
+    // Metadata : Status
+    //
+    // 1) wait download/upload
+    // 2) in download/upload
+    // 3) downloading/uploading
+    // 4) done or error
+    //
+    @objc let metadataStatusNormal: Int             = 0
+
+    @objc let metadataStatustypeDownload: Int       = 1
+
+    @objc let metadataStatusWaitDownload: Int       = 2
+    @objc let metadataStatusInDownload: Int         = 3
+    @objc let metadataStatusDownloading: Int        = 4
+    @objc let metadataStatusDownloadError: Int      = 5
+
+    @objc let metadataStatusTypeUpload: Int         = 6
+
+    @objc let metadataStatusWaitUpload: Int         = 7
+    @objc let metadataStatusInUpload: Int           = 8
+    @objc let metadataStatusUploading: Int          = 9
+    @objc let metadataStatusUploadError: Int        = 10
+    @objc let metadataStatusUploadForcedStart: Int  = 11
+    
+    // Notification Center
+
+    @objc let notificationCenterApplicationDidEnterBackground   = "applicationDidEnterBackground"
+    @objc let notificationCenterApplicationWillEnterForeground  = "applicationWillEnterForeground"
+
+    @objc let notificationCenterInitializeMain                  = "initializeMain"
+    @objc let notificationCenterChangeTheming                   = "changeTheming"
+    @objc let notificationCenterChangeUserProfile               = "changeUserProfile"
+    @objc let notificationCenterRichdocumentGrabFocus           = "richdocumentGrabFocus"
+    @objc let notificationCenterReloadDataNCShare               = "reloadDataNCShare"
+    @objc let notificationCenterCloseRichWorkspaceWebView       = "closeRichWorkspaceWebView"
+
+    @objc let notificationCenterReloadDataSource                = "reloadDataSource"                 // userInfo: ocId?, serverUrl?
+    @objc let notificationCenterReloadDataSourceNetworkForced   = "reloadDataSourceNetworkForced"    // userInfo: serverUrl?
+
+    @objc let notificationCenterChangeStatusFolderE2EE          = "changeStatusFolderE2EE"           // userInfo: serverUrl
+
+    @objc let notificationCenterDownloadStartFile               = "downloadStartFile"                // userInfo: ocId
+    @objc let notificationCenterDownloadedFile                  = "downloadedFile"                   // userInfo: ocId, selector, errorCode, errorDescription
+    @objc let notificationCenterDownloadCancelFile              = "downloadCancelFile"               // userInfo: ocId
+
+    @objc let notificationCenterUploadStartFile                 = "uploadStartFile"                  // userInfo: ocId
+    @objc let notificationCenterUploadedFile                    = "uploadedFile"                     // userInfo: ocId, ocIdTemp, errorCode, errorDescription
+    @objc let notificationCenterUploadCancelFile                = "uploadCancelFile"                 // userInfo: ocId
+
+    @objc let notificationCenterProgressTask                    = "progressTask"                     // userInfo: account, ocId, serverUrl, status, progress, totalBytes, totalBytesExpected
+    
+    @objc let notificationCenterCreateFolder                    = "createFolder"                     // userInfo: ocId
+    @objc let notificationCenterDeleteFile                      = "deleteFile"                       // userInfo: ocId, fileNameView, typeFile, onlyLocal
+    @objc let notificationCenterRenameFile                      = "renameFile"                       // userInfo: ocId, errorCode, errorDescription
+    @objc let notificationCenterMoveFile                        = "moveFile"                         // userInfo: ocId, serverUrlTo
+    @objc let notificationCenterCopyFile                        = "copyFile"                         // userInfo: ocId, serverUrlFrom
+    @objc let notificationCenterFavoriteFile                    = "favoriteFile"                     // userInfo: ocId
+
+    @objc let notificationCenterMenuSearchTextPDF               = "menuSearchTextPDF"
+    @objc let notificationCenterMenuDetailClose                 = "menuDetailClose"
 }
+
+//DispatchQueue.main.async
+//DispatchQueue.main.asyncAfter(deadline: .now() + 0.1)
+//DispatchQueue.global().async
+
+//#if targetEnvironment(simulator)
+//#endif
+
+
+//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+//dispatch_async(dispatch_get_main_queue(), ^{
+//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+
+//#if TARGET_OS_SIMULATOR
+//#endif

+ 0 - 33
iOSClient/Brand/iOSClient.plist

@@ -8,33 +8,6 @@
 	<string>en</string>
 	<key>CFBundleDisplayName</key>
 	<string>Nextcloud</string>
-	<key>CFBundleDocumentTypes</key>
-	<array>
-		<dict>
-			<key>CFBundleTypeIconFiles</key>
-			<array>
-				<string></string>
-			</array>
-			<key>CFBundleTypeName</key>
-			<string>All files</string>
-			<key>CFBundleTypeRole</key>
-			<string>Viewer</string>
-			<key>LSHandlerRank</key>
-			<string>Default</string>
-			<key>LSItemContentTypes</key>
-			<array>
-				<string>public.data</string>
-				<string>public.content</string>
-				<string>public.text</string>
-				<string>public.movie</string>
-				<string>public.audio</string>
-				<string>public.image</string>
-				<string>public.presentation</string>
-				<string>public.video</string>
-				<string>com.adobe.pdf</string>
-			</array>
-		</dict>
-	</array>
 	<key>CFBundleExecutable</key>
 	<string>$(EXECUTABLE_NAME)</string>
 	<key>CFBundleIdentifier</key>
@@ -68,12 +41,6 @@
 	<true/>
 	<key>ITSEncryptionExportComplianceCode</key>
 	<string>3b2bb0b1-fa12-43cb-a78f-0f7e1afd33df</string>
-	<key>LSApplicationQueriesSchemes</key>
-	<array>
-		<string>dbapi-1</string>
-		<string>dbapi-2</string>
-		<string>dbapi-3</string>
-	</array>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
 	<key>LSSupportsOpeningDocumentsInPlace</key>

+ 0 - 337
iOSClient/CCGlobal.h

@@ -1,337 +0,0 @@
-//
-//  CCGlobal.h
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 13/10/14.
-//  Copyright (c) 2014 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 <UIKit/UIKit.h>
-
-#ifndef EXTENSION
-
-//AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
-//#define app ((AppDelegate *)[[UIApplication sharedApplication] delegate])
-//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-//dispatch_async(dispatch_get_main_queue(), ^{
-//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
-
-//DispatchQueue.main.async
-//DispatchQueue.main.asyncAfter(deadline: .now() + 0.1)
-//DispatchQueue.global().async
-
-//NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
-//NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];
-//NSString *languageCode = [languageDic objectForKey:@"kCFLocaleLanguageCodeKey"];
-
-//#if targetEnvironment(simulator)
-//#endif
-
-//#if TARGET_OS_SIMULATOR
-//#endif
-
-//if indexPath.section <  collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section)
-
-#define CALL_ORIGIN NSLog(@"Origin: [%@]", [[[[NSThread callStackSymbols] objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] objectAtIndex:1])
-#endif
-
-// Directory on Group
-#define k_appApplicationSupport                         @"Library/Application Support"
-#define k_appUserData                                   @"Library/Application Support/UserData"
-#define k_appCertificates                               @"Library/Application Support/Certificates"
-#define k_appScan                                       @"Library/Application Support/Scan"
-#define k_DirectoryProviderStorage                      @"File Provider Storage"
-
-// Server Status
-#define k_serverStatus                                  @"/status.php"
-
-// Login Flow
-#define k_flowEndpoint                                  @"/index.php/login/flow"
-
-// Avatar
-#define k_avatar_size                                   128
-
-// Passphrase test EndToEnd Encryption
-#define k_passphrase_test                               @"more over television factory tendency independence international intellectual impress interest sentence pony"
-
-#define k_dismissAfterSecond                            4
-#define k_dismissAfterSecondLong                        10
-
-#define k_daysOfActivity                                7
-
-#define k_sizePreview                                   1024
-#define k_sizeIcon                                      512
-
-// Database JSON
-#define k_databaseDefaultJSON                           @"nextcloud.json"
-
-// Intro selector
-#define k_intro_login                                   0
-#define k_intro_signup                                  1
-
-// Login
-#define k_login_Add                                     0
-#define k_login_Add_Forced                              1
-#define k_login_Add_SignUp                              2
-
-// Constants to identify the different permissions of a file
-#define k_permission_shared                             @"S"
-#define k_permission_can_share                          @"R"
-#define k_permission_mounted                            @"M"
-#define k_permission_file_can_write                     @"W"
-#define k_permission_can_create_file                    @"C"
-#define k_permission_can_create_folder                  @"K"
-#define k_permission_can_delete                         @"D"
-#define k_permission_can_rename                         @"N"
-#define k_permission_can_move                           @"V"
-
-// Service Key Share
-#define k_serviceShareKeyChain                          @"Crypto Cloud"
-#define k_metadataKeyedUnarchiver                       @"it.twsweb.nextcloud.metadata"
-
-// Metadata : Status
-//
-// 1) wait download/upload
-// 2) in download/upload
-// 3) downloading/uploading
-// 4) done or error
-//
-#define k_metadataStatusNormal                          0
-
-#define k_metadataStatustypeDownload                    1
-
-#define k_metadataStatusWaitDownload                    2
-#define k_metadataStatusInDownload                      3
-#define k_metadataStatusDownloading                     4
-#define k_metadataStatusDownloadError                   5
-
-#define k_metadataStatusTypeUpload                      6
-
-#define k_metadataStatusWaitUpload                      7
-#define k_metadataStatusInUpload                        8
-#define k_metadataStatusUploading                       9
-#define k_metadataStatusUploadError                     10
-#define k_metadataStatusUploadForcedStart               11
-
-// Timer
-#define k_timerAutoUpload                               5
-#define k_timerUpdateApplicationIconBadgeNumber         5
-#define k_timerErrorNetworking                          3
-
-// Max Size Operation
-#define k_maxSizeOperationUpload                        524288000   // 500 MB
-
-// Max Cache Proxy Video
-#define k_maxHTTPCache                                  10737418240 // 10GB
-
-// Error
-#define k_CCErrorBadRequest                             400
-#define k_CCErrorResourceNotFound                       404
-#define k_CCErrorConflict                               409
-#define k_CCErrorBadServerResponse                      -1011
-#define k_CCErrorInternalError                          -99999
-#define k_CCErrorFileNotSaved                           -99998
-#define k_CCErrorDecodeMetadata                         -99997
-#define k_CCErrorE2EENotEnabled                         -99996
-#define k_CCErrorE2EENotMove                            -99995
-#define k_CCErrorOffline                                -99994
-#define k_CCErrorCharactersForbidden                    -99993
-#define k_CCErrorCreationFile                           -99992
-
-// Selector
-#define selectorDownloadFile                            @"downloadFile"
-#define selectorDownloadAllFile                         @"downloadAllFile"
-#define selectorReadFile                                @"readFile"
-#define selectorListingFavorite                         @"listingFavorite"
-#define selectorLoadFileView                            @"loadFileView"
-#define selectorLoadFileQuickLook                       @"loadFileQuickLook"
-#define selectorLoadCopy                                @"loadCopy"
-#define selectorLoadOffline                             @"loadOffline"
-#define selectorOpenIn                                  @"openIn"
-#define selectorUploadAutoUpload                        @"uploadAutoUpload"
-#define selectorUploadAutoUploadAll                     @"uploadAutoUploadAll"
-#define selectorUploadFile                              @"uploadFile"
-#define selectorSaveAlbum                               @"saveAlbum"
-
-// Metadata : FileType
-#define k_metadataTypeFile_audio                        @"audio"
-#define k_metadataTypeFile_compress                     @"compress"
-#define k_metadataTypeFile_directory                    @"directory"
-#define k_metadataTypeFile_document                     @"document"
-#define k_metadataTypeFile_image                        @"image"
-#define k_metadataTypeFile_unknown                      @"unknow"
-#define k_metadataTypeFile_video                        @"video"
-#define k_metadataTypeFile_imagemeter                   @"imagemeter"
-
-// TabBar button
-#define k_tabBarApplicationIndexFile                    0
-#define k_tabBarApplicationIndexFavorite                1
-#define k_tabBarApplicationIndexPlusHide                2
-#define k_tabBarApplicationIndexMedia                   3
-#define k_tabBarApplicationIndexMore                    4
-
-// Filename Mask and Type
-#define k_keyFileNameMask                               @"fileNameMask"
-#define k_keyFileNameType                               @"fileNameType"
-#define k_keyFileNameAutoUploadMask                     @"fileNameAutoUploadMask"
-#define k_keyFileNameAutoUploadType                     @"fileNameAutoUploadType"
-#define k_keyFileNameOriginal                           @"fileNameOriginal"
-#define k_keyFileNameOriginalAutoUpload                 @"fileNameOriginalAutoUpload"
-
-// Activity
-#define k_activityVerboseDefault                        0
-#define k_activityVerboseHigh                           1
-#define k_activityTypeInfo                              @"info"
-#define k_activityTypeSuccess                           @"success"
-#define k_activityTypeFailure                           @"error"
-
-#define k_activityDebugActionDownload                   @"Download"
-#define k_activityDebugActionDownloadPicker             @"Download Picker"
-#define k_activityDebugActionUpload                     @"Upload"
-#define k_activityDebugActionUploadPicker               @"Upload Picker"
-#define k_activityDebugActionUploadShare                @"Upload Share"
-#define k_activityDebugActionAutoUpload                 @"Auto Upload"
-#define k_activityDebugActionReadFolder                 @"Read Folder"
-#define k_activityDebugActionListingFavorites           @"Listing Favorites"
-#define k_activityDebugActionCreateFolder               @"Create Folder"
-#define k_activityDebugActionDeleteFileFolder           @"Delete File-Folder"
-#define k_activityDebugActionGetNotification            @"Get Notification Server"
-#define k_activityDebugActionSubscribingServerPush      @"Subscribing Server Push"
-#define k_activityDebugActionUnsubscribingServerPush    @"Unsubscribing Server Push"
-#define k_activityDebugActionSubscribingPushProxy       @"Subscribing Push Proxy"
-#define k_activityDebugActionUnsubscribingPushProxy     @"Unsubscribing Push Proxy"
-#define k_activityDebugActionCapabilities               @"Capabilities Of Server"
-#define k_activityDebugActionEndToEndEncryption         @"End To End Encryption "
-
-// E2EE
-#define k_max_filesize_E2EE                             524288000   // 500 MB
-#define k_E2EE_API                                      @"1.1"
-
-// Flow Version
-#define k_flow_version_available                        12
-
-// New capabilities version
-#define k_trash_version_available                       14
-#define k_trash_version_available_more_fix              15
-#define k_files_comments                                20
-
-// Toolbar Detail
-#define k_detail_Toolbar_Height                         49
-
-
-//Share permission
-//permissions - (int) 1 = read; 2 = update; 4 = create; 8 = delete; 16 = share; 31 = all (default: 31, for public shares: 1)
-#define k_read_share_permission                         1
-#define k_update_share_permission                       2
-#define k_create_share_permission                       4
-#define k_delete_share_permission                       8
-#define k_share_share_permission                        16
-
-#define k_min_file_share_permission                     1
-#define k_max_file_share_permission                     19
-#define k_min_folder_share_permission                   1
-#define k_max_folder_share_permission                   31
-#define k_default_file_remote_share_permission_no_support_share_option      3
-#define k_default_folder_remote_share_permission_no_support_share_option    15
-
-// Layout
-#define k_layout_list                                   @"typeLayoutList"
-#define k_layout_grid                                   @"typeLayoutGrid"
-
-#define k_layout_view_move                              @"LayoutMove"
-#define k_layout_view_richdocument                      @"LayoutRichdocument"
-#define k_layout_view_trash                             @"LayoutTrash"
-#define k_layout_view_offline                           @"LayoutOffline"
-#define k_layout_view_favorite                          @"LayoutFavorite"
-#define k_layout_view_files                             @"LayoutFiles"
-#define k_layout_view_viewInFolder                      @"ViewInFolder"
-#define k_layout_view_transfers                         @"LayoutTransfers"
-#define k_layout_view_media                             @"LayoutMedia"
-#define k_layout_view_recent                            @"LayoutRecent"
-#define k_layout_view_shares                            @"LayoutShares"
-
-// Button Type in Cell list/grid
-#define k_buttonMoreMore                                @"more"
-#define k_buttonMoreStop                                @"stop"
-
-// Rich Workspace
-#define k_fileNameRichWorkspace                         @"Readme.md"
-
-// Text -  OnlyOffice - Collabora
-#define k_editor_text                                   @"text"
-#define k_editor_onlyoffice                             @"onlyoffice"
-#define k_editor_collabora                              @"collabora"
-
-#define k_onlyoffice_docx                               @"onlyoffice_docx"
-#define k_onlyoffice_xlsx                               @"onlyoffice_xlsx"
-#define k_onlyoffice_pptx                               @"onlyoffice_pptx"
-
-// Template
-#define k_template_document                             @"document"
-#define k_template_spreadsheet                          @"spreadsheet"
-#define k_template_presentation                         @"presentation"
-
-// Nextcloud version
-#define k_nextcloud_version_12_0                        12
-#define k_nextcloud_version_13_0                        13
-#define k_nextcloud_version_14_0                        14
-#define k_nextcloud_version_15_0                        15
-#define k_nextcloud_version_16_0                        16
-#define k_nextcloud_version_17_0                        17
-#define k_nextcloud_version_18_0                        18
-#define k_nextcloud_version_19_0                        19
-#define k_nextcloud_version_20_0                        20
-
-// Notification Center
-
-#define k_notificationCenter_applicationDidEnterBackground  @"applicationDidEnterBackground"
-#define k_notificationCenter_applicationWillEnterForeground @"applicationWillEnterForeground"
-
-#define k_notificationCenter_initializeMain                 @"initializeMain"
-#define k_notificationCenter_setTitleMain                   @"setTitleMain"
-#define k_notificationCenter_changeTheming                  @"changeTheming"
-#define k_notificationCenter_changeUserProfile              @"changeUserProfile"
-#define k_notificationCenter_richdocumentGrabFocus          @"richdocumentGrabFocus"
-#define k_notificationCenter_reloadDataNCShare              @"reloadDataNCShare"
-#define k_notificationCenter_closeRichWorkspaceWebView      @"closeRichWorkspaceWebView"
-
-#define k_notificationCenter_reloadDataSource               @"reloadDataSource"                 // userInfo: ocId?, serverUrl?
-#define k_notificationCenter_reloadDataSourceNetworkForced  @"reloadDataSourceNetworkForced"    // userInfo: serverUrl?
-
-#define k_notificationCenter_changeStatusFolderE2EE         @"changeStatusFolderE2EE"           // userInfo: serverUrl
-
-#define k_notificationCenter_downloadStartFile              @"downloadStartFile"                // userInfo: ocId
-#define k_notificationCenter_downloadedFile                 @"downloadedFile"                   // userInfo: ocId, selector, errorCode, errorDescription
-#define k_notificationCenter_downloadCancelFile             @"downloadCancelFile"               // userInfo: ocId
-
-#define k_notificationCenter_uploadStartFile                @"uploadStartFile"                  // userInfo: ocId
-#define k_notificationCenter_uploadedFile                   @"uploadedFile"                     // userInfo: ocId, ocIdTemp, errorCode, errorDescription
-#define k_notificationCenter_uploadCancelFile               @"uploadCancelFile"                 // userInfo: ocId
-
-#define k_notificationCenter_progressTask                   @"progressTask"                     // userInfo: account, ocId, serverUrl, status, progress, totalBytes, totalBytesExpected
-
-#define k_notificationCenter_createFolder                   @"createFolder"                     // userInfo: ocId
-#define k_notificationCenter_deleteFile                     @"deleteFile"                       // userInfo: ocId, fileNameView, typeFile, onlyLocal
-#define k_notificationCenter_renameFile                     @"renameFile"                       // userInfo: ocId, errorCode, errorDescription
-#define k_notificationCenter_moveFile                       @"moveFile"                         // userInfo: ocId, serverUrlTo
-#define k_notificationCenter_copyFile                       @"copyFile"                         // userInfo: ocId, serverUrlFrom
-#define k_notificationCenter_favoriteFile                   @"favoriteFile"                     // userInfo: ocId
-
-#define k_notificationCenter_menuSearchTextPDF              @"menuSearchTextPDF"
-#define k_notificationCenter_menuSaveLivePhoto              @"menuSaveLivePhoto"                // userInfo: ocId, ocIdMov
-#define k_notificationCenter_menuDetailClose                @"menuDetailClose"

+ 0 - 40
iOSClient/CryptoCloud.pch

@@ -1,40 +0,0 @@
-//
-//  CryptoCloud.pch
-//  Nextcloud iOS
-//
-//  Created by Marino Faggiana on 17/09/15.
-//  Copyright (c) 2015 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/>.
-//
-
-#ifndef CryptoCloud_pch
-#define CryptoCloud_pch
-
-// Include any system framework and library headers here that should be included in all compilation units.
-// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
-
-#endif /* CryptoCloud_pch */
-
-#ifdef __OBJC__
-
-#import <UIKit/UIKit.h>
-#import <Foundation/Foundation.h>
-#import <QuartzCore/QuartzCore.h>
-#import "CCGlobal.h"
-#import "NSNotificationCenter+MainThread.h"
-
-#endif

+ 2 - 2
iOSClient/Data/NCDataSource.swift

@@ -150,11 +150,11 @@ class NCDataSource: NSObject {
         
     // MARK: -
 
-    func getFilesInformation() -> (directories: Int,  files: Int, size: Double) {
+    func getFilesInformation() -> (directories: Int,  files: Int, size: Int64) {
 
         var directories: Int = 0
         var files: Int = 0
-        var size: Double = 0
+        var size: Int64 = 0
 
         for metadata in metadatas {
             if metadata.directory {

+ 11 - 13
iOSClient/Data/NCDatabase.swift

@@ -52,16 +52,16 @@ class tableAccount: Object {
     @objc dynamic var enabled: Bool = false
     @objc dynamic var groups = ""
     @objc dynamic var language = ""
-    @objc dynamic var lastLogin: Double = 0
+    @objc dynamic var lastLogin: Int64 = 0
     @objc dynamic var locale = ""
     @objc dynamic var mediaPath = ""
     @objc dynamic var password = ""
     @objc dynamic var phone = ""
-    @objc dynamic var quota: Double = 0
-    @objc dynamic var quotaFree: Double = 0
+    @objc dynamic var quota: Int64 = 0
+    @objc dynamic var quotaFree: Int64 = 0
     @objc dynamic var quotaRelative: Double = 0
-    @objc dynamic var quotaTotal: Double = 0
-    @objc dynamic var quotaUsed: Double = 0
+    @objc dynamic var quotaTotal: Int64 = 0
+    @objc dynamic var quotaUsed: Int64 = 0
     @objc dynamic var role = ""
     @objc dynamic var storageLocation = ""
     @objc dynamic var subadmin = ""
@@ -81,10 +81,10 @@ class tableAccount: Object {
     // HC
     @objc dynamic var hcIsTrial: Bool = false
     @objc dynamic var hcTrialExpired: Bool = false
-    @objc dynamic var hcTrialRemainingSec: Double = 0
+    @objc dynamic var hcTrialRemainingSec: Int64 = 0
     @objc dynamic var hcTrialEndTime: NSDate? = nil
     @objc dynamic var hcAccountRemoveExpired: Bool = false
-    @objc dynamic var hcAccountRemoveRemainingSec: Double = 0
+    @objc dynamic var hcAccountRemoveRemainingSec: Int64 = 0
     @objc dynamic var hcAccountRemoveTime: NSDate? = nil
     @objc dynamic var hcNextGroupExpirationGroup = ""
     @objc dynamic var hcNextGroupExpirationGroupExpired: Bool = false
@@ -221,7 +221,6 @@ class tableDirectory: Object {
     @objc dynamic var permissions = ""
     @objc dynamic var richWorkspace: String?
     @objc dynamic var serverUrl = ""
-    @objc dynamic var synchronized: Bool = false
 
     override static func primaryKey() -> String {
         return "ocId"
@@ -296,7 +295,6 @@ class tableLocalFile: Object {
     @objc dynamic var fileName = ""
     @objc dynamic var ocId = ""
     @objc dynamic var offline: Bool = false
-    @objc dynamic var size: Double = 0
     
     override static func primaryKey() -> String {
         return "ocId"
@@ -330,8 +328,8 @@ class tableMetadata: Object {
     @objc dynamic var ownerId = ""
     @objc dynamic var ownerDisplayName = ""
     @objc dynamic var permissions = ""
-    @objc dynamic var quotaUsedBytes: Double = 0
-    @objc dynamic var quotaAvailableBytes: Double = 0
+    @objc dynamic var quotaUsedBytes: Int64 = 0
+    @objc dynamic var quotaAvailableBytes: Int64 = 0
     @objc dynamic var resourceType = ""
     @objc dynamic var richWorkspace: String?
     @objc dynamic var serverUrl = ""
@@ -339,7 +337,7 @@ class tableMetadata: Object {
     @objc dynamic var sessionError = ""
     @objc dynamic var sessionSelector = ""
     @objc dynamic var sessionTaskIdentifier: Int = 0
-    @objc dynamic var size: Double = 0
+    @objc dynamic var size: Int64 = 0
     @objc dynamic var status: Int = 0
     @objc dynamic var trashbinFileName = ""
     @objc dynamic var trashbinOriginalLocation = ""
@@ -436,7 +434,7 @@ class tableTrash: Object {
     @objc dynamic var filePath = ""
     @objc dynamic var hasPreview: Bool = false
     @objc dynamic var iconName = ""
-    @objc dynamic var size: Double = 0
+    @objc dynamic var size: Int64 = 0
     @objc dynamic var typeFile = ""
     @objc dynamic var trashbinFileName = ""
     @objc dynamic var trashbinOriginalLocation = ""

+ 77 - 31
iOSClient/Data/NCManageDatabase.swift

@@ -119,6 +119,11 @@ class NCManageDatabase: NSObject {
                         }
                     }
                     
+                    if oldSchemaVersion < 160 {
+                        migration.deleteData(forType: tableDirectory.className())
+                        migration.deleteData(forType: tableMetadata.className())
+                    }
+                    
                 }, shouldCompactOnLaunch: { totalBytes, usedBytes in
                     
                     // totalBytes refers to the size of the file on disk in bytes (data + free space)
@@ -136,7 +141,7 @@ class NCManageDatabase: NSObject {
                 if let databaseFilePath = databaseFilePath {
                     do {
                         #if !EXTENSION
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: NCBrandGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
                         #endif
                         try FileManager.default.removeItem(at: databaseFilePath)
                     } catch {}
@@ -158,7 +163,7 @@ class NCManageDatabase: NSObject {
             if let databaseFilePath = databaseFilePath {
                 do {
                     #if !EXTENSION
-                    NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
+                    NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: NCBrandGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
                     #endif
                     try FileManager.default.removeItem(at: databaseFilePath)
                 } catch {}
@@ -395,7 +400,7 @@ class NCManageDatabase: NSObject {
         if result.autoUploadDirectory.count > 0 {
             return result.autoUploadDirectory
         } else {
-            return NCUtility.shared.getHomeServer(urlBase: urlBase, account: account)
+            return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, account: account)
         }
     }
 
@@ -1030,10 +1035,10 @@ class NCManageDatabase: NSObject {
                         addObject.mimetypes.append(mimeType)
                     }
                     addObject.name = editor.name
-                    if editor.name.lowercased() == k_editor_onlyoffice {
-                        addObject.editor = k_editor_onlyoffice
+                    if editor.name.lowercased() == NCBrandGlobal.shared.editorOnlyoffice {
+                        addObject.editor = NCBrandGlobal.shared.editorOnlyoffice
                     } else {
-                        addObject.editor = k_editor_text
+                        addObject.editor = NCBrandGlobal.shared.editorText
                     }
                     for mimeType in editor.optionalMimetypes {
                         addObject.optionalMimetypes.append(mimeType)
@@ -1255,6 +1260,7 @@ class NCManageDatabase: NSObject {
         }
     }
     
+    /*
     @objc func setDirectory(synchronized: Bool, serverUrl: String, account: String) {
         
         let realm = try! Realm()
@@ -1294,7 +1300,8 @@ class NCManageDatabase: NSObject {
             NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
         }
     }
-
+    */
+    
     //MARK: -
     //MARK: Table e2e Encryption
     
@@ -1556,7 +1563,6 @@ class NCManageDatabase: NSObject {
                 addObject.exifLongitude = "-1"
                 addObject.ocId = metadata.ocId
                 addObject.fileName = metadata.fileName
-                addObject.size = metadata.size
             
                 realm.add(addObject, update: .all)
             }
@@ -1706,13 +1712,18 @@ class NCManageDatabase: NSObject {
         if isEncrypted || metadata.e2eEncrypted {
             if let tableE2eEncryption = NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", account, file.serverUrl, file.fileName)) {
                 metadata.fileNameView = tableE2eEncryption.fileName
-                let results = NCCommunicationCommon.shared.getInternalContenType(fileName: metadata.fileNameView, contentType: file.contentType, directory: file.directory)
-                metadata.contentType = results.contentType
+                let results = NCCommunicationCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: file.contentType, directory: file.directory)
+                metadata.contentType = results.mimeType
                 metadata.iconName = results.iconName
                 metadata.typeFile = results.typeFile
             }
         }
         
+        // Live Photo "DETECT"
+        if !metadata.directory && !metadata.livePhoto && (metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage) {
+            metadata.livePhoto = isLivePhoto(metadata: metadata)
+        }
+        
         return metadata
     }
     
@@ -1755,10 +1766,10 @@ class NCManageDatabase: NSObject {
     @objc func createMetadata(account: String, fileName: String, ocId: String, serverUrl: String, urlBase: String, url: String, contentType: String, livePhoto: Bool) -> tableMetadata {
         
         let metadata = tableMetadata()
-        let results = NCCommunicationCommon.shared.getInternalContenType(fileName: fileName, contentType: contentType, directory: false)
+        let results = NCCommunicationCommon.shared.getInternalType(fileName: fileName, mimeType: contentType, directory: false)
         
         metadata.account = account
-        metadata.contentType = results.contentType
+        metadata.contentType = results.mimeType
         metadata.creationDate = Date() as NSDate
         metadata.date = Date() as NSDate
         metadata.hasPreview = true
@@ -1878,9 +1889,14 @@ class NCManageDatabase: NSObject {
         do {
             try realm.safeWrite {
                 if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first {
+                    let resultsType = NCCommunicationCommon.shared.getInternalType(fileName: fileNameTo, mimeType: "", directory: result.directory)
                     result.fileName = fileNameTo
                     result.fileNameView = fileNameTo
                     result.fileNameWithoutExt = (fileNameTo as NSString).deletingPathExtension
+                    result.ext = resultsType.ext
+                    result.iconName = resultsType.iconName
+                    result.contentType = resultsType.mimeType
+                    result.typeFile = resultsType.typeFile
                 }
             }
         } catch let error {
@@ -1916,10 +1932,10 @@ class NCManageDatabase: NSObject {
                     
                     if let result = metadatasResult.first(where: { $0.ocId == metadata.ocId }) {
                         // update
-                        if result.status == k_metadataStatusNormal && (result.etag != metadata.etag || result.fileNameView != metadata.fileNameView || result.date != metadata.date || result.permissions != metadata.permissions) {
+                        if result.status == NCBrandGlobal.shared.metadataStatusNormal && (result.etag != metadata.etag || result.fileNameView != metadata.fileNameView || result.date != metadata.date || result.permissions != metadata.permissions) {
                             ocIdsUdate.append(metadata.ocId)
                             realm.add(metadata, update: .all)
-                        } else if result.status == k_metadataStatusNormal && addCompareLivePhoto && result.livePhoto != metadata.livePhoto {
+                        } else if result.status == NCBrandGlobal.shared.metadataStatusNormal && addCompareLivePhoto && result.livePhoto != metadata.livePhoto {
                             ocIdsUdate.append(metadata.ocId)
                             realm.add(metadata, update: .all)
                         }
@@ -1933,8 +1949,6 @@ class NCManageDatabase: NSObject {
                         let table = realm.objects(tableDirectory.self).filter(NSPredicate(format: "ocId == %@", metadata.ocId)).first
                         if table?.etag != metadata.etag {
                             ocIdsUdate.append(metadata.ocId)
-                        } else if addDirectorySynchronized && table?.synchronized == false {
-                            ocIdsUdate.append(metadata.ocId)
                         }
                     }
                     
@@ -1969,7 +1983,7 @@ class NCManageDatabase: NSObject {
         return (metadatasUpdate, metadatasLocalUpdate)
     }
     
-    func setMetadataSession(ocId: String, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil, setFavorite: Bool = false) {
+    func setMetadataSession(ocId: String, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil) {
             
         let realm = try! Realm()
         realm.refresh()
@@ -1995,9 +2009,6 @@ class NCManageDatabase: NSObject {
                 if let etag = etag {
                     result?.etag = etag
                 }
-                if setFavorite {
-                    result?.favorite = true
-                }
             }
         } catch let error {
             NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
@@ -2127,7 +2138,7 @@ class NCManageDatabase: NSObject {
         
         // For Live Photo
         var fileNameImages: [String] = []
-        let filtered = results.filter{ $0.typeFile.contains(k_metadataTypeFile_image) }
+        let filtered = results.filter{ $0.typeFile.contains(NCBrandGlobal.shared.metadataTypeFileImage) }
         filtered.forEach { print($0)
             let fileName = ($0.fileNameView as NSString).deletingPathExtension
             fileNameImages.append(fileName)
@@ -2219,13 +2230,13 @@ class NCManageDatabase: NSObject {
         var serverUrl = serverUrl
         var fileName = ""
         
-        let serverUrlHome = NCUtility.shared.getHomeServer(urlBase: urlBase, account: account)
+        let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, account: account)
         if serverUrlHome == serverUrl {
             fileName = "."
             serverUrl = ".."
         } else {
             fileName = (serverUrl as NSString).lastPathComponent
-            serverUrl = NCUtility.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: urlBase, account: account)
+            serverUrl = NCUtilityFileSystem.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: urlBase, account: account)
         }
         
         guard let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first else { return nil }
@@ -2257,7 +2268,7 @@ class NCManageDatabase: NSObject {
         do {
             try realm.safeWrite {
                 
-                let results = realm.objects(tableMetadata.self).filter("account == %@ AND (status == %d OR status == %@)", account, k_metadataStatusWaitUpload, k_metadataStatusUploadError)
+                let results = realm.objects(tableMetadata.self).filter("account == %@ AND (status == %d OR status == %@)", account, NCBrandGlobal.shared.metadataStatusWaitUpload, NCBrandGlobal.shared.metadataStatusUploadError)
                 realm.delete(results)
             }
         } catch let error {
@@ -2313,7 +2324,7 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @objc func isLivePhoto(metadata: tableMetadata) -> tableMetadata? {
+    @objc func getMetadataLivePhoto(metadata: tableMetadata) -> tableMetadata? {
            
         let realm = try! Realm()
         realm.refresh()
@@ -2328,6 +2339,18 @@ class NCManageDatabase: NSObject {
         
         return tableMetadata.init(value: result)
     }
+   
+    func isLivePhoto(metadata: tableMetadata) -> Bool {
+           
+        let realm = try! Realm()
+        realm.refresh()
+        
+        if realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameWithoutExt == %@ AND ocId != %@", metadata.account, metadata.serverUrl, metadata.fileNameWithoutExt, metadata.ocId)).first == nil {
+            return false
+        }
+        
+        return true
+    }
     
     func getMetadatasMedia(predicate: NSPredicate, sort: String, ascending: Bool = false) -> [tableMetadata] {
         
@@ -2347,13 +2370,13 @@ class NCManageDatabase: NSObject {
         
         if metadataFolder != nil {
             
-            isShare = metadata.permissions.contains(k_permission_shared) && !metadataFolder!.permissions.contains(k_permission_shared)
-            isMounted = metadata.permissions.contains(k_permission_mounted) && !metadataFolder!.permissions.contains(k_permission_mounted)
+            isShare = metadata.permissions.contains(NCBrandGlobal.shared.permissionShared) && !metadataFolder!.permissions.contains(NCBrandGlobal.shared.permissionShared)
+            isMounted = metadata.permissions.contains(NCBrandGlobal.shared.permissionMounted) && !metadataFolder!.permissions.contains(NCBrandGlobal.shared.permissionMounted)
             
         } else if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl))  {
                 
-            isShare = metadata.permissions.contains(k_permission_shared) && !directory.permissions.contains(k_permission_shared)
-            isMounted = metadata.permissions.contains(k_permission_mounted) && !directory.permissions.contains(k_permission_mounted)
+            isShare = metadata.permissions.contains(NCBrandGlobal.shared.permissionShared) && !directory.permissions.contains(NCBrandGlobal.shared.permissionShared)
+            isMounted = metadata.permissions.contains(NCBrandGlobal.shared.permissionMounted) && !directory.permissions.contains(NCBrandGlobal.shared.permissionMounted)
         }
         
         if isShare || isMounted {
@@ -2363,6 +2386,29 @@ class NCManageDatabase: NSObject {
         }
     }
     
+    func isDownloadMetadata(_ metadata: tableMetadata, download: Bool) -> Bool {
+        
+        let localFile = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+        let fileSize = CCUtility.fileProviderStorageSize(metadata.ocId, fileNameView: metadata.fileNameView)
+        if (localFile != nil || download) && (localFile?.etag != metadata.etag || fileSize == 0) {
+            return true
+        }
+        return false
+    }
+    
+    func getMetadataConflict(account: String, serverUrl: String, fileName: String) -> tableMetadata? {
+        
+        // verify exists conflict
+        let fileNameExtension = (fileName as NSString).pathExtension.lowercased()
+        let fileNameWithoutExtension = (fileName as NSString).deletingPathExtension
+        var fileNameConflict = fileName
+        
+        if fileNameExtension == "heic" && CCUtility.getFormatCompatibility() {
+            fileNameConflict = fileNameWithoutExtension + ".jpg"
+        }
+        return getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView == %@", account, serverUrl, fileNameConflict))
+    }
+    
     //MARK: -
     //MARK: Table Photo Library
     
@@ -2453,8 +2499,8 @@ class NCManageDatabase: NSObject {
         for share in shares {
             
             let addObject = tableShare()
-            let fullPath = NCUtility.shared.getHomeServer(urlBase: urlBase, account: account) + share.path
-            let serverUrl = NCUtility.shared.deletingLastPathComponent(serverUrl:fullPath, urlBase: urlBase, account: account)
+            let fullPath = NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, account: account) + share.path
+            let serverUrl = NCUtilityFileSystem.shared.deletingLastPathComponent(serverUrl:fullPath, urlBase: urlBase, account: account)
             let fileName = NSString(string: fullPath).lastPathComponent
                         
             addObject.account = account

+ 20 - 20
iOSClient/Diagnostics/NCCapabilitiesViewController.swift

@@ -78,7 +78,7 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr
         
         self.title = NSLocalizedString("_capabilities_", comment: "")
                
-        let shareImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "shareFill"), width: 50, height: 50, color: .gray)
+        let shareImage = UIImage.init(named: "shareFill")!.image(color: .gray, size: 25)
         self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: shareImage, style: UIBarButtonItem.Style.plain, target: self, action: #selector(share))
         self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: UIBarButtonItem.Style.plain, target: self, action: #selector(close))
 
@@ -140,17 +140,17 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr
         statusComments.layer.borderColor = NCBrandColor.shared.textView.cgColor
         statusComments.layer.backgroundColor = NCBrandColor.shared.graySoft.withAlphaComponent(0.3).cgColor
         
-        imageFileSharing.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "share"), width: 100, height: 100, color: .gray)
-        imageExternalSite.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "externalsites"), width: 100, height: 100, color: .gray)
-        imageEndToEndEncryption.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "lock"), width: 100, height: 100, color: .gray)        
-        imageActivity.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "activity"), width: 100, height: 100, color: .gray)
-        imageNotification.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "notification"), width: 100, height: 100, color: .gray)
-        imageDeletedFiles.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "delete"), width: 100, height: 100, color: .gray)
-        imageText.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "text"), width: 100, height: 100, color: .gray)
-        imageCollabora.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "collabora"), width: 100, height: 100, color: .gray)
-        imageOnlyOffice.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "onlyoffice"), width: 100, height: 100, color: .gray)
-        imageUserStatus.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "userStatusAway"), width: 100, height: 100, color: .gray)
-        imageComments.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "comments"), width: 100, height: 100, color: .gray)
+        imageFileSharing.image = UIImage.init(named: "share")!.image(color: .gray, size: 50)
+        imageExternalSite.image = UIImage.init(named: "externalsites")!.image(color: .gray, size: 50)
+        imageEndToEndEncryption.image = UIImage.init(named: "lock")!.image(color: .gray, size: 50)
+        imageActivity.image = UIImage.init(named: "activity")!.image(color: .gray, size: 50)
+        imageNotification.image = UIImage.init(named: "notification")!.image(color: .gray, size: 50)
+        imageDeletedFiles.image = UIImage.init(named: "delete")!.image(color: .gray, size: 50)
+        imageText.image = UIImage.init(named: "text")!.image(color: .gray, size: 50)
+        imageCollabora.image = UIImage.init(named: "collabora")!.image(color: .gray, size: 50)
+        imageOnlyOffice.image = UIImage.init(named: "onlyoffice")!.image(color: .gray, size: 50)
+        imageUserStatus.image = UIImage.init(named: "userStatusAway")!.image(color: .gray, size: 50)
+        imageComments.image = UIImage.init(named: "comments")!.image(color: .gray, size: 50)
 
         guard let account = NCManageDatabase.shared.getAccountActive() else { return }
         self.account = account.account
@@ -159,18 +159,18 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr
             capabilitiesText = text
             updateCapabilities()
         } else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "_no_capabilities_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_no_capabilities_found_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
             
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                 self.dismiss(animated: true, completion: nil)
             }
         }
         
-        homeImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "home"), width: 100, height: 100, color: .gray)
-        homeServer.text = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) + "/"
+        homeImage.image = UIImage.init(named: "home")!.image(color: .gray, size: 50)
+        homeServer.text = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) + "/"
         
-        davImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "dav"), width: 100, height: 100, color: .gray)
-        davFiles.text = appDelegate.urlBase + "/" + NCUtility.shared.getDAV() + "/files/" + appDelegate.user + "/"
+        davImage.image = UIImage.init(named: "dav")!.image(color: .gray, size: 50)
+        davFiles.text = appDelegate.urlBase + "/" + NCUtilityFileSystem.shared.getDAV() + "/files/" + appDelegate.user + "/"
     }
 
     @objc func updateCapabilities() {
@@ -181,7 +181,7 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr
                 
                 // EDITORS
                 let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-                if serverVersionMajor >= k_nextcloud_version_18_0 {
+                if serverVersionMajor >= NCBrandGlobal.shared.nextcloudVersion18 {
                     NCCommunication.shared.NCTextObtainEditorDetails() { (account, editors, creators, errorCode, errorMessage) in
                         if errorCode == 0 && account == self.appDelegate.account {
                             NCManageDatabase.shared.addDirectEditing(account: account, editors: editors, creators: creators)
@@ -278,9 +278,9 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr
         var onlyofficeEditors = false
         if let editors = NCManageDatabase.shared.getDirectEditingEditors(account: account) {
             for editor in editors {
-                if editor.editor == k_editor_text {
+                if editor.editor == NCBrandGlobal.shared.editorText {
                     textEditor = true
-                } else if editor.editor == k_editor_onlyoffice {
+                } else if editor.editor == NCBrandGlobal.shared.editorOnlyoffice {
                     onlyofficeEditors = true
                 }
             }

+ 1 - 1
iOSClient/EmptyView/NCEmptyDataSet.swift

@@ -88,7 +88,7 @@ public class NCEmptyView: UIView {
     public override func awakeFromNib() {
         super.awakeFromNib()
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         changeTheming()
     }
     

+ 0 - 0
iOSClient/Utility/NSNotificationCenter+MainThread.h → iOSClient/Extensions/NSNotificationCenter+MainThread.h


+ 0 - 0
iOSClient/Utility/NSNotificationCenter+MainThread.m → iOSClient/Extensions/NSNotificationCenter+MainThread.m


+ 0 - 0
iOSClient/Utility/NotificationCenter+MainThread.swift → iOSClient/Extensions/NotificationCenter+MainThread.swift


+ 17 - 9
iOSClient/Utility/NSString+TruncateToWidth.h → iOSClient/Extensions/String+Extensions.swift

@@ -1,9 +1,9 @@
 //
-//  NSString+TruncateToWidth.h
+//  String+Extensions.swift
 //  Nextcloud
 //
-//  Created by Marino Faggiana on 06/04/16.
-//  Copyright (c) 2016 Marino Faggiana. All rights reserved.
+//  Created by Marino Faggiana on 22/12/20.
+//  Copyright © 2020 Marino Faggiana. All rights reserved.
 //
 //  Author Marino Faggiana <marino.faggiana@nextcloud.com>
 //
@@ -21,10 +21,18 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-#import <Foundation/Foundation.h>
+import Foundation
 
-@interface NSString (TruncateToWidth)
-
-- (NSString*)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font atEnd:(BOOL)atEnd;
-
-@end
+extension String {
+    
+    func formatSecondsToString(_ seconds: TimeInterval) -> String {
+        if seconds.isNaN {
+            return "00:00:00"
+        }
+        let sec = Int(seconds.truncatingRemainder(dividingBy: 60))
+        let min = Int(seconds.truncatingRemainder(dividingBy: 3600) / 60)
+        let hour = Int(seconds / 3600)
+        return String(format: "%02d:%02d:%02d", hour, min, sec)
+    }
+    
+}

+ 52 - 2
iOSClient/Utility/UIColor+adjust.swift → iOSClient/Extensions/UIColor+Extensions.swift

@@ -5,11 +5,61 @@
 //  Created by Marino Faggiana on 04/02/2020.
 //  Copyright © 2020 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
 
 extension UIColor {
+    
+    @objc convenience init?(hex: String) {
+
+        let r, g, b, a: CGFloat
+        
+        if hex.hasPrefix("#") {
+            
+            let start = hex.index(hex.startIndex, offsetBy: 1)
+            let hexColor = String(hex[start...])
+            let scanner = Scanner(string: hexColor)
+            var hexNumber: UInt64 = 0
+            
+            if hexColor.count == 6 && scanner.scanHexInt64(&hexNumber) {
+                
+                r = CGFloat((hexNumber & 0xff0000) >> 16) / 255.0
+                g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255.0
+                b = CGFloat(hexNumber & 0x0000ff) / 255.0
+
+                self.init(red: r, green: g, blue: b, alpha: 1)
+                return
+                
+            } else if hexColor.count == 7 && scanner.scanHexInt64(&hexNumber) {
+                    
+                r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
+                g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
+                b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
+                a = CGFloat(hexNumber & 0x000000ff) / 255
 
+                self.init(red: r, green: g, blue: b, alpha: a)
+                return
+            }
+        }
+        
+        return nil
+    }
+    
     @objc func lighter(by percentage: CGFloat = 30.0) -> UIColor? {
         return self.adjust(by: abs(percentage) )
     }
@@ -33,7 +83,7 @@ extension UIColor {
     @objc func isTooLight() -> Bool {
         
         var white: CGFloat = 0.0
-        color.getWhite(&white, alpha: nil)
+        self.getWhite(&white, alpha: nil)
         if white == 1 { return true }
         
         guard let components = cgColor.components, components.count > 2 else {return false}
@@ -44,7 +94,7 @@ extension UIColor {
     @objc func isTooDark() -> Bool {
         
         var white: CGFloat = 0.0
-        color.getWhite(&white, alpha: nil)
+        self.getWhite(&white, alpha: nil)
         if white == 0 { return true }
         
         guard let components = cgColor.components, components.count > 2 else {return false}

+ 48 - 27
iOSClient/Utility/UIImage+Extensions.swift → iOSClient/Extensions/UIImage+Extensions.swift

@@ -26,36 +26,30 @@ import Accelerate
 
 extension UIImage {
     
-    func resizeImageUsingVImage(size:CGSize) -> UIImage? {
+    @objc func resizeImage(size: CGSize, isAspectRation: Bool) -> UIImage? {
         
-        let cgImage = self.cgImage!
-        var format = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: nil, bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue), version: 0, decode: nil, renderingIntent: CGColorRenderingIntent.defaultIntent)
-        var sourceBuffer = vImage_Buffer()
-        defer {
-            free(sourceBuffer.data)
+        let originRatio = self.size.width / self.size.height
+        let newRatio = size.width / size.height
+        var newSize = size
+
+        if isAspectRation {
+            if originRatio < newRatio {
+                newSize.height = size.height
+                newSize.width = size.height * originRatio
+            } else {
+                newSize.width = size.width;
+                newSize.height = size.width / originRatio
+            }
         }
-        var error = vImageBuffer_InitWithCGImage(&sourceBuffer, &format, nil, cgImage, numericCast(kvImageNoFlags))
-        guard error == kvImageNoError else { return nil }
-        // create a destination buffer
-        let destWidth = Int(size.width)
-        let destHeight = Int(size.height)
-        let bytesPerPixel = self.cgImage!.bitsPerPixel/8
-        let destBytesPerRow = destWidth * bytesPerPixel
-        let destData = UnsafeMutablePointer<UInt8>.allocate(capacity: destHeight * destBytesPerRow)
-        defer {
-            destData.deallocate()
+        
+        UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
+        self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
+        let newImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+        if let image = newImage {
+            return image
         }
-        var destBuffer = vImage_Buffer(data: destData, height: vImagePixelCount(destHeight), width: vImagePixelCount(destWidth), rowBytes: destBytesPerRow)
-        // scale the image
-        error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, nil, numericCast(kvImageHighQualityResampling))
-        guard error == kvImageNoError else { return nil }
-        // create a CGImage from vImage_Buffer
-        var destCGImage = vImageCreateCGImageFromBuffer(&destBuffer, &format, nil, nil, numericCast(kvImageNoFlags), &error)?.takeRetainedValue()
-        guard error == kvImageNoError else { return nil }
-        // create a UIImage
-        let resizedImage = destCGImage.flatMap { UIImage(cgImage: $0, scale: 0.0, orientation: self.imageOrientation) }
-        destCGImage = nil
-        return resizedImage
+        return self
     }
     
     func fixedOrientation() -> UIImage? {
@@ -119,4 +113,31 @@ extension UIImage {
         guard let newCGImage = ctx.makeImage() else { return nil }
         return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
     }
+    
+    @objc func image(color: UIColor, size: CGFloat) -> UIImage {
+        
+        let size = CGSize(width: size, height: size)
+        
+        UIGraphicsBeginImageContextWithOptions(size, false, self.scale)
+        color.setFill()
+
+        let context = UIGraphicsGetCurrentContext()
+        context?.translateBy(x: 0, y: size.height)
+        context?.scaleBy(x: 1.0, y: -1.0)
+        context?.setBlendMode(CGBlendMode.normal)
+
+        let rect = CGRect(origin: .zero, size: size)
+        guard let cgImage = self.cgImage else { return self }
+        context?.clip(to: rect, mask: cgImage)
+        context?.fill(rect)
+
+        let newImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
+        UIGraphicsEndImageContext()
+        
+        return newImage
+    }
+    
+    func imageColor(_ color: UIColor) -> UIImage {
+        return image(color: color, size: size.width)
+    }
 }

+ 0 - 0
iOSClient/Utility/UIImage+animatedGIF.h → iOSClient/Extensions/UIImage+animatedGIF.h


+ 0 - 0
iOSClient/Utility/UIImage+animatedGIF.m → iOSClient/Extensions/UIImage+animatedGIF.m


+ 57 - 0
iOSClient/Extensions/UIImageView+Extensions.swift

@@ -0,0 +1,57 @@
+//
+//  UIImageView+Extensions.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 22/12/20.
+//  Copyright © 2020 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
+
+extension UIImageView {
+    
+    @objc func avatar(roundness: CGFloat = 2, borderWidth: CGFloat = 1, borderColor: UIColor = NCBrandColor.shared.avatarBorder, backgroundColor: UIColor = .clear) {
+        
+        layer.cornerRadius = bounds.width / roundness
+        layer.borderWidth = borderWidth
+        layer.borderColor = borderColor.cgColor
+        layer.backgroundColor = backgroundColor.cgColor
+
+        clipsToBounds = true
+        
+        let path = UIBezierPath(roundedRect: bounds.insetBy(dx: 0.5, dy: 0.5), cornerRadius: bounds.width / roundness)
+        let mask = CAShapeLayer()
+        
+        mask.path = path.cgPath
+        layer.mask = mask
+    }
+    
+    func clearLayerMask() {
+        
+        layer.cornerRadius = 0
+        layer.borderWidth = 0
+        layer.borderColor = nil
+        layer.backgroundColor = nil
+        
+        clipsToBounds = false
+        
+        mask = nil
+        layer.mask = nil
+    }
+}

+ 7 - 17
iOSClient/Favorites/NCFavorite.swift

@@ -31,9 +31,9 @@ class NCFavorite: NCCollectionViewCommon  {
         
         appDelegate.activeFavorite = self
         titleCurrentFolder = NSLocalizedString("_favorites_", comment: "")
-        layoutKey = k_layout_view_favorite
+        layoutKey = NCBrandGlobal.shared.layoutViewFavorite
         enableSearchBar = true
-        emptyImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 300, height: 300, color: NCBrandColor.shared.yellowFavorite)
+        emptyImage = UIImage.init(named: "favorite")?.image(color: NCBrandColor.shared.yellowFavorite, size: UIScreen.main.bounds.width)
         emptyTitle = "_favorite_no_files_"
         emptyDescription = "_tutorial_favorite_view_"
     }
@@ -76,18 +76,9 @@ class NCFavorite: NCCollectionViewCommon  {
         
         if serverUrl == "" {
             
-            NCNetworking.shared.listingFavoritescompletion(selector: selectorListingFavorite) { (account, metadatas, errorCode, errorDescription) in
-                if errorCode == 0 {
-                    for metadata in metadatas ?? [] {
-                        if !metadata.directory && CCUtility.getFavoriteOffline() {
-                            let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                            if localFile == nil || localFile?.etag != metadata.etag {
-                                NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
-                            }
-                        }
-                    }
-                } else {
-                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+            NCNetworking.shared.listingFavoritescompletion(selector: NCBrandGlobal.shared.selectorListingFavorite) { (account, metadatas, errorCode, errorDescription) in
+                if errorCode != 0 {
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 }
                 
                 self.refreshControl.endRefreshing()
@@ -101,9 +92,8 @@ class NCFavorite: NCCollectionViewCommon  {
                 if errorCode == 0 {
                     for metadata in metadatas ?? [] {
                         if !metadata.directory {
-                            let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                            if (CCUtility.getFavoriteOffline() && localFile == nil) || (localFile != nil && localFile?.etag != metadata.etag) {
-                                NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                            if NCManageDatabase.shared.isDownloadMetadata(metadata, download: false) {
+                                NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                             }
                         }
                     }

+ 6 - 7
iOSClient/FileViewInFolder/NCFileViewInFolder.swift

@@ -33,16 +33,16 @@ class NCFileViewInFolder: NCCollectionViewCommon  {
         
         appDelegate.activeFileViewInFolder = self
         titleCurrentFolder = NCBrandOptions.shared.brand
-        layoutKey = k_layout_view_viewInFolder
+        layoutKey = NCBrandGlobal.shared.layoutViewViewInFolder
         enableSearchBar = false
-        emptyImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 300, height: 300, color: NCBrandColor.shared.brandElement)
+        emptyImage = UIImage.init(named: "folder")?.image(color: NCBrandColor.shared.brandElement, size: UIScreen.main.bounds.width)
         emptyTitle = "_files_no_files_"
         emptyDescription = "_no_file_pull_down_"
     }
     
     override func viewWillAppear(_ animated: Bool) {
                 
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             self.navigationItem.title = NCBrandOptions.shared.brand
         } else {
             self.navigationItem.title = (serverUrl as NSString).lastPathComponent
@@ -54,7 +54,7 @@ class NCFileViewInFolder: NCCollectionViewCommon  {
         (layout, sort, ascending, groupBy, directoryOnTop, titleButton, itemForLine) = NCUtility.shared.getLayoutForView(key: layoutKey, serverUrl: serverUrl)
         gridLayout.itemForLine = CGFloat(itemForLine)
         
-        if layout == k_layout_list {
+        if layout == NCBrandGlobal.shared.layoutList {
             collectionView?.collectionViewLayout = listLayout
         } else {
             collectionView?.collectionViewLayout = gridLayout
@@ -132,9 +132,8 @@ class NCFileViewInFolder: NCCollectionViewCommon  {
             if errorCode == 0 {
                 for metadata in metadatas ?? [] {
                     if !metadata.directory {
-                        let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                        if (CCUtility.getFavoriteOffline() && localFile == nil) || (localFile != nil && localFile?.etag != metadata.etag) {
-                            NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                        if NCManageDatabase.shared.isDownloadMetadata(metadata, download: false) {
+                            NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                         }
                     }
                 }

+ 11 - 12
iOSClient/Files/NCFiles.swift

@@ -33,9 +33,9 @@ class NCFiles: NCCollectionViewCommon  {
         
         appDelegate.activeFiles = self
         titleCurrentFolder = NCBrandOptions.shared.brand
-        layoutKey = k_layout_view_files
+        layoutKey = NCBrandGlobal.shared.layoutViewFiles
         enableSearchBar = true
-        emptyImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 300, height: 300, color: NCBrandColor.shared.brandElement)
+        emptyImage = UIImage.init(named: "folder")?.image(color: NCBrandColor.shared.brandElement, size: UIScreen.main.bounds.width)
         emptyTitle = "_files_no_files_"
         emptyDescription = "_no_file_pull_down_"
     }
@@ -43,7 +43,7 @@ class NCFiles: NCCollectionViewCommon  {
     override func viewWillAppear(_ animated: Bool) {
         
         if isRoot {
-            serverUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+            serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
         }
         
         super.viewWillAppear(animated)
@@ -54,7 +54,7 @@ class NCFiles: NCCollectionViewCommon  {
     override func initializeMain() {
         
         if isRoot {
-            serverUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+            serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
             reloadDataSourceNetwork(forced: true)
         }
         
@@ -68,18 +68,18 @@ class NCFiles: NCCollectionViewCommon  {
         
         DispatchQueue.global(qos: .background).async {
                         
-            if !self.isSearching {
+            if !self.isSearching && self.appDelegate.account != nil && self.appDelegate.urlBase != nil {
                 self.metadatasSource = 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, serverUrl:  self.serverUrl)
+                    self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, serverUrl: self.serverUrl)
                 }
             }
             
             self.dataSource = NCDataSource.init(metadatasSource: self.metadatasSource, sort: self.sort, ascending: self.ascending, directoryOnTop: self.directoryOnTop, favoriteOnTop: true, filterLivePhoto: true)
             
-            DispatchQueue.main.async {
-                self.refreshControl.endRefreshing()
-                self.collectionView.reloadData()                
+            DispatchQueue.main.async { [weak self] in
+                self?.refreshControl.endRefreshing()
+                self?.collectionView.reloadData()                
             }
         }
     }
@@ -99,9 +99,8 @@ class NCFiles: NCCollectionViewCommon  {
             if errorCode == 0 {
                 for metadata in metadatas ?? [] {
                     if !metadata.directory {
-                        let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                        if (CCUtility.getFavoriteOffline() && localFile == nil) || (localFile != nil && localFile?.etag != metadata.etag) {
-                            NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                        if NCManageDatabase.shared.isDownloadMetadata(metadata, download: false) {
+                            NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                         }
                     }
                 }

+ 0 - 23
iOSClient/Images.xcassets/CryptoCloud.imageset/Contents.json

@@ -1,23 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "filename" : "settingsCryptoCloud.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "settingsCryptoCloud@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "settingsCryptoCloud@3x.png",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

BIN
iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud.png


BIN
iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud@2x.png


BIN
iOSClient/Images.xcassets/CryptoCloud.imageset/settingsCryptoCloud@3x.png


+ 0 - 23
iOSClient/Images.xcassets/avatar.imageset/Contents.json

@@ -1,23 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "filename" : "avatar.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "avatar@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "avatar@3x.png",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

BIN
iOSClient/Images.xcassets/avatar.imageset/avatar.png


BIN
iOSClient/Images.xcassets/avatar.imageset/avatar@2x.png


BIN
iOSClient/Images.xcassets/avatar.imageset/avatar@3x.png


BIN
iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf


+ 12 - 0
iOSClient/Images.xcassets/avatarCredentials.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "filename" : "account-circle-outline.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
iOSClient/Images.xcassets/avatarCredentials.imageset/account-circle-outline.pdf


+ 1 - 1
iOSClient/Images.xcassets/avatarBN.imageset/Contents.json → iOSClient/Images.xcassets/copy.imageset/Contents.json

@@ -1,7 +1,7 @@
 {
   "images" : [
     {
-      "filename" : "avatarBN.pdf",
+      "filename" : "copy.svg",
       "idiom" : "universal"
     }
   ],

+ 1 - 0
iOSClient/Images.xcassets/copy.imageset/copy.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" /></svg>

+ 1 - 1
iOSClient/Images.xcassets/offline.imageset/Contents.json

@@ -1,7 +1,7 @@
 {
   "images" : [
     {
-      "filename" : "offline.pdf",
+      "filename" : "archive-arrow-down-outline.svg",
       "idiom" : "universal"
     }
   ],

+ 1 - 0
iOSClient/Images.xcassets/offline.imageset/archive-arrow-down-outline.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20 21H4V10H6V19H18V10H20V21M3 3H21V9H3V3M5 5V7H19V5M10.5 11V14H8L12 18L16 14H13.5V11" /></svg>

BIN
iOSClient/Images.xcassets/offline.imageset/offline.pdf


+ 0 - 2
iOSClient/Login/CCLogin.h

@@ -23,8 +23,6 @@
 
 #import <UIKit/UIKit.h>
 
-#import "UIImage+animatedGIF.h"
-
 @class NCLoginWeb;
 @class NCLoginQRCode;
 

+ 12 - 11
iOSClient/Login/CCLogin.m

@@ -24,6 +24,7 @@
 #import "CCLogin.h"
 #import "AppDelegate.h"
 #import "CCUtility.h"
+#import "NSNotificationCenter+MainThread.h"
 #import "NCBridgeSwift.h"
 
 @interface CCLogin () <NCLoginQRCodeDelegate>
@@ -82,7 +83,7 @@
     cancelButton.tintColor = textColor;
     
     // Base URL
-    _imageBaseUrl.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginURL"] multiplier:2 color:textColor];
+    _imageBaseUrl.image = [[UIImage imageNamed:@"loginURL"] imageWithColor:textColor size:50];
     _baseUrl.textColor = textColor;
     _baseUrl.tintColor = textColor;
     _baseUrl.placeholder = NSLocalizedString(@"_login_url_", nil);
@@ -92,7 +93,7 @@
     [self.baseUrl setDelegate:self];
     
     // User
-    _imageUser.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginUser"] multiplier:2 color:textColor];
+    _imageUser.image = [[UIImage imageNamed:@"loginUser"] imageWithColor:textColor size:50];
     _user.textColor = textColor;
     _user.tintColor = textColor;
     _user.placeholder = NSLocalizedString(@"_username_", nil);
@@ -103,7 +104,7 @@
     [self.user setDelegate:self];
 
     // Password
-    _imagePassword.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginPassword"] multiplier:2 color:textColor];
+    _imagePassword.image = [[UIImage imageNamed:@"loginPassword"] imageWithColor:textColor size:50];
     _password.textColor = textColor;
     _password.tintColor = textColor;
     _password.placeholder = NSLocalizedString(@"_password_", nil);
@@ -112,7 +113,7 @@
     [self.password setFont:[UIFont systemFontOfSize:13]];
     [self.password setDelegate:self];
 
-    [self.toggleVisiblePassword setImage:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"visiblePassword"] multiplier:2 color:textColor] forState:UIControlStateNormal];
+    [self.toggleVisiblePassword setImage:[[UIImage imageNamed:@"visiblePassword"] imageWithColor:textColor size:25] forState:UIControlStateNormal];
     
     // Login
     [self.login setTitle:NSLocalizedString(@"_login_", nil) forState:UIControlStateNormal] ;
@@ -133,7 +134,7 @@
     }
     
     // QrCode image
-    [self.qrCode setImage:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"qrcode"] width:100 height:100 color:textColor] forState:UIControlStateNormal];
+    [self.qrCode setImage:[[UIImage imageNamed:@"qrcode"] imageWithColor:textColor size:100] forState:UIControlStateNormal];
     
     NSArray *listAccount = [[NCManageDatabase shared] getAccounts];
     if ([listAccount count] == 0) {
@@ -215,7 +216,7 @@
                 }
                 
                 // Login Flow
-                else if (_user.hidden && _password.hidden && versionMajor >= k_flow_version_available) {
+                else if (_user.hidden && _password.hidden && versionMajor >= [[NCBrandGlobal shared] nextcloudVersion12]) {
                     
                     NCLoginWeb *activeLoginWeb = [[UIStoryboard storyboardWithName:@"CCLogin" bundle:nil] instantiateViewControllerWithIdentifier:@"NCLoginWeb"];
                     activeLoginWeb.urlBase = self.baseUrl.text;
@@ -224,7 +225,7 @@
                 }
                 
                 // NO Login Flow available
-                else if (versionMajor < k_flow_version_available) {
+                else if (versionMajor < [[NCBrandGlobal shared] nextcloudVersion12]) {
                     
                     [self.loginTypeView setHidden:YES];
                     
@@ -330,7 +331,7 @@
             self.login.enabled = NO;
             [self.activity startAnimating];
             
-            NSString *webDAV = [[NCUtility shared] getWebDAVWithAccount:appDelegate.account];
+            NSString *webDAV = [[NCUtilityFileSystem shared] getWebDAVWithAccount:appDelegate.account];
             NSString *serverUrl = [NSString stringWithFormat:@"%@/%@", url, webDAV];
             
             [[NCCommunication shared] checkServerWithServerUrl:serverUrl completionHandler:^(NSInteger errorCode, NSString *errorDescription) {
@@ -402,18 +403,18 @@
         [appDelegate settingAccount:tableAccount.account urlBase:tableAccount.urlBase user:tableAccount.user userID:tableAccount.userID password:[CCUtility getPassword:tableAccount.account]];
         
         if ([CCUtility getIntro]) {
-            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
             [self dismissViewControllerAnimated:YES completion:nil];
         } else {
             [CCUtility setIntro:YES];
             if (self.presentingViewController == nil) {
                 UIViewController *viewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateInitialViewController];
                 viewController.modalPresentationStyle = UIModalPresentationFullScreen;
-                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
                 appDelegate.window.rootViewController = viewController;
                 [appDelegate.window makeKeyWindow];
             } else {
-                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_initializeMain object:nil userInfo:nil];
+                [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:NCBrandGlobal.shared.notificationCenterInitializeMain object:nil userInfo:nil];
                 [self dismissViewControllerAnimated:YES completion:nil];
             }
         }

+ 6 - 6
iOSClient/Login/NCAppConfigView.swift

@@ -61,15 +61,15 @@ class NCAppConfigView: UIViewController {
         appDelegate.timerErrorNetworking.invalidate()
         
         guard let serverUrl = self.serverUrl else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
             return
         }
         guard let username = self.username else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
             return
         }
         guard let password = self.password else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
             return
         }
         
@@ -86,17 +86,17 @@ class NCAppConfigView: UIViewController {
                     NCManageDatabase.shared.addAccount(account, urlBase: serverUrl, user: username, password: token!)
                     
                     guard let tableAccount = NCManageDatabase.shared.setAccountActive(account) else {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+                        NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
                         self.dismiss(animated: true, completion: nil)
                         return
                     }
                     
                     self.appDelegate.settingAccount(account, urlBase: serverUrl, user: username, userID: tableAccount.userID, password: token!)
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_initializeMain)
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterInitializeMain)
                     
                     self.dismiss(animated: true) {}
                 } else {
-                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 }
             }
         }

+ 6 - 6
iOSClient/Login/NCLoginWeb.swift

@@ -62,12 +62,12 @@ class NCLoginWeb: UIViewController {
         webView!.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
         webView!.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
         
-        // ADD k_flowEndpoint for Web Flow
+        // ADD end point for Web Flow
         if urlBase != NCBrandOptions.shared.linkloginPreferredProviders {
             if loginFlowV2Available {
                 urlBase = loginFlowV2Login
             } else {
-                urlBase = urlBase + k_flowEndpoint
+                urlBase = urlBase + "/index.php/login/flow"
             }
         }
         
@@ -79,7 +79,7 @@ class NCLoginWeb: UIViewController {
         if let url = URL(string: urlBase) {
             loadWebPage(webView: webView!, url: url)
         } else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
         }
     }
     
@@ -235,7 +235,7 @@ extension NCLoginWeb: WKNavigationDelegate {
             
         if (CCUtility.getIntro()) {
             
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_initializeMain)
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterInitializeMain)
             self.dismiss(animated: true)
                 
         } else {
@@ -244,7 +244,7 @@ extension NCLoginWeb: WKNavigationDelegate {
             if (self.presentingViewController == nil) {
                 if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() {
                     viewController.modalPresentationStyle = .fullScreen
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_initializeMain)
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterInitializeMain)
                     viewController.view.alpha = 0
                     appDelegate.window.rootViewController = viewController
                     appDelegate.window.makeKeyAndVisible()
@@ -253,7 +253,7 @@ extension NCLoginWeb: WKNavigationDelegate {
                     }
                 }
             } else {
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_initializeMain)
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterInitializeMain)
                 self.dismiss(animated: true)
             }
         }

+ 1 - 1
iOSClient/Main/ActionSheetHeaderView/NCActionSheetHeader.swift

@@ -38,7 +38,7 @@ class NCActionSheetHeader: NSObject {
         
         // Header
         if isDirectory {
-            image = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), multiplier: 3, color: NCBrandColor.shared.brandElement)
+            image = UIImage.init(named: "folder")?.image(color: NCBrandColor.shared.brandElement, size: UIScreen.main.bounds.width)
         } else if iconName.count > 0 {
             image = UIImage.init(named: iconName)
         } else {

+ 280 - 26
iOSClient/Main/Colleaction Common/NCCollectionCommon.swift

@@ -64,31 +64,33 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
     // MARK: -
     
     @objc func createImagesThemingColor() {
+        
         images.cellFileImage = UIImage.init(named: "file")!
         
-        images.cellSharedImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "share"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
-        images.cellCanShareImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "share"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
-        images.cellShareByLinkImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "sharebylink"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
+        images.cellSharedImage = UIImage(named: "share")!.image(color: NCBrandColor.shared.graySoft, size: 50)
+        images.cellCanShareImage = UIImage(named: "share")!.image(color: NCBrandColor.shared.graySoft, size: 50)
+        images.cellShareByLinkImage = UIImage(named: "sharebylink")!.image(color: NCBrandColor.shared.graySoft, size: 50)
         
-        images.cellFavouriteImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 50, height: 50, color: NCBrandColor.shared.yellowFavorite)
-        images.cellCommentImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "comment"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
-        images.cellLivePhotoImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "livePhoto"), width: 50, height: 50, color: NCBrandColor.shared.textView)
+        images.cellFavouriteImage = UIImage(named: "favorite")!.image(color: NCBrandColor.shared.yellowFavorite, size: 50)
+        images.cellCommentImage = UIImage(named: "comment")!.image(color: NCBrandColor.shared.graySoft, size: 50)
+        images.cellLivePhotoImage = UIImage(named: "livePhoto")!.image(color: NCBrandColor.shared.textView, size: 50)
         images.cellOfflineFlag = UIImage.init(named: "offlineFlag")!
         images.cellLocal = UIImage.init(named: "local")!
             
-        images.cellFolderEncryptedImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folderEncrypted"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderSharedWithMeImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder_shared_with_me"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderPublicImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder_public"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderGroupImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder_group"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderExternalImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder_external"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderAutomaticUploadImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folderAutomaticUpload"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        images.cellFolderImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 600, height: 600, color: NCBrandColor.shared.brandElement)
-        
-        images.cellCheckedYes = CCGraphics.changeThemingColorImage(UIImage.init(named: "checkedYes"), width: 50, height: 50, color: .darkGray)
-        images.cellCheckedNo = CCGraphics.changeThemingColorImage(UIImage.init(named: "checkedNo"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
-        
-        images.cellButtonMore = CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
-        images.cellButtonStop = CCGraphics.changeThemingColorImage(UIImage.init(named: "stop"), width: 50, height: 50, color: NCBrandColor.shared.graySoft)
+        let folderWidth: CGFloat = UIScreen.main.bounds.width / 3
+        images.cellFolderEncryptedImage = UIImage(named: "folderEncrypted")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderSharedWithMeImage = UIImage(named: "folder_shared_with_me")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderPublicImage = UIImage(named: "folder_public")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderGroupImage = UIImage(named: "folder_group")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderExternalImage = UIImage(named: "folder_external")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderAutomaticUploadImage = UIImage(named: "folderAutomaticUpload")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        images.cellFolderImage =  UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: folderWidth)
+        
+        images.cellCheckedYes = UIImage(named: "checkedYes")!.image(color: .darkGray, size: 50)
+        images.cellCheckedNo = UIImage(named: "checkedNo")!.image(color: NCBrandColor.shared.graySoft, size: 50)
+        
+        images.cellButtonMore = UIImage(named: "more")!.image(color: NCBrandColor.shared.graySoft, size: 50)
+        images.cellButtonStop = UIImage(named: "stop")!.image(color: NCBrandColor.shared.graySoft, size: 50)
     }
     
     // MARK: - NCSelect + Delegate
@@ -104,7 +106,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
         }
     }
 
-    func openSelectView(items: [Any]) {
+    func openSelectView(items: [Any], viewController: UIViewController) {
         
         let navigationController = UIStoryboard.init(name: "NCSelect", bundle: nil).instantiateInitialViewController() as! UINavigationController
         let topViewController = navigationController.topViewController as! NCSelect
@@ -115,7 +117,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
             copyItems.append(item)
         }
         
-        let homeUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+        let homeUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
         var serverUrl = (copyItems[0] as! Nextcloud.tableMetadata).serverUrl
         
         // Setup view controllers such that the current view is of the same directory the items to be copied are in
@@ -151,7 +153,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
             listViewController.insert(vc, at: 0)
             
             if serverUrl != homeUrl {
-                serverUrl = NCUtility.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)
+                serverUrl = NCUtilityFileSystem.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)
             } else {
                 break
             }
@@ -160,7 +162,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
         navigationController.setViewControllers(listViewController, animated: false)
         navigationController.modalPresentationStyle = .formSheet
         
-        appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
+        viewController.present(navigationController, animated: true, completion: nil)
     }
     
     @objc func openFileViewInFolder(serverUrl: String, fileName: String) {
@@ -171,7 +173,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
         let topViewController = viewController
         var listViewController = [NCFileViewInFolder]()
         var serverUrl = serverUrl
-        let homeUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+        let homeUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
         
         while true {
             
@@ -194,7 +196,7 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
             listViewController.insert(vc, at: 0)
             
             if serverUrl != homeUrl {
-                serverUrl = NCUtility.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)
+                serverUrl = NCUtilityFileSystem.shared.deletingLastPathComponent(serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)
             } else {
                 break
             }
@@ -205,8 +207,253 @@ class NCCollectionCommon: NSObject, NCSelectDelegate {
         
         appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
     }
+    
+    // MARK: - Save Photo - Video - Live Photo
+    
+    func saveAlbum(metadata: tableMetadata) {
+        
+        let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+        let status = PHPhotoLibrary.authorizationStatus()
+
+        if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage && status == PHAuthorizationStatus.authorized {
+            
+            if let image = UIImage.init(contentsOfFile: fileNamePath) {
+                UIImageWriteToSavedPhotosAlbum(image, self, #selector(SaveAlbum(_:didFinishSavingWithError:contextInfo:)), nil)
+            } else {
+                NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorFileNotSaved)
+            }
+            
+        } else if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo && status == PHAuthorizationStatus.authorized {
+            
+            if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(fileNamePath) {
+                UISaveVideoAtPathToSavedPhotosAlbum(fileNamePath, self, #selector(SaveAlbum(_:didFinishSavingWithError:contextInfo:)), nil)
+            } else {
+                NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorFileNotSaved)
+            }
+            
+        } else if status != PHAuthorizationStatus.authorized {
+            
+            NCContentPresenter.shared.messageNotification("_access_photo_not_enabled_", description: "_access_photo_not_enabled_msg_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorFileNotSaved)
+        }
+    }
+    
+    @objc private func SaveAlbum(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
+        
+        if error != nil {
+            NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorFileNotSaved)
+        }
+    }
+    
+    func saveLivePhoto(metadata: tableMetadata, metadataMOV: tableMetadata) {
+        
+        if !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+            NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorSaveAlbumLivePhotoIMG)
+        }
+        
+        if !CCUtility.fileProviderStorageExists(metadataMOV.ocId, fileNameView: metadataMOV.fileNameView) {
+            NCOperationQueue.shared.download(metadata: metadataMOV, selector: NCBrandGlobal.shared.selectorSaveAlbumLivePhotoMOV)
+        }
+        
+        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && CCUtility.fileProviderStorageExists(metadataMOV.ocId, fileNameView: metadataMOV.fileNameView) {
+            saveLivePhotoToDisk(metadata: metadata, metadataMov: metadataMOV, progressView: nil, viewActivity: self.appDelegate.window.rootViewController?.view)
+        }
+    }
+    
+    func saveLivePhotoToDisk(metadata: tableMetadata, metadataMov: tableMetadata, progressView: UIProgressView?, viewActivity: UIView?) {
+        
+        let fileNameImage = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!)
+        let fileNameMov = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadataMov.ocId, fileNameView: metadataMov.fileNameView)!)
+        
+        if let view = viewActivity {
+            NCUtility.shared.startActivityIndicator(view: view)
+        }
+        
+        NCLivePhoto.generate(from: fileNameImage, videoURL: fileNameMov, progress: { progress in
+            DispatchQueue.main.async {
+                progressView?.progress = Float(progress)
+            }
+        }, completion: { livePhoto, resources in
+            NCUtility.shared.stopActivityIndicator()
+            progressView?.progress = 0
+            if resources != nil {
+                NCLivePhoto.saveToLibrary(resources!) { (result) in
+                    if !result {
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_livephoto_save_error_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
+                    }
+                }
+            } else {
+                NCContentPresenter.shared.messageNotification("_error_", description: "_livephoto_save_error_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
+            }
+        })
+    }
+    
+    // MARK: - Context Menu COnfiguration
+    
+    @available(iOS 13.0, *)
+    func contextMenuConfiguration(metadata: tableMetadata, viewController: UIViewController, enableDeleteLocal: Bool, enableViewInFolder: Bool) -> UIMenu {
+        
+        var titleDeleteConfirmFile = NSLocalizedString("_delete_file_", comment: "")
+        if metadata.directory { titleDeleteConfirmFile = NSLocalizedString("_delete_folder_", comment: "") }
+        var titleSave: String = NSLocalizedString("_save_selected_files_", comment: "")
+        let metadataMOV = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
+        if metadataMOV != nil {
+            titleSave = NSLocalizedString("_livephoto_save_", comment: "")
+        }
+        
+        let copy = UIAction(title: NSLocalizedString("_copy_file_", comment: ""), image: UIImage(systemName: "doc.on.doc") ) { action in
+            self.appDelegate.pasteboardOcIds = [metadata.ocId]
+            self.copyPasteboard()
+        }
+        
+        let detail = UIAction(title: NSLocalizedString("_details_", comment: ""), image: UIImage(systemName: "info") ) { action in
+            NCNetworkingNotificationCenter.shared.openShare(ViewController: viewController, metadata: metadata, indexPage: 0)
+        }
+        
+        let save = UIAction(title: titleSave, image: UIImage(systemName: "square.and.arrow.down")) { action in
+            if metadataMOV != nil {
+                NCCollectionCommon.shared.saveLivePhoto(metadata: metadata, metadataMOV: metadataMOV!)
+            } else {
+                if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+                    self.saveAlbum(metadata: metadata)
+                } else {
+                    NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorSaveAlbum)
+                }
+            }
+        }
+        
+        let viewInFolder = UIAction(title: NSLocalizedString("_view_in_folder_", comment: ""), image: UIImage(systemName: "arrow.forward.square")) { action in
+            NCCollectionCommon.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileName: metadata.fileName)
+        }
+        
+        let openIn = UIAction(title: NSLocalizedString("_open_in_", comment: ""), image: UIImage(systemName: "square.and.arrow.up") ) { action in
+            NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: NCBrandGlobal.shared.selectorOpenIn)
+        }
+        
+        let openQuickLook = UIAction(title: NSLocalizedString("_open_quicklook_", comment: ""), image: UIImage(systemName: "eye")) { action in
+            NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: NCBrandGlobal.shared.selectorLoadFileQuickLook)
+        }
+        
+        let open = UIMenu(title: NSLocalizedString("_open_", comment: ""), image: UIImage(systemName: "square.and.arrow.up"), children: [openIn, openQuickLook])
+        
+        let moveCopy = UIAction(title: NSLocalizedString("_move_or_copy_", comment: ""), image: UIImage(systemName: "arrow.up.right.square")) { action in
+            NCCollectionCommon.shared.openSelectView(items: [metadata], viewController: viewController)
+        }
+        
+        let deleteConfirmFile = UIAction(title: titleDeleteConfirmFile, image: UIImage(systemName: "trash"), attributes: .destructive) { action in
+            NCNetworking.shared.deleteMetadata(metadata, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, onlyLocal: false) { (errorCode, errorDescription) in
+                if errorCode != 0 {
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                }
+            }
+        }
+        
+        let deleteConfirmLocal = UIAction(title: NSLocalizedString("_remove_local_file_", comment: ""), image: UIImage(systemName: "trash"), attributes: .destructive) { action in
+            NCNetworking.shared.deleteMetadata(metadata, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, onlyLocal: true) { (errorCode, errorDescription) in
+            }
+        }
+        
+        var delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmLocal, deleteConfirmFile])
+        
+        if !enableDeleteLocal {
+            delete = UIMenu(title: NSLocalizedString("_delete_file_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmFile])
+        }
+        
+        if metadata.directory {
+            delete = UIMenu(title: NSLocalizedString("_delete_folder_", comment: ""), image: UIImage(systemName: "trash"), options: .destructive, children: [deleteConfirmFile])
+        }
+        
+        // ------ MENU -----
+        
+        if metadata.directory {
+             return UIMenu(title: "", children: [detail, moveCopy, delete])
+        }
+        
+        var children: [UIMenuElement] = [detail, open, moveCopy, copy, delete]
+
+        if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo {
+            children.insert(save, at: 2)
+        }
+        
+        if enableViewInFolder {
+            children.insert(viewInFolder, at: 5)
+        }
+        
+        return UIMenu(title: "", image: nil, identifier: nil, children: children)
+    }
+    
+    // MARK: - Copy & Paste
+
+    func copyPasteboard() {
+        
+        var metadatas: [tableMetadata] = []
+        var items = [[String : Any]]()
+        
+        for ocId in appDelegate.pasteboardOcIds {
+            if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId as? String) {
+                metadatas.append(metadata)
+            }
+        }
+        
+        for metadata in metadatas {
+            
+            if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+                do {
+                    // Get Data
+                    let data = try Data.init(contentsOf: URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)))
+                    // Pasteboard item
+                    if let unmanagedFileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (metadata.fileNameView as NSString).pathExtension as CFString, nil) {
+                        let fileUTI = unmanagedFileUTI.takeRetainedValue() as String
+                        items.append([fileUTI:data])
+                    }
+                } catch {
+                    print("error")
+                }
+            } else {
+                NCNetworking.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorLoadCopy) { (_) in }
+            }
+        }
+        
+        UIPasteboard.general.setItems(items, options: [:])
+    }
+
+    func pastePasteboard(serverUrl: String) {
+                
+        for (index, items) in UIPasteboard.general.items.enumerated() {
+            for item in items {
+                let pasteboardType = item.key
+                if let data = UIPasteboard.general.data(forPasteboardType: pasteboardType, inItemSet: IndexSet([index]))?.first {
+                    let results = NCCommunicationCommon.shared.getDescriptionFile(inUTI: pasteboardType as CFString)
+                    if results.resultTypeFile != NCCommunicationCommon.typeFile.unknow.rawValue {
+                        uploadPasteFile(fileName: results.resultFilename, ext: results.resultExtension, contentType: pasteboardType, serverUrl: serverUrl, data: data)
+                    }
+                }
+            }
+        }
+    }
+
+    private func uploadPasteFile(fileName: String, ext: String, contentType: String, serverUrl: String, data: Data) {
+        
+        do {
+            let fileNameView = fileName + "_" + CCUtility.getIncrementalNumber() + "." + ext
+            let ocId = UUID().uuidString
+            let filePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
+            
+            try data.write(to: URL(fileURLWithPath: filePath))
+           
+            let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: fileNameView, ocId: ocId, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: contentType, livePhoto: false)
+            
+            metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
+            metadataForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
+            metadataForUpload.size = NCUtilityFileSystem.shared.getFileSize(filePath: filePath)
+            metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
+            
+            NCManageDatabase.shared.addMetadata(metadataForUpload)
+            
+        } catch { }
+    }
 }
 
+
 // MARK: - List Layout
 
 class NCListLayout: UICollectionViewFlowLayout {
@@ -256,6 +503,7 @@ class NCGridLayout: UICollectionViewFlowLayout {
     var heightLabelPlusButton: CGFloat = 45
     var marginLeftRight: CGFloat = 6
     var itemForLine: CGFloat = 3
+    var itemWidthDefault: CGFloat = 120
 
     override init() {
         super.init()
@@ -277,6 +525,12 @@ class NCGridLayout: UICollectionViewFlowLayout {
         get {
             if let collectionView = collectionView {
                 
+                if collectionView.frame.width < 400 {
+                    itemForLine = 3
+                } else {
+                    itemForLine = collectionView.frame.width / itemWidthDefault
+                }
+                
                 let itemWidth: CGFloat = (collectionView.frame.width - marginLeftRight * 2 - marginLeftRight * (itemForLine - 1)) / itemForLine
                 let itemHeight: CGFloat = itemWidth + heightLabelPlusButton
                 
@@ -284,7 +538,7 @@ class NCGridLayout: UICollectionViewFlowLayout {
             }
             
             // Default fallback
-            return CGSize(width: 100, height: 100)
+            return CGSize(width: itemWidthDefault, height: itemWidthDefault)
         }
         set {
             super.itemSize = newValue

+ 143 - 304
iOSClient/Main/Colleaction Common/NCCollectionViewCommon.swift

@@ -24,8 +24,8 @@
 import Foundation
 import NCCommunication
 
-class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, UIAdaptivePresentationControllerDelegate, NCEmptyDataSetDelegate  {
-
+class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, NCListCellDelegate, NCGridCellDelegate, NCSectionHeaderMenuDelegate, UIAdaptivePresentationControllerDelegate, NCEmptyDataSetDelegate, UIContextMenuInteractionDelegate  {
+    
     @IBOutlet weak var collectionView: UICollectionView!
 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
@@ -91,7 +91,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         if enableSearchBar {
             searchController = UISearchController(searchResultsController: nil)
             searchController?.searchResultsUpdater = self
-            searchController?.dimsBackgroundDuringPresentation = false
+            searchController?.obscuresBackgroundDuringPresentation = false
             searchController?.delegate = self
             searchController?.searchBar.delegate = self
             navigationItem.searchController = searchController
@@ -122,11 +122,6 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         // Empty
         emptyDataSet = NCEmptyDataSet.init(view: collectionView, offset: 0, delegate: self)
         
-        // 3D Touch peek and pop
-        if traitCollection.forceTouchCapability == .available {
-            registerForPreviewing(with: self, sourceView: view)
-        }
-        
         // Long Press on CollectionView
         let longPressedGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressCollecationView(_:)))
         longPressedGesture.minimumPressDuration = 0.5
@@ -136,29 +131,29 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         
         // Notification
         
-        NotificationCenter.default.addObserver(self, selector: #selector(initializeMain), name: NSNotification.Name(rawValue: k_notificationCenter_initializeMain), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSource), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSourceNetworkForced(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_reloadDataSourceNetworkForced), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(changeStatusFolderE2EE(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_changeStatusFolderE2EE), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(closeRichWorkspaceWebView), name: NSNotification.Name(rawValue: k_notificationCenter_closeRichWorkspaceWebView), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(initializeMain), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterInitializeMain), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSource(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterReloadDataSource), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataSourceNetworkForced(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterReloadDataSourceNetworkForced), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeStatusFolderE2EE(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeStatusFolderE2EE), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(closeRichWorkspaceWebView), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterCloseRichWorkspaceWebView), object: nil)
 
-        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_deleteFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_moveFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(copyFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_copyFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_renameFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(createFolder(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_createFolder), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(favoriteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_favoriteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDeleteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterMoveFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(copyFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterCopyFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterRenameFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(createFolder(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterCreateFolder), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(favoriteFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterFavoriteFile), object: nil)
 
-        NotificationCenter.default.addObserver(self, selector: #selector(downloadStartFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_downloadStartFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_downloadedFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(downloadCancelFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_downloadCancelFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(downloadStartFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDownloadStartFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDownloadedFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(downloadCancelFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDownloadCancelFile), object: nil)
 
-        NotificationCenter.default.addObserver(self, selector: #selector(uploadStartFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_uploadStartFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_uploadedFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(uploadCancelFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_uploadCancelFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(uploadStartFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterUploadStartFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterUploadedFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(uploadCancelFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterUploadCancelFile), object: nil)
 
-        NotificationCenter.default.addObserver(self, selector: #selector(triggerProgressTask(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_progressTask), object:nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(triggerProgressTask(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterProgressTask), object:nil)
 
         changeTheming()
     }
@@ -169,7 +164,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         appDelegate.activeViewController = self
 
         if serverUrl == "" {
-            appDelegate.activeServerUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+            appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
         } else {
             appDelegate.activeServerUrl = serverUrl
         }
@@ -177,7 +172,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         (layout, sort, ascending, groupBy, directoryOnTop, titleButton, itemForLine) = NCUtility.shared.getLayoutForView(key: layoutKey, serverUrl: serverUrl)
         gridLayout.itemForLine = CGFloat(itemForLine)
         
-        if layout == k_layout_list {
+        if layout == NCBrandGlobal.shared.layoutList {
             collectionView?.collectionViewLayout = listLayout
         } else {
             collectionView?.collectionViewLayout = gridLayout
@@ -245,7 +240,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         // set active serverUrl
         if self.view?.window != nil {
             if serverUrl == "" {
-                appDelegate.activeServerUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+                appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
             } else {
                 appDelegate.activeServerUrl = serverUrl
             }
@@ -304,7 +299,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             if let ocId = userInfo["ocId"] as? String, let fileNameView = userInfo["fileNameView"] as? String, let onlyLocal = userInfo["onlyLocal"] as? Bool {
                 if onlyLocal {
                     reloadDataSource()
-                } else if fileNameView.lowercased() == k_fileNameRichWorkspace.lowercased() {
+                } else if fileNameView.lowercased() == NCBrandGlobal.shared.fileNameRichWorkspace.lowercased() {
                     reloadDataSourceNetwork(forced: true)
                 } else {
                     if let row = dataSource.deleteMetadata(ocId: ocId) {
@@ -508,9 +503,9 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                 let _ = userInfo["serverUrl"] as? String ?? ""
                 let progressNumber = userInfo["progress"] as? NSNumber ?? 0
                 let progress = progressNumber.floatValue
-                let status = userInfo["status"] as? Int ?? Int(k_metadataStatusNormal)
-                let totalBytes = userInfo["totalBytes"] as? Double ?? 0
-                let totalBytesExpected = userInfo["totalBytesExpected"] as? Double ?? 0
+                let status = userInfo["status"] as? Int ?? NCBrandGlobal.shared.metadataStatusNormal
+                let totalBytes = userInfo["totalBytes"] as? Int64 ?? 0
+                let totalBytesExpected = userInfo["totalBytesExpected"] as? Int64 ?? 0
                 
                 appDelegate.listProgressMetadata.setObject([progress as NSNumber, totalBytes as NSNumber, totalBytesExpected as NSNumber], forKey: userInfo["ocId"] as? NSString ?? "")
                 
@@ -521,10 +516,10 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                             if progress > 0 {
                                 cell.progressView?.isHidden = false
                                 cell.progressView?.progress = progress
-                                cell.setButtonMore(named: k_buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
-                                if status == k_metadataStatusInDownload {
+                                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
+                                if status == NCBrandGlobal.shared.metadataStatusInDownload {
                                     cell.labelInfo.text = CCUtility.transformedSize(totalBytesExpected) + " - ↓ " + CCUtility.transformedSize(totalBytes)
-                                } else if status == k_metadataStatusInUpload {
+                                } else if status == NCBrandGlobal.shared.metadataStatusInUpload {
                                     cell.labelInfo.text = CCUtility.transformedSize(totalBytesExpected) + " - ↑ " + CCUtility.transformedSize(totalBytes)
                                 }
                             }
@@ -533,10 +528,10 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                             if progress > 0 {
                                 cell.progressView?.isHidden = false
                                 cell.progressView?.progress = progress
-                                cell.setButtonMore(named: k_buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
-                                if status == k_metadataStatusInDownload {
+                                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
+                                if status == NCBrandGlobal.shared.metadataStatusInDownload {
                                     cell.labelInfo.text = CCUtility.transformedSize(totalBytesExpected) + " - ↓ " + CCUtility.transformedSize(totalBytes)
-                                } else if status == k_metadataStatusInUpload {
+                                } else if status == NCBrandGlobal.shared.metadataStatusInUpload {
                                     cell.labelInfo.text = CCUtility.transformedSize(totalBytesExpected) + " - ↑ " + CCUtility.transformedSize(totalBytes)
                                 }
                             }
@@ -545,7 +540,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                             if progress > 0 {
                                 cell.progressView.isHidden = false
                                 cell.progressView.progress = progress
-                                cell.setButtonMore(named: k_buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
+                                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
                             }
                         }
                     }
@@ -557,9 +552,9 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     // MARK: - Empty
     
     func emptyDataSetView(_ view: NCEmptyView) {
-        
+                
         if searchController?.isActive ?? false {
-            view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "search"), width: 300, height: 300, color: .gray)
+            view.emptyImage.image = UIImage.init(named: "search")?.image(color: .gray, size: UIScreen.main.bounds.width)
             if isReloadDataSourceNetworkInProgress {
                 view.emptyTitle.text = NSLocalizedString("_search_in_progress_", comment: "")
             } else {
@@ -567,7 +562,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             }
             view.emptyDescription.text = NSLocalizedString("_search_instruction_", comment: "")
         } else if isReloadDataSourceNetworkInProgress {
-            view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "networkInProgress"), width: 300, height: 300, color: .gray)
+            view.emptyImage.image = UIImage.init(named: "networkInProgress")?.image(color: .gray, size: UIScreen.main.bounds.width)
             view.emptyTitle.text = NSLocalizedString("_request_in_progress_", comment: "")
             view.emptyDescription.text = ""
         } else {
@@ -576,7 +571,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                 view.emptyTitle.text = NSLocalizedString(emptyTitle, comment: "")
                 view.emptyDescription.text = NSLocalizedString(emptyDescription, comment: "")
             } else {
-                view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 300, height: 300, color: NCBrandColor.shared.brandElement)
+                view.emptyImage.image = UIImage.init(named: "folder")?.image(color: NCBrandColor.shared.brandElement, size: UIScreen.main.bounds.width)
                 view.emptyTitle.text = NSLocalizedString("_files_no_files_", comment: "")
                 view.emptyDescription.text = NSLocalizedString("_no_file_pull_down_", comment: "")
             }
@@ -629,7 +624,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                     self.collectionView.reloadData()
                 })
             })
-            layout = k_layout_list
+            layout = NCBrandGlobal.shared.layoutList
             NCUtility.shared.setLayoutForView(key: layoutKey, serverUrl: serverUrl, layout: layout)
         } else {
             // grid layout
@@ -639,7 +634,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                     self.collectionView.reloadData()
                 })
             })
-            layout = k_layout_grid
+            layout = NCBrandGlobal.shared.layoutGrid
             NCUtility.shared.setLayoutForView(key: layoutKey, serverUrl: serverUrl, layout: layout)
         }
     }
@@ -677,9 +672,9 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
 
         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(objectId) else { return }
 
-        if namedButtonMore == k_buttonMoreMore {
+        if namedButtonMore == NCBrandGlobal.shared.buttonMoreMore {
             toggleMoreMenu(viewController: self, metadata: metadata)
-        } else if namedButtonMore == k_buttonMoreStop {
+        } else if namedButtonMore == NCBrandGlobal.shared.buttonMoreStop {
             NCNetworking.shared.cancelTransferMetadata(metadata) { }
         }
     }
@@ -698,11 +693,9 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     }
     
     func longPressListItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {
-        openMenuItems(with: objectId, gestureRecognizer: gestureRecognizer)
     }
     
     func longPressGridItem(with objectId: String, gestureRecognizer: UILongPressGestureRecognizer) {
-        openMenuItems(with: objectId, gestureRecognizer: gestureRecognizer)
     }
     
     func longPressMoreListItem(with objectId: String, namedButtonMore: String, gestureRecognizer: UILongPressGestureRecognizer) {
@@ -712,7 +705,31 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     }
     
     @objc func longPressCollecationView(_ gestureRecognizer: UILongPressGestureRecognizer) {
+        
         openMenuItems(with: nil, gestureRecognizer: gestureRecognizer)
+        /*
+        if #available(iOS 13.0, *) {
+            
+            let interaction = UIContextMenuInteraction(delegate: self)
+            self.view.addInteraction(interaction)
+        }
+        */
+    }
+    
+    @available(iOS 13.0, *)
+    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
+        
+        return UIContextMenuConfiguration(identifier: nil, previewProvider: {
+            
+            return nil
+            
+        }, actionProvider: { suggestedActions in
+            
+            //let share = UIAction(title: "Share Pupper", image: UIImage(systemName: "square.and.arrow.up")) { action in
+            //}
+            //return UIMenu(title: "Main Menu", children: [share])
+            return nil
+        })
     }
     
     func openMenuItems(with objectId: String?, gestureRecognizer: UILongPressGestureRecognizer) {
@@ -731,18 +748,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
         
         becomeFirstResponder()
                 
-        if metadataTouch != nil {
-            listMenuItems.append(UIMenuItem.init(title: NSLocalizedString("_copy_file_", comment: ""), action: #selector(copyFileMenu(_:))))
-        }
-        
-        listMenuItems.append(UIMenuItem.init(title: NSLocalizedString("_paste_file_", comment: ""), action: #selector(pasteFilesMenu(_:))))
-        
-        if metadataTouch != nil {
-            listMenuItems.append(UIMenuItem.init(title: NSLocalizedString("_open_quicklook_", comment: ""), action: #selector(openQuickLookMenu(_:))))
-            if !NCBrandOptions.shared.disable_openin_file {
-                listMenuItems.append(UIMenuItem.init(title: NSLocalizedString("_open_in_", comment: ""), action: #selector(openInMenu(_:))))
-            }
-        }
+        listMenuItems.append(UIMenuItem.init(title: NSLocalizedString("_paste_file_", comment: ""), action: #selector(pasteFilesMenu)))
         
         if listMenuItems.count > 0 {
             UIMenuController.shared.menuItems = listMenuItems
@@ -755,156 +761,17 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     
     override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
         
-        if (#selector(pasteFilesMenu(_:)) == action) {
+        if (#selector(pasteFilesMenu) == action) {
             if UIPasteboard.general.items.count > 0 {
                 return true
             }
         }
         
-        if (#selector(openQuickLookMenu(_:)) == action || #selector(openInMenu(_:)) == action || #selector(copyFileMenu(_:)) == action) {
-            guard let metadata = metadataTouch else { return false }
-            if !metadata.directory && metadata.status == k_metadataStatusNormal {
-                return true
-            }
-        }
-
         return false
     }
     
-    @objc func copyFileMenu(_ notification: Any) {
-        var metadatas: [tableMetadata] = []
-        var items = [[String : Any]]()
-
-        if isEditMode {
-            for ocId in selectOcId {
-                if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                    metadatas.append(metadata)
-                }
-            }
-        } else {
-            guard let metadata = metadataTouch else { return }
-            metadatas.append(metadata)
-        }
-                
-        for metadata in metadatas {
-            
-            if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-                do {
-                    let etagPasteboard = try NSKeyedArchiver.archivedData(withRootObject: metadata.ocId, requiringSecureCoding: false)
-                    items.append([k_metadataKeyedUnarchiver:etagPasteboard])
-                } catch {
-                    print("error")
-                }
-            } else {
-                NCNetworking.shared.download(metadata: metadata, selector: selectorLoadCopy, setFavorite: false) { (_) in }
-            }
-        }
-        
-        UIPasteboard.general.setItems(items, options: [:])
-        
-        if isEditMode {
-            tapSelect(sender: self)
-        }
-    }
-    
-    @objc func pasteFilesMenu(_ notification: Any) {
-        
-        var listData: [String] = []
-        
-        for item in UIPasteboard.general.items {
-            for object in item {
-                let contentType = object.key
-                let data = object.value
-                if contentType == k_metadataKeyedUnarchiver {
-                    do {
-                        if let ocId = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data as! Data) as? String{
-                            uploadPasteOcId(ocId)
-                        }
-                    } catch {
-                        print("error")
-                    }
-                    continue
-                }
-                if data is String {
-                    if listData.contains(data as! String) {
-                        continue
-                    } else {
-                        listData.append(data as! String)
-                    }
-                }
-                let type = NCCommunicationCommon.shared.convertUTItoResultType(fileUTI: contentType as CFString)
-                if type.resultTypeFile != NCCommunicationCommon.typeFile.unknow.rawValue && type.resultExtension != "" {
-                    uploadPasteFile(fileName: type.resultFilename, ext: type.resultExtension, contentType: contentType, data: data)
-                }
-            }
-        }
-    }
-    
-    private func uploadPasteFile(fileName: String, ext: String, contentType: String, data: Any) {
-        do {
-            let fileNameView = fileName + "_" + CCUtility.getIncrementalNumber() + "." + ext
-            let ocId = UUID().uuidString
-            let filePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
-            
-            if data is UIImage {
-                try (data as? UIImage)?.jpegData(compressionQuality: 1)?.write(to: URL(fileURLWithPath: filePath))
-            } else if data is Data {
-                try (data as? Data)?.write(to: URL(fileURLWithPath: filePath))
-            } else if data is String {
-                try (data as? String)?.write(to: URL(fileURLWithPath: filePath), atomically: true, encoding: .utf8)
-            } else {
-                return
-            }
-            
-            let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: fileNameView, ocId: ocId, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: contentType, livePhoto: false)
-            
-            metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
-            metadataForUpload.sessionSelector = selectorUploadFile
-            metadataForUpload.size = Double(NCUtilityFileSystem.shared.getFileSize(filePath: filePath))
-            metadataForUpload.status = Int(k_metadataStatusWaitUpload)
-            
-            NCManageDatabase.shared.addMetadata(metadataForUpload)
-            
-        } catch { }
-    }
-    
-    private func uploadPasteOcId(_ ocId: String) {
-        if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-            if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-                let fileNameView = NCUtility.shared.createFileName(metadata.fileNameView, serverUrl: serverUrl, account: appDelegate.account)
-                let ocId = NSUUID().uuidString
-                
-                CCUtility.copyFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView), toPath: CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView))
-                let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: fileNameView, ocId: ocId, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "", livePhoto: false)
-                
-                metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
-                metadataForUpload.sessionSelector = selectorUploadFile
-                metadataForUpload.size = metadata.size
-                metadataForUpload.status = Int(k_metadataStatusWaitUpload)
-                
-                NCManageDatabase.shared.addMetadata(metadataForUpload)
-            }
-        }
-    }
-    
-    @objc func openQuickLookMenu(_ notification: Any) {
-        guard let metadata = metadataTouch else { return }
-                
-        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadedFile, userInfo: ["ocId": metadata.ocId, "selector": selectorLoadFileQuickLook, "errorCode": 0, "errorDescription": "" ])
-        } else {
-            NCNetworking.shared.download(metadata: metadata, selector: selectorLoadFileQuickLook) { (_) in }
-        }
-    }
-    
-    @objc func openInMenu(_ notification: Any) {
-        guard let metadata = metadataTouch else { return }
-                
-        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadedFile, userInfo: ["ocId": metadata.ocId, "selector": selectorOpenIn, "errorCode": 0, "errorDescription": "" ])
-        } else {
-            NCNetworking.shared.download(metadata: metadata, selector: selectorOpenIn) { (_) in }
-        }
+    @objc func pasteFilesMenu() {
+        NCCollectionCommon.shared.pastePasteboard(serverUrl: serverUrl)
     }
     
     // MARK: - DataSource + NC Endpoint
@@ -978,14 +845,14 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                                             
                                             if !NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata!, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: self.serverUrl, account: account, urlBase: self.appDelegate.urlBase) {
                                                 
-                                                NCContentPresenter.shared.messageNotification("_error_e2ee_", description: "_e2e_error_decode_metadata_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorDecodeMetadata), forced: true)
+                                                NCContentPresenter.shared.messageNotification("_error_e2ee_", description: "_e2e_error_decode_metadata_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorDecodeMetadata, forced: true)
                                             } else {
                                                 self.reloadDataSource()
                                             }
                                             
-                                        } else if errorCode != k_CCErrorResourceNotFound {
+                                        } else if errorCode != NCBrandGlobal.shared.ErrorResourceNotFound {
                                             
-                                            NCContentPresenter.shared.messageNotification("_error_e2ee_", description: "_e2e_error_decode_metadata_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorDecodeMetadata), forced: true)
+                                            NCContentPresenter.shared.messageNotification("_error_e2ee_", description: "_e2e_error_decode_metadata_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorDecodeMetadata, forced: true)
                                         }
                                         
                                         completion(metadatas, metadatasUpdate, errorCode, errorDescription)
@@ -1010,44 +877,6 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     }
 }
 
-// MARK: - 3D Touch peek and pop
-
-extension NCCollectionViewCommon: UIViewControllerPreviewingDelegate {
-    
-    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
-        
-        guard let point = collectionView?.convert(location, from: collectionView?.superview) else { return nil }
-        guard let indexPath = collectionView?.indexPathForItem(at: point) else { return nil }
-        guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return nil }
-        guard let viewController = UIStoryboard(name: "CCPeekPop", bundle: nil).instantiateViewController(withIdentifier: "PeekPopImagePreview") as? CCPeekPop else { return nil }
-
-        viewController.metadata = metadata
-
-        if layout == k_layout_grid {
-            guard let cell = collectionView?.cellForItem(at: indexPath) as? NCGridCell else { return nil }
-            previewingContext.sourceRect = cell.frame
-            viewController.imageFile = cell.imageItem.image
-        } else {
-            guard let cell = collectionView?.cellForItem(at: indexPath) as? NCListCell else { return nil }
-            previewingContext.sourceRect = cell.frame
-            viewController.imageFile = cell.imageItem.image
-        }
-        
-        viewController.showOpenIn = true
-        viewController.showOpenQuickLook = NCUtility.shared.isQuickLookDisplayable(metadata: metadata)
-        viewController.showShare = false
-        
-        return viewController
-    }
-    
-    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
-        
-        guard let indexPath = collectionView?.indexPathForItem(at: previewingContext.sourceRect.origin) else { return }
-        
-        collectionView(collectionView, didSelectItemAt: indexPath)
-    }
-}
-
 // MARK: - Collection View
 
 extension NCCollectionViewCommon: UICollectionViewDelegate {
@@ -1070,7 +899,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
         }
         
         if metadata.e2eEncrypted && !CCUtility.isEnd(toEndEnabled: appDelegate.account) {
-            NCContentPresenter.shared.messageNotification("_info_", description: "_e2e_goto_settings_for_enable_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorE2EENotEnabled), forced: true)
+            NCContentPresenter.shared.messageNotification("_info_", description: "_e2e_goto_settings_for_enable_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorE2EENotEnabled, forced: true)
             return
         }
         
@@ -1079,7 +908,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             guard let serverUrlPush = CCUtility.stringAppendServerUrl(metadataTouch!.serverUrl, addFileName: metadataTouch!.fileName) else { return }
             
             // FILES
-            if layoutKey == k_layout_view_files {
+            if layoutKey == NCBrandGlobal.shared.layoutViewFiles {
                 
                 if let viewController = appDelegate.listFilesVC.value(forKey: serverUrlPush) {
                     guard let vcFiles = (viewController as? NCFiles) else { return }
@@ -1103,7 +932,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             }
             
             // FAVORITE
-            if layoutKey == k_layout_view_favorite {
+            if layoutKey == NCBrandGlobal.shared.layoutViewFavorite {
             
                 if let viewController = appDelegate.listFavoriteVC.value(forKey: serverUrlPush) {
                     guard let vcFavorite = (viewController as? NCFavorite) else { return }
@@ -1126,7 +955,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             }
             
             // OFFLINE
-            if layoutKey == k_layout_view_offline {
+            if layoutKey == NCBrandGlobal.shared.layoutViewOffline {
                 
                 if let viewController = appDelegate.listOfflineVC.value(forKey: serverUrlPush) {
                     guard let vcOffline = (viewController as? NCOffline) else { return }
@@ -1149,7 +978,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             }
             
             // RECENT ( for push use Files ... he he he )
-            if layoutKey == k_layout_view_recent {
+            if layoutKey == NCBrandGlobal.shared.layoutViewRecent {
                 
                 if let viewController = appDelegate.listFilesVC.value(forKey: serverUrlPush) {
                     guard let vcFiles = (viewController as? NCFiles) else { return }
@@ -1173,7 +1002,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             }
             
             //VIEW IN FOLDER
-            if layoutKey == k_layout_view_viewInFolder {
+            if layoutKey == NCBrandGlobal.shared.layoutViewViewInFolder {
                 
                 let vcFileViewInFolder:NCFileViewInFolder = UIStoryboard(name: "NCFileViewInFolder", bundle: nil).instantiateInitialViewController() as! NCFileViewInFolder
                 
@@ -1184,7 +1013,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             }
             
             // SHARES ( for push use Files ... he he he )
-            if layoutKey == k_layout_view_shares {
+            if layoutKey == NCBrandGlobal.shared.layoutViewShares {
                 
                 if let viewController = appDelegate.listFilesVC.value(forKey: serverUrlPush) {
                     guard let vcFiles = (viewController as? NCFiles) else { return }
@@ -1211,28 +1040,10 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             
             guard let metadataTouch = metadataTouch else { return }
             
-            if metadata.typeFile == k_metadataTypeFile_document && NCUtility.shared.isDirectEditing(account: metadata.account, contentType: metadata.contentType) != nil {
-                if NCCommunication.shared.isNetworkReachable() {
-                    NCViewer.shared.view(viewController: self, metadata: metadataTouch, metadatas: [metadataTouch])
-                } else {
-                    NCContentPresenter.shared.messageNotification("_info_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorOffline), forced: true)
-                }
-                return
-            }
-            
-            if metadata.typeFile == k_metadataTypeFile_document && NCUtility.shared.isRichDocument(metadata) {
-                if NCCommunication.shared.isNetworkReachable() {
-                    NCViewer.shared.view(viewController: self, metadata: metadataTouch, metadatas: [metadataTouch])
-                } else {
-                    NCContentPresenter.shared.messageNotification("_info_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorOffline), forced: true)
-                }
-                return
-            }
-            
-            if metadata.typeFile == k_metadataTypeFile_image || metadata.typeFile == k_metadataTypeFile_video || metadata.typeFile == k_metadataTypeFile_audio {
+            if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileAudio {
                 var metadatas: [tableMetadata] = []
                 for metadata in dataSource.metadatas {
-                    if metadata.typeFile == k_metadataTypeFile_image || metadata.typeFile == k_metadataTypeFile_video || metadata.typeFile == k_metadataTypeFile_audio {
+                    if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileAudio {
                         metadatas.append(metadata)
                     }
                 }
@@ -1242,8 +1053,10 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             
             if CCUtility.fileProviderStorageExists(metadataTouch.ocId, fileNameView: metadataTouch.fileNameView) {
                 NCViewer.shared.view(viewController: self, metadata: metadataTouch, metadatas: [metadataTouch])
+            } else if NCCommunication.shared.isNetworkReachable() {
+                NCNetworking.shared.download(metadata: metadataTouch, selector: NCBrandGlobal.shared.selectorLoadFileView) { (_) in }
             } else {
-                NCNetworking.shared.download(metadata: metadataTouch, selector: selectorLoadFileView) { (_) in }
+                NCContentPresenter.shared.messageNotification("_info_", description: "_go_online_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorOffline, forced: true)
             }
         }
     }
@@ -1255,6 +1068,33 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
         }
         collectionView.reloadData()
     }
+    
+    @available(iOS 13.0, *)
+    func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
+        
+        guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return nil }
+        metadataTouch = metadata
+        let identifier = indexPath as NSCopying
+
+        return UIContextMenuConfiguration(identifier: identifier, previewProvider: {
+            
+            return NCViewerProviderContextMenu(metadata: metadata)
+            
+        }, actionProvider: { suggestedActions in
+            
+            return NCCollectionCommon.shared.contextMenuConfiguration(metadata: metadata, viewController: self, enableDeleteLocal: true, enableViewInFolder: false)
+        })
+    }
+    
+    @available(iOS 13.0, *)
+    func collectionView(_ collectionView: UICollectionView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
+        animator.addCompletion {
+
+            if let indexPath = configuration.identifier as? IndexPath {
+                self.collectionView(collectionView, didSelectItemAt: indexPath)
+            }
+        }
+    }
 }
 
 extension NCCollectionViewCommon: UICollectionViewDataSource {
@@ -1276,9 +1116,9 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
             let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeaderMenu", for: indexPath) as! NCSectionHeaderMenu
             
             if collectionView.collectionViewLayout == gridLayout {
-                header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), width: 100, height: 100, color: NCBrandColor.shared.icon), for: .normal)
+                header.buttonSwitch.setImage(UIImage.init(named: "switchList")!.image(color: NCBrandColor.shared.icon, size: 50), for: .normal)
             } else {
-                header.buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchGrid"), width: 100, height: 100, color: NCBrandColor.shared.icon), for: .normal)
+                header.buttonSwitch.setImage(UIImage.init(named: "switchGrid")!.image(color: NCBrandColor.shared.icon, size: 50), for: .normal)
             }
             
             header.delegate = self
@@ -1313,7 +1153,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                 
         guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else {
-            if layout == k_layout_list {
+            if layout == NCBrandGlobal.shared.layoutList {
                 return collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
             } else {
                 return collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
@@ -1325,8 +1165,8 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         var isMounted = false
                 
         if metadataFolder != nil {
-            isShare = metadata.permissions.contains(k_permission_shared) && !metadataFolder!.permissions.contains(k_permission_shared)
-            isMounted = metadata.permissions.contains(k_permission_mounted) && !metadataFolder!.permissions.contains(k_permission_mounted)
+            isShare = metadata.permissions.contains(NCBrandGlobal.shared.permissionShared) && !metadataFolder!.permissions.contains(NCBrandGlobal.shared.permissionShared)
+            isMounted = metadata.permissions.contains(NCBrandGlobal.shared.permissionMounted) && !metadataFolder!.permissions.contains(NCBrandGlobal.shared.permissionMounted)
         }
         
         if dataSource.metadataShare[metadata.ocId] != nil {
@@ -1336,7 +1176,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         //
         // LAYOUT LIST
         //
-        if layout == k_layout_list {
+        if layout == NCBrandGlobal.shared.layoutList {
             
             let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as! NCListCell
             cell.delegate = self
@@ -1352,6 +1192,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
             cell.imageLocal.image = nil
             cell.imageFavorite.image = nil
             cell.imageShared.image = nil
+            cell.imageShared.clearLayerMask()
             cell.imageMore.image = nil
             
             cell.imageItem.image = nil
@@ -1431,17 +1272,15 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
                 cell.imageShared.image = NCCollectionCommon.images.cellCanShareImage
             }
             if metadata.ownerId.count > 0 && metadata.ownerId != appDelegate.userID {
-                // Load avatar
-                let fileNameSource = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.user, urlBase: appDelegate.urlBase) + "-" + metadata.ownerId + ".png"
-                let fileNameSourceAvatar = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.user, urlBase: appDelegate.urlBase) + "-avatar-" + metadata.ownerId + ".png"
-                if FileManager.default.fileExists(atPath: fileNameSourceAvatar) {
-                    cell.imageShared.image = UIImage(contentsOfFile: fileNameSourceAvatar)
-                } else if FileManager.default.fileExists(atPath: fileNameSource) {
-                    cell.imageShared.image = NCUtility.shared.createAvatar(fileNameSource: fileNameSource, fileNameSourceAvatar: fileNameSourceAvatar)
+                let fileNameUser = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(appDelegate.user, urlBase: appDelegate.urlBase) + "-" + metadata.ownerId + ".png"
+                if FileManager.default.fileExists(atPath: fileNameUser) {
+                    cell.imageShared.avatar()
+                    cell.imageShared.image = UIImage(contentsOfFile: fileNameUser)
                 } else {
-                    NCCommunication.shared.downloadAvatar(userID: metadata.ownerId, fileNameLocalPath: fileNameSource, size: Int(k_avatar_size)) { (account, data, errorCode, errorMessage) in
+                    NCCommunication.shared.downloadAvatar(userID: metadata.ownerId, fileNameLocalPath: fileNameUser, size: NCBrandGlobal.shared.avatarSize) { (account, data, errorCode, errorMessage) in
                         if errorCode == 0 && account == self.appDelegate.account {
-                            cell.imageShared.image = NCUtility.shared.createAvatar(fileNameSource: fileNameSource, fileNameSourceAvatar: fileNameSourceAvatar)
+                            cell.imageShared.avatar()
+                            cell.imageShared.image = UIImage(contentsOfFile: fileNameUser)
                         }
                     }
                 }
@@ -1449,38 +1288,38 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
             
             // Transfer
             var progress: Float = 0.0
-            var totalBytes: Double = 0.0
+            var totalBytes: Int64 = 0
             let progressArray = appDelegate.listProgressMetadata.object(forKey: metadata.ocId) as? NSArray
             if progressArray != nil && progressArray?.count == 3 {
                 progress = progressArray?.object(at: 0) as? Float ?? 0
-                totalBytes = progressArray?.object(at: 1) as? Double ?? 0
+                totalBytes = progressArray?.object(at: 1) as? Int64 ?? 0
             }
-            if metadata.status == k_metadataStatusInDownload || metadata.status == k_metadataStatusDownloading ||  metadata.status >= k_metadataStatusTypeUpload {
+            if metadata.status == NCBrandGlobal.shared.metadataStatusInDownload || metadata.status == NCBrandGlobal.shared.metadataStatusDownloading ||  metadata.status >= NCBrandGlobal.shared.metadataStatusTypeUpload {
                 cell.progressView.isHidden = false
-                cell.setButtonMore(named: k_buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
+                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
             } else {
                 cell.progressView.isHidden = true
                 cell.progressView.progress = progress
-                cell.setButtonMore(named: k_buttonMoreMore, image: NCCollectionCommon.images.cellButtonMore)
+                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreMore, image: NCCollectionCommon.images.cellButtonMore)
             }
             // Write status on Label Info
             switch metadata.status {
-            case Int(k_metadataStatusWaitDownload):
+            case NCBrandGlobal.shared.metadataStatusWaitDownload:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - " + NSLocalizedString("_status_wait_download_", comment: "")
                 break
-            case Int(k_metadataStatusInDownload):
+            case NCBrandGlobal.shared.metadataStatusInDownload:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - " + NSLocalizedString("_status_in_download_", comment: "")
                 break
-            case Int(k_metadataStatusDownloading):
+            case NCBrandGlobal.shared.metadataStatusDownloading:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - ↓ " + CCUtility.transformedSize(totalBytes)
                 break
-            case Int(k_metadataStatusWaitUpload):
+            case NCBrandGlobal.shared.metadataStatusWaitUpload:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - " + NSLocalizedString("_status_wait_upload_", comment: "")
                 break
-            case Int(k_metadataStatusInUpload):
+            case NCBrandGlobal.shared.metadataStatusInUpload:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - " + NSLocalizedString("_status_in_upload_", comment: "")
                 break
-            case Int(k_metadataStatusUploading):
+            case NCBrandGlobal.shared.metadataStatusUploading:
                 cell.labelInfo.text = CCUtility.transformedSize(metadata.size) + " - ↑ " + CCUtility.transformedSize(totalBytes)
                 break
             default:
@@ -1529,7 +1368,7 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         //
         // LAYOUT GRID
         //
-        if layout == k_layout_grid {
+        if layout == NCBrandGlobal.shared.layoutGrid {
             
             let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! NCGridCell
             cell.delegate = self
@@ -1607,13 +1446,13 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
             }
             
             // Transfer
-            if metadata.status == k_metadataStatusInDownload || metadata.status == k_metadataStatusDownloading ||  metadata.status >= k_metadataStatusTypeUpload {
+            if metadata.status == NCBrandGlobal.shared.metadataStatusInDownload || metadata.status == NCBrandGlobal.shared.metadataStatusDownloading ||  metadata.status >= NCBrandGlobal.shared.metadataStatusTypeUpload {
                 cell.progressView.isHidden = false
-                cell.setButtonMore(named: k_buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
+                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreStop, image: NCCollectionCommon.images.cellButtonStop)
             } else {
                 cell.progressView.isHidden = true
                 cell.progressView.progress = 0.0
-                cell.setButtonMore(named: k_buttonMoreMore, image: NCCollectionCommon.images.cellButtonMore)
+                cell.setButtonMore(named: NCBrandGlobal.shared.buttonMoreMore, image: NCCollectionCommon.images.cellButtonMore)
             }
             
             // Live Photo

+ 8 - 1
iOSClient/Main/Colleaction Common/NCListCell.swift

@@ -132,7 +132,14 @@ class NCListCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCImageCell
     func selected(_ status: Bool) {
         if status {
             imageSelect.image = NCCollectionCommon.images.cellCheckedYes
-            backgroundView = NCUtility.shared.cellBlurEffect(with: self.bounds)
+            
+            let blurEffect = UIBlurEffect(style: .extraLight)
+            let blurEffectView = UIVisualEffectView(effect: blurEffect)
+            blurEffectView.frame = self.bounds
+            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+            blurEffectView.backgroundColor = NCBrandColor.shared.brandElement.withAlphaComponent(0.2)
+            backgroundView = blurEffectView
+            
             separator.isHidden = true
         } else {
             imageSelect.image = NCCollectionCommon.images.cellCheckedNo

+ 5 - 5
iOSClient/Main/Colleaction Common/NCListCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -76,10 +76,10 @@
                         </connections>
                     </button>
                     <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="jc6-Vg-TaS" userLabel="imageShared">
-                        <rect key="frame" x="522.5" y="17.5" width="25" height="25"/>
+                        <rect key="frame" x="520" y="15" width="30" height="30"/>
                         <constraints>
-                            <constraint firstAttribute="height" constant="25" id="Cvy-nZ-zyD"/>
-                            <constraint firstAttribute="width" constant="25" id="jfe-Fg-vA8"/>
+                            <constraint firstAttribute="height" constant="30" id="Cvy-nZ-zyD"/>
+                            <constraint firstAttribute="width" constant="30" id="jfe-Fg-vA8"/>
                         </constraints>
                     </imageView>
                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yhy-xd-w5C" userLabel="buttonMore">

+ 27 - 27
iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift

@@ -46,7 +46,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         
         self.init()
         
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             titleServerUrl = "/"
         } else {
             if let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl)) {
@@ -86,7 +86,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             })
         }
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
 
         changeTheming()
     }
@@ -125,7 +125,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         row.action.formSelector = #selector(changeDestinationFolder(_:))
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
-        row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, width: 50, height: 50, color: NCBrandColor.shared.brandElement) as UIImage
+        row.cellConfig["imageView.image"] = UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 25)
         row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
         row.cellConfig["textLabel.textColor"] = NCBrandColor.shared.textView
@@ -165,7 +165,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         // Maintain the original fileName
         
         row = XLFormRowDescriptor(tag: "maintainOriginalFileName", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_maintain_original_filename_", comment: ""))
-        row.value = CCUtility.getOriginalFileName(k_keyFileNameOriginal)
+        row.value = CCUtility.getOriginalFileName(NCBrandGlobal.shared.keyFileNameOriginal)
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
@@ -176,7 +176,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         // Add File Name Type
         
         row = XLFormRowDescriptor(tag: "addFileNameType", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_add_filenametype_", comment: ""))
-        row.value = CCUtility.getFileNameType(k_keyFileNameType)
+        row.value = CCUtility.getFileNameType(NCBrandGlobal.shared.keyFileNameType)
         row.hidden = "$\("maintainOriginalFileName") == 1"
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
@@ -191,7 +191,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         form.addFormSection(section)
         
         row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: (NSLocalizedString("_filename_", comment: "")))
-        let fileNameMask : String = CCUtility.getFileNameMask(k_keyFileNameMask)
+        let fileNameMask : String = CCUtility.getFileNameMask(NCBrandGlobal.shared.keyFileNameMask)
         if fileNameMask.count > 0 {
             row.value = fileNameMask
         }
@@ -249,11 +249,11 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             }
         }
         else if formRow.tag == "maintainOriginalFileName" {
-            CCUtility.setOriginalFileName((formRow.value! as AnyObject).boolValue, key: k_keyFileNameOriginal)
+            CCUtility.setOriginalFileName((formRow.value! as AnyObject).boolValue, key: NCBrandGlobal.shared.keyFileNameOriginal)
             self.reloadForm()
         }
         else if formRow.tag == "addFileNameType" {
-            CCUtility.setFileNameType((formRow.value! as AnyObject).boolValue, key: k_keyFileNameType)
+            CCUtility.setFileNameType((formRow.value! as AnyObject).boolValue, key: NCBrandGlobal.shared.keyFileNameType)
             self.reloadForm()
         }
         else if formRow.tag == "maskFileName" {
@@ -278,7 +278,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                     
                     self.reloadFormRow(formRow)
                     
-                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCharactersForbidden), forced: true)
+                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorCharactersForbidden, forced: true)
                 }
             }
             
@@ -309,7 +309,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             
             self.serverUrl = serverUrl!
             
-            if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+            if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
                 self.titleServerUrl = "/"
             } else {
                 if let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account
@@ -365,8 +365,8 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             
             let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: self.appDelegate.urlBase, account: self.appDelegate.account)
             if autoUploadPath == self.serverUrl {
-                if NCNetworking.shared.createFolder(assets: self.assets, selector: selectorUploadFile, useSubFolder: useSubFolder, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase) {
-                    NCContentPresenter.shared.messageNotification("_error_", description: "_error_createsubfolders_upload_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
+                if NCNetworking.shared.createFolder(assets: self.assets, selector: NCBrandGlobal.shared.selectorUploadFile, useSubFolder: useSubFolder, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase) {
+                    NCContentPresenter.shared.messageNotification("_error_", description: "_error_createsubfolders_upload_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
                     return
                 }
             }
@@ -375,7 +375,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                     
                 var serverUrl = self.serverUrl
                 var livePhoto: Bool = false
-                let fileName = CCUtility.createFileName(asset.value(forKey: "filename") as? String, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)!
+                let fileName = CCUtility.createFileName(asset.value(forKey: "filename") as? String, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: NCBrandGlobal.shared.keyFileNameMask, keyFileNameType: NCBrandGlobal.shared.keyFileNameType, keyFileNameOriginal: NCBrandGlobal.shared.keyFileNameOriginal)!
                 let assetDate = asset.creationDate ?? Date()
                 let dateFormatter = DateFormatter()
                 
@@ -406,9 +406,9 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                 
                 metadataForUpload.assetLocalIdentifier = asset.localIdentifier
                 metadataForUpload.session = self.session
-                metadataForUpload.sessionSelector = selectorUploadFile
-                metadataForUpload.size = Double(NCUtilityFileSystem.shared.getFileSize(asset: asset))
-                metadataForUpload.status = Int(k_metadataStatusWaitUpload)
+                metadataForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
+                metadataForUpload.size = NCUtilityFileSystem.shared.getFileSize(asset: asset)
+                metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
                 
                 if livePhoto {
                     
@@ -426,10 +426,10 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                             metadataMOVForUpload.livePhoto = true
                             
                             metadataMOVForUpload.session = self.session
-                            metadataMOVForUpload.sessionSelector = selectorUploadFile
+                            metadataMOVForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
                             metadataMOVForUpload.size = fileSize
-                            metadataMOVForUpload.status = Int(k_metadataStatusWaitUpload)
-                            metadataMOVForUpload.typeFile = k_metadataTypeFile_video
+                            metadataMOVForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
+                            metadataMOVForUpload.typeFile = NCBrandGlobal.shared.metadataTypeFileVideo
 
                             metadatasMOV.append(metadataMOVForUpload)
                         }
@@ -438,7 +438,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                     semaphore.wait()
                 }
                 
-                if NCUtility.shared.getMetadataConflict(account: self.appDelegate.account, serverUrl: serverUrl, fileName: fileName) != nil {
+                if NCManageDatabase.shared.getMetadataConflict(account: self.appDelegate.account, serverUrl: serverUrl, fileName: fileName) != nil {
                     metadatasUploadInConflict.append(metadataForUpload)
                 } else {
                     metadatasNOConflict.append(metadataForUpload)
@@ -484,7 +484,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
         var returnString: String = ""
         let asset = assets[0]
         
-        if (CCUtility.getOriginalFileName(k_keyFileNameOriginal)) {
+        if (CCUtility.getOriginalFileName(NCBrandGlobal.shared.keyFileNameOriginal)) {
             
             return (NSLocalizedString("_filename_", comment: "") + ": " + (asset.value(forKey: "filename") as! String))
             
@@ -495,21 +495,21 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
             if valueRenameTrimming.count > 0 {
                 
                 self.form.delegate = nil
-                CCUtility.setFileNameMask(valueRename, key: k_keyFileNameMask)
+                CCUtility.setFileNameMask(valueRename, key: NCBrandGlobal.shared.keyFileNameMask)
                 self.form.delegate = self
                 
-                returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)
+                returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: NCBrandGlobal.shared.keyFileNameMask, keyFileNameType: NCBrandGlobal.shared.keyFileNameType, keyFileNameOriginal: NCBrandGlobal.shared.keyFileNameOriginal)
                 
             } else {
                 
-                CCUtility.setFileNameMask("", key: k_keyFileNameMask)
-                returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)
+                CCUtility.setFileNameMask("", key: NCBrandGlobal.shared.keyFileNameMask)
+                returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCBrandGlobal.shared.keyFileNameType, keyFileNameOriginal: NCBrandGlobal.shared.keyFileNameOriginal)
             }
             
         } else {
             
-            CCUtility.setFileNameMask("", key: k_keyFileNameMask)
-            returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)
+            CCUtility.setFileNameMask("", key: NCBrandGlobal.shared.keyFileNameMask)
+            returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCBrandGlobal.shared.keyFileNameType, keyFileNameOriginal: NCBrandGlobal.shared.keyFileNameOriginal)
         }
         
         return String(format: NSLocalizedString("_preview_filename_", comment: ""), "MM, MMM, DD, YY, YYYY, HH, hh, mm, ss, ampm") + ":" + "\n\n" + returnString

+ 17 - 13
iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift

@@ -148,7 +148,7 @@ extension NCCreateFormUploadConflictDelegate {
             }
             
             switchAlreadyExistingFiles.isOn = true
-            NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
+            NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError, forced: true)
         }
         
         tableView.reloadData()
@@ -170,7 +170,7 @@ extension NCCreateFormUploadConflictDelegate {
             
                 let fileNameMOV = (metadata.fileNameView as NSString).deletingPathExtension + ".mov"
                 
-                let newFileName = NCUtility.shared.createFileName(metadata.fileNameView, serverUrl: metadata.serverUrl, account: metadata.account)
+                let newFileName = NCUtilityFileSystem.shared.createFileName(metadata.fileNameView, serverUrl: metadata.serverUrl, account: metadata.account)
                 metadata.ocId = UUID().uuidString
                 metadata.fileName = newFileName
                 metadata.fileNameView = newFileName
@@ -275,7 +275,7 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
 
             // -----> Already Existing File
             
-            guard let metadataAlreadyExists = NCUtility.shared.getMetadataConflict(account: metadataNewFile.account, serverUrl: metadataNewFile.serverUrl, fileName: metadataNewFile.fileNameView) else { return UITableViewCell() }
+            guard let metadataAlreadyExists = NCManageDatabase.shared.getMetadataConflict(account: metadataNewFile.account, serverUrl: metadataNewFile.serverUrl, fileName: metadataNewFile.fileNameView) else { return UITableViewCell() }
             if FileManager().fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadataAlreadyExists.ocId, etag: metadataAlreadyExists.etag)) {
                 cell.imageAlreadyExistingFile.image =  UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadataAlreadyExists.ocId, etag: metadataAlreadyExists.etag))
             } else if FileManager().fileExists(atPath: CCUtility.getDirectoryProviderStorageOcId(metadataAlreadyExists.ocId, fileNameView: metadataAlreadyExists.fileNameView)) && metadataAlreadyExists.contentType == "application/pdf" {
@@ -325,13 +325,13 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
                                 cell.imageNewFile.image = image
                             }
                         } else if mediaType == PHAssetMediaType.video {
-                            if let image = CCGraphics.thumbnailImage(forVideo: URL(fileURLWithPath: fileNamePath), atTime: 1) {
+                            if let image = NCUtility.shared.imageFromVideo(url: URL(fileURLWithPath: fileNamePath), at: 0) {
                                 cell.imageNewFile.image = image
                             }
                         }
                         
                         let fileDictionary = try FileManager.default.attributesOfItem(atPath: fileNamePath)
-                        let fileSize = fileDictionary[FileAttributeKey.size] as! Double
+                        let fileSize = fileDictionary[FileAttributeKey.size] as! Int64
                         
                         cell.labelDetailNewFile.text = CCUtility.dateDiff(date) + "\n" + CCUtility.transformedSize(fileSize)
                         
@@ -340,10 +340,15 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
                 } else {
                     
                     CCUtility.extractImageVideoFromAssetLocalIdentifier(forUpload: metadataNewFile, notification: false) { (metadataNew, fileNamePath) in
-                        DispatchQueue.main.async {
+                        DispatchQueue.global(qos: .background).async {
                             if metadataNew != nil {
                                 self.fileNamesPath[metadataNewFile.fileNameView] = fileNamePath!
+                                
                                 do {
+                                    
+                                    let fileDictionary = try FileManager.default.attributesOfItem(atPath: fileNamePath!)
+                                    let fileSize = fileDictionary[FileAttributeKey.size] as! Int64
+                                    
                                     if mediaType == PHAssetMediaType.image {
                                         let data = try Data(contentsOf: URL(fileURLWithPath: fileNamePath!))
                                         if let image = UIImage(data: data) {
@@ -352,17 +357,16 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
                                             }
                                         }
                                     } else if mediaType == PHAssetMediaType.video {
-                                        if let image = CCGraphics.thumbnailImage(forVideo: URL(fileURLWithPath: fileNamePath!), atTime: 1) {
+                                        if let image = NCUtility.shared.imageFromVideo(url: URL(fileURLWithPath: fileNamePath!), at: 0) {
                                             DispatchQueue.main.async {
                                                 cell.imageNewFile.image = image
                                             }
                                         }
                                     }
                                     
-                                    let fileDictionary = try FileManager.default.attributesOfItem(atPath: fileNamePath!)
-                                    let fileSize = fileDictionary[FileAttributeKey.size] as! Double
-                                    
-                                    cell.labelDetailNewFile.text = CCUtility.dateDiff(date) + "\n" + CCUtility.transformedSize(fileSize)
+                                    DispatchQueue.main.async {
+                                        cell.labelDetailNewFile.text = CCUtility.dateDiff(date) + "\n" + CCUtility.transformedSize(fileSize)
+                                    }
                                     
                                 } catch { print("Error: \(error)") }
                             }
@@ -373,7 +377,7 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
             } else if FileManager().fileExists(atPath: filePathNewFile) {
                 
                 do {
-                    if metadataNewFile.typeFile == k_metadataTypeFile_image {
+                    if metadataNewFile.typeFile == NCBrandGlobal.shared.metadataTypeFileImage {
                         let data = try Data(contentsOf: URL(fileURLWithPath: filePathNewFile))
                         if let image = UIImage(data: data) {
                             cell.imageNewFile.image = image
@@ -381,7 +385,7 @@ extension NCCreateFormUploadConflict: UITableViewDataSource {
                     }
                     
                     let fileDictionary = try FileManager.default.attributesOfItem(atPath: filePathNewFile)
-                    let fileSize = fileDictionary[FileAttributeKey.size] as! Double
+                    let fileSize = fileDictionary[FileAttributeKey.size] as! Int64
                     
                     cell.labelDetailNewFile.text = CCUtility.dateDiff(metadataNewFile.date as Date) + "\n" + CCUtility.transformedSize(fileSize)
                     

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

@@ -56,7 +56,7 @@ import NCCommunication
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             fileNameFolder = "/"
         } else {
             fileNameFolder = (serverUrl as NSString).lastPathComponent
@@ -74,7 +74,7 @@ import NCCommunication
         // title 
         self.title = titleForm
       
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
 
         changeTheming()
         
@@ -111,7 +111,7 @@ import NCCommunication
         row.value = fileNameFolder
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
-        row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, width: 50, height: 50, color: NCBrandColor.shared.brandElement) as UIImage
+        row.cellConfig["imageView.image"] =  UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 25)
         
         row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
@@ -222,7 +222,7 @@ import NCCommunication
         }
         
         self.serverUrl = serverUrl
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             fileNameFolder = "/"
         } else {
             fileNameFolder = (serverUrl as NSString).lastPathComponent
@@ -270,12 +270,12 @@ import NCCommunication
             return
         } else {
             
-            let result = NCCommunicationCommon.shared.getInternalContenType(fileName: fileNameForm as! String, contentType: "", directory: false)
-            if NCUtility.shared.isDirectEditing(account: appDelegate.account, contentType: result.contentType) == nil {
+            let result = NCCommunicationCommon.shared.getInternalType(fileName: fileNameForm as! String, mimeType: "", directory: false)
+            if NCUtility.shared.isDirectEditing(account: appDelegate.account, contentType: result.mimeType) == nil {
                 fileNameForm = (fileNameForm as! NSString).deletingPathExtension + "." + fileNameExtension
             }
             
-            if NCUtility.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: String(describing: fileNameForm)) != nil {
+            if NCManageDatabase.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: String(describing: fileNameForm)) != nil {
                 
                 let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: String(describing: fileNameForm), ocId: "", serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "", livePhoto: false)
                 
@@ -315,11 +315,11 @@ import NCCommunication
     
     func createDocument(fileNamePath: String, fileName: String) {
         
-        if self.editorId == k_editor_text || self.editorId == k_editor_onlyoffice {
+        if self.editorId == NCBrandGlobal.shared.editorText || self.editorId == NCBrandGlobal.shared.editorOnlyoffice {
              
             var customUserAgent: String?
             
-            if self.editorId == k_editor_onlyoffice {
+            if self.editorId == NCBrandGlobal.shared.editorOnlyoffice {
                 customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
             }
             
@@ -328,24 +328,24 @@ import NCCommunication
                 if errorCode == 0 && account == self.appDelegate.account {
                     
                     if url != nil && url!.count > 0 {
-                        let result = NCCommunicationCommon.shared.getInternalContenType(fileName: fileName, contentType: "", directory: false)
+                        let results = NCCommunicationCommon.shared.getInternalType(fileName: fileName, mimeType: "", directory: false)
                         
                         self.dismiss(animated: true, completion: {
-                            let metadata = NCManageDatabase.shared.createMetadata(account: self.appDelegate.account, fileName: fileName, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, urlBase: self.appDelegate.urlBase, url: url ?? "", contentType: result.contentType, livePhoto: false)
+                            let metadata = NCManageDatabase.shared.createMetadata(account: self.appDelegate.account, fileName: fileName, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, urlBase: self.appDelegate.urlBase, url: url ?? "", contentType: results.mimeType, livePhoto: false)
                             
                             NCViewer.shared.view(viewController: self.appDelegate.activeViewController, metadata: metadata, metadatas: [metadata])
                         })
                     }
                     
                 } else if errorCode != 0 {
-                    NCContentPresenter.shared.messageNotification("_error_", description: errorMessage, delay: TimeInterval(k_dismissAfterSecond), type:NCContentPresenter.messageType.error, errorCode: errorCode)
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorMessage, delay: NCBrandGlobal.shared.dismissAfterSecond, type:NCContentPresenter.messageType.error, errorCode: errorCode)
                 } else {
                    print("[LOG] It has been changed user during networking process, error.")
                 }
             }
         }
         
-        if self.editorId == k_editor_collabora {
+        if self.editorId == NCBrandGlobal.shared.editorCollabora {
             
             NCCommunication.shared.createRichdocuments(path: fileNamePath, templateId: templateIdentifier) { (account, url, errorCode, errorDescription) in
                 
@@ -360,7 +360,7 @@ import NCCommunication
                    
                     
                 } else if errorCode != 0 {
-                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 } else {
                     print("[LOG] It has been changed user during networking process, error.")
                 }
@@ -380,10 +380,10 @@ import NCCommunication
         indicator.color = NCBrandColor.shared.brandElement
         indicator.startAnimating()
         
-        if self.editorId == k_editor_text || self.editorId == k_editor_onlyoffice {
+        if self.editorId == NCBrandGlobal.shared.editorText || self.editorId == NCBrandGlobal.shared.editorOnlyoffice {
                         
             var customUserAgent: String?
-            if self.editorId == k_editor_onlyoffice {
+            if self.editorId == NCBrandGlobal.shared.editorOnlyoffice {
                 customUserAgent = NCUtility.shared.getCustomUserAgentOnlyOffice()
             }
             NCCommunication.shared.NCTextGetListOfTemplates(customUserAgent: customUserAgent) { (account, templates, errorCode, errorMessage) in
@@ -417,13 +417,13 @@ import NCCommunication
                     let temp = NCCommunicationEditorTemplates()
                     
                     temp.identifier = ""
-                    if self.editorId == k_editor_text {
+                    if self.editorId == NCBrandGlobal.shared.editorText {
                         temp.ext = "md"
-                    } else if self.editorId == k_editor_onlyoffice && self.typeTemplate == k_template_document {
+                    } else if self.editorId == NCBrandGlobal.shared.editorOnlyoffice && self.typeTemplate == NCBrandGlobal.shared.templateDocument {
                         temp.ext = "docx"
-                    } else if self.editorId == k_editor_onlyoffice && self.typeTemplate == k_template_spreadsheet {
+                    } else if self.editorId == NCBrandGlobal.shared.editorOnlyoffice && self.typeTemplate == NCBrandGlobal.shared.templateSpreadsheet {
                         temp.ext = "xlsx"
-                    } else if self.editorId == k_editor_onlyoffice && self.typeTemplate == k_template_presentation {
+                    } else if self.editorId == NCBrandGlobal.shared.editorOnlyoffice && self.typeTemplate == NCBrandGlobal.shared.templatePresentation {
                         temp.ext = "pptx"
                     }
                     temp.name = "Empty"
@@ -441,7 +441,7 @@ import NCCommunication
             
         }
         
-        if self.editorId == k_editor_collabora  {
+        if self.editorId == NCBrandGlobal.shared.editorCollabora  {
                         
             NCCommunication.shared.getTemplatesRichdocuments(typeTemplate: typeTemplate) { (account, templates, errorCode, errorDescription) in
                 
@@ -476,11 +476,11 @@ import NCCommunication
                     let temp = NCCommunicationEditorTemplates()
                     
                     temp.identifier = ""
-                    if self.typeTemplate == k_template_document {
+                    if self.typeTemplate == NCBrandGlobal.shared.templateDocument {
                         temp.ext = "docx"
-                    } else if self.typeTemplate == k_template_spreadsheet {
+                    } else if self.typeTemplate == NCBrandGlobal.shared.templateSpreadsheet {
                         temp.ext = "xlsx"
-                    } else if self.typeTemplate == k_template_presentation {
+                    } else if self.typeTemplate == NCBrandGlobal.shared.templatePresentation {
                         temp.ext = "pptx"
                     }
                     temp.name = "Empty"

+ 13 - 23
iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift

@@ -49,7 +49,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         
         self.init()
         
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             titleServerUrl = "/"
         } else {
             titleServerUrl = (serverUrl as NSString).lastPathComponent
@@ -81,7 +81,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         //        let rowCell = row.cell(forForm: self)
         //        rowCell.becomeFirstResponder()
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
 
         changeTheming()
         
@@ -115,7 +115,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         row.action.formSelector = #selector(changeDestinationFolder(_:))
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
-        row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, width: 50, height: 50, color: NCBrandColor.shared.brandElement) as UIImage
+        row.cellConfig["imageView.image"] =  UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 25)
         
         row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
@@ -171,7 +171,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         row.value = 0
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
-        row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "textRecognition")!, width: 50, height: 50, color: NCBrandColor.shared.brandElement) as UIImage
+        row.cellConfig["imageView.image"] = UIImage(named: "textRecognition")!.image(color: NCBrandColor.shared.brandElement, size: 25) 
         
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
         row.cellConfig["textLabel.textColor"] = NCBrandColor.shared.textView
@@ -337,16 +337,6 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         self.form.delegate = self
     }
     
-    override func textFieldDidBeginEditing(_ textField: UITextField) {
-        
-        let cell = textField.formDescriptorCell()
-        let tag = cell?.rowDescriptor.tag
-        
-        if tag == "fileName" {
-            CCUtility.selectFileName(from: textField)
-        }
-    }
-    
     func createFileName(_ fileName: String?) -> String {
         
         var name: String = ""
@@ -378,7 +368,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
             CCUtility.setDirectoryScanDocuments(serverUrl!)
             self.serverUrl = serverUrl!
             
-            if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+            if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
                 self.titleServerUrl = "/"
             } else {
                 self.titleServerUrl = (serverUrl! as NSString).lastPathComponent
@@ -414,10 +404,10 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "", livePhoto: false)
         
         metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
-        metadataForUpload.sessionSelector = selectorUploadFile
-        metadataForUpload.status = Int(k_metadataStatusWaitUpload)
+        metadataForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
+        metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
                 
-        if NCUtility.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileNameSave) != nil {
+        if NCManageDatabase.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileNameSave) != nil {
                         
             guard let conflictViewController = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict else { return }
             conflictViewController.textLabelDetailNewFile = NSLocalizedString("_now_", comment: "")
@@ -453,7 +443,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
         
         guard let fileNameGenerateExport = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else {
             NCUtility.shared.stopActivityIndicator()
-            NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorCreationFile, forced: true)
             return
         }
         
@@ -489,7 +479,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
                 try textFile.write(to: NSURL(fileURLWithPath: fileNameGenerateExport) as URL  , atomically: true, encoding: .utf8)
             } catch {
                 NCUtility.shared.stopActivityIndicator()
-                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true)
+                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorCreationFile, forced: true)
                 return
             }
         }
@@ -571,7 +561,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
             
             guard let data = image.jpegData(compressionQuality: CGFloat(0.5)) else {
                 NCUtility.shared.stopActivityIndicator()
-                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true)
+                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorCreationFile, forced: true)
                 return
             }
             
@@ -579,7 +569,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
                 try data.write(to: NSURL.fileURL(withPath: fileNameGenerateExport), options: .atomic)
             } catch {
                 NCUtility.shared.stopActivityIndicator()
-                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true)
+                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorCreationFile, forced: true)
                 return
             }
         }
@@ -761,7 +751,7 @@ class NCCreateScanDocument : NSObject, VNDocumentCameraViewControllerDelegate {
     func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
         
         for pageNumber in 0..<scan.pageCount {
-            let fileName = CCUtility.createFileName("scan.png", fileDate: Date(), fileType: PHAssetMediaType.image, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType, keyFileNameOriginal: k_keyFileNameOriginal)!
+            let fileName = CCUtility.createFileName("scan.png", fileDate: Date(), fileType: PHAssetMediaType.image, keyFileName: NCBrandGlobal.shared.keyFileNameMask, keyFileNameType: NCBrandGlobal.shared.keyFileNameType, keyFileNameOriginal: NCBrandGlobal.shared.keyFileNameOriginal)!
             let fileNamePath = CCUtility.getDirectoryScan() + "/" + fileName
             let image = scan.imageOfPage(at: pageNumber)
             do {

+ 13 - 23
iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift

@@ -45,7 +45,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
     
     public func setup(serverUrl: String, fileNamePath: String, fileName: String) {
     
-        if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+        if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
             titleServerUrl = "/"
         } else {
             titleServerUrl = (serverUrl as NSString).lastPathComponent
@@ -80,14 +80,14 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         self.title = NSLocalizedString("_voice_memo_title_", comment: "")
         
         // Button Play Stop
-        buttonPlayStop.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "audioPlay")!, width: 200, height: 200, color: NCBrandColor.shared.icon), for: .normal)
+        buttonPlayStop.setImage(UIImage(named: "audioPlay")!.image(color: NCBrandColor.shared.icon, size: 100), for: .normal)
         
         // Progress view
         progressView.progress = 0
         progressView.progressTintColor = .green
         progressView.trackTintColor = UIColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1.0)
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
 
         changeTheming()
     }
@@ -128,7 +128,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         row.action.formSelector = #selector(changeDestinationFolder(_:))
         row.cellConfig["backgroundColor"] = NCBrandColor.shared.backgroundForm
 
-        row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "folder")!, width: 50, height: 50, color: NCBrandColor.shared.brandElement) as UIImage
+        row.cellConfig["imageView.image"] =  UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 25)
         
         row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue
         row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0)
@@ -176,16 +176,6 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         }
     }
     
-    override func textFieldDidBeginEditing(_ textField: UITextField) {
-        
-        let cell = textField.formDescriptorCell()
-        let tag = cell?.rowDescriptor.tag
-        
-        if tag == "fileName" {
-            CCUtility.selectFileName(from: textField)
-        }
-    }
-    
     //MARK: TableViewDelegate
 
     override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
@@ -203,7 +193,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
             
             self.serverUrl = serverUrl!
             
-            if serverUrl == NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
+            if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) {
                 self.titleServerUrl = "/"
             } else {
                 self.titleServerUrl = (serverUrl! as NSString).lastPathComponent
@@ -234,10 +224,10 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         let metadataForUpload = NCManageDatabase.shared.createMetadata(account: self.appDelegate.account, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: self.serverUrl, urlBase: self.appDelegate.urlBase ,url: "", contentType: "", livePhoto: false)
         
         metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
-        metadataForUpload.sessionSelector = selectorUploadFile
-        metadataForUpload.status = Int(k_metadataStatusWaitUpload)
+        metadataForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
+        metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
         
-        if NCUtility.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileNameSave) != nil {
+        if NCManageDatabase.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileNameSave) != nil {
                         
             guard let conflictViewController = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict else { return }
             conflictViewController.textLabelDetailNewFile = NSLocalizedString("_now_", comment: "")
@@ -303,8 +293,8 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
     //MARK: Player - Timer
 
     func updateTimerUI() {
-        labelTimer.text = NCUtility.shared.formatSecondsToString(counterSecondPlayer)
-        labelDuration.text = NCUtility.shared.formatSecondsToString(durationPlayer)
+        labelTimer.text =  String.init().formatSecondsToString(counterSecondPlayer)
+        labelDuration.text = String.init().formatSecondsToString(durationPlayer)
         progressView.progress = Float(counterSecondPlayer / durationPlayer)
     }
     
@@ -325,7 +315,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
             progressView.progress = 0
             updateTimerUI()
             
-            buttonPlayStop.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "audioPlay")!, width: 200, height: 200, color: NCBrandColor.shared.icon), for: .normal)
+            buttonPlayStop.setImage(UIImage(named: "audioPlay")!.image(color: NCBrandColor.shared.icon, size: 100), for: .normal)
             
         } else {
             
@@ -334,7 +324,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
             
             timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
             
-            buttonPlayStop.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "stop")!, width: 200, height: 200, color: NCBrandColor.shared.icon), for: .normal)
+            buttonPlayStop.setImage(UIImage(named: "stop")!.image(color: NCBrandColor.shared.icon, size: 100), for: .normal)
         }
     }
     
@@ -345,7 +335,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud
         progressView.progress = 0
         updateTimerUI()
         
-        buttonPlayStop.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "audioPlay")!, width: 200, height: 200, color: NCBrandColor.shared.icon), for: .normal)
+        buttonPlayStop.setImage(UIImage(named: "audioPlay")!.image(color: NCBrandColor.shared.icon, size: 100), for: .normal)
     }
 }
 

+ 39 - 64
iOSClient/Main/Menu/AppDelegate+Menu.swift

@@ -53,9 +53,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
         
         actions.append(
             NCMenuAction(
-                title: NSLocalizedString("_upload_photos_videos_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "file_photo"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                action: { menuAction in
+                title: NSLocalizedString("_upload_photos_videos_", comment: ""), icon: UIImage(named: "file_photo")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                     NCPhotosPickerViewController.init(viewController: appDelegate.window.rootViewController!, maxSelectedAssets: 0, singleSelectedMode: false)
                 }
             )
@@ -63,9 +61,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
 
         actions.append(
             NCMenuAction(
-                title: NSLocalizedString("_upload_file_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "file"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                action: { menuAction in
+                title: NSLocalizedString("_upload_file_", comment: ""), icon: UIImage(named: "file")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                     if let tabBarController = self.window.rootViewController as? UITabBarController {
                         self.documentPickerViewController = NCDocumentPickerViewController.init(tabBarController: tabBarController)
                     }
@@ -76,28 +72,26 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
         #if HC
         actions.append(
             NCMenuAction(
-                title: NSLocalizedString("_im_create_new_file", tableName: "IMLocalizable", bundle: Bundle.main, value: "", comment: ""),
-                icon: CCGraphics.scale(UIImage(named: "imagemeter"), to: CGSize(width: 25, height: 25), isAspectRation: true),
-                action: { menuAction in
+                title: NSLocalizedString("_im_create_new_file", tableName: "IMLocalizable", bundle: Bundle.main, value: "", comment: ""), icon: UIImage(named: "imagemeter")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                     _ = IMCreate.init(serverUrl: appDelegate.activeServerUrl, imagemeterViewerDelegate: NCNetworkingMain.shared)
                 }
             )
         )
         #endif
       
-        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == k_editor_text}) && !isEncrypted {
-            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == k_editor_text})!
+        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == NCBrandGlobal.shared.editorText}) && !isEncrypted {
+            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == NCBrandGlobal.shared.editorText})!
             actions.append(
-                NCMenuAction(title: NSLocalizedString("_create_nextcloudtext_document_", comment: ""), icon: CCGraphics.changeThemingColorImage(UIImage(named: "file_txt"), width: 50, height: 50, color: NCBrandColor.shared.icon), action: { menuAction in
+                NCMenuAction(title: NSLocalizedString("_create_nextcloudtext_document_", comment: ""), icon: UIImage(named: "file_txt")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                     guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                         return
                     }
                     navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
                     
                     let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                    viewController.editorId = k_editor_text
+                    viewController.editorId = NCBrandGlobal.shared.editorText
                     viewController.creatorId = directEditingCreator.identifier
-                    viewController.typeTemplate = k_template_document
+                    viewController.typeTemplate = NCBrandGlobal.shared.templateDocument
                     viewController.serverUrl = appDelegate.activeServerUrl
                     viewController.titleForm = NSLocalizedString("_create_nextcloudtext_document_", comment: "")
 
@@ -109,9 +103,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
         if #available(iOS 13.0, *) {
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_scans_document_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "scan"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                    action: { menuAction in
+                    title: NSLocalizedString("_scans_document_", comment: ""), icon: UIImage(named: "scan")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                         NCCreateScanDocument.shared.openScannerDocument(viewController: appDelegate.window.rootViewController!)
                     }
                 )
@@ -120,9 +112,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
         
         actions.append(
             NCMenuAction(
-                title: NSLocalizedString("_create_voice_memo_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "microphone"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                action: { menuAction in
+                title: NSLocalizedString("_create_voice_memo_", comment: ""), icon: UIImage(named: "microphone")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                     
                     let fileName = CCUtility.createFileNameDate(NSLocalizedString("_voice_memo_filename_", comment: ""), extension: "m4a")!
                     let viewController = UIStoryboard(name: "NCAudioRecorderViewController", bundle: nil).instantiateInitialViewController() as! NCAudioRecorderViewController
@@ -139,8 +129,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
 
         actions.append(
             NCMenuAction(title: NSLocalizedString("_create_folder_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "folder"), width: 50, height: 50, color: NCBrandColor.shared.brandElement),
-                action: { menuAction in
+                icon: UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 50), action: { menuAction in
                     
                      guard let serverUrl = appDelegate.activeServerUrl else { return }
                     
@@ -155,7 +144,7 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
                          if let fileNameFolder = alertController.textFields?.first?.text {
                              NCNetworking.shared.createFolder(fileName: fileNameFolder, serverUrl: serverUrl, account: appDelegate.account, urlBase: appDelegate.urlBase, overwrite: false) { (errorCode, errorDescription) in
                                  if errorCode != 0 {
-                                     NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                                  }
                              }
                          }
@@ -169,15 +158,13 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
             )
         )
 
-        if serverVersionMajor >= k_nextcloud_version_18_0 && directory?.richWorkspace == nil && !isEncrypted && NCCommunication.shared.isNetworkReachable() {
+        if serverVersionMajor >= NCBrandGlobal.shared.nextcloudVersion18 && directory?.richWorkspace == nil && !isEncrypted && NCCommunication.shared.isNetworkReachable() {
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_add_folder_info_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "addFolderInfo"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                    action: { menuAction in
+                    title: NSLocalizedString("_add_folder_info_", comment: ""), icon: UIImage(named: "addFolderInfo")!.image(color: NCBrandColor.shared.icon, size: 50), action: { menuAction in
                         let richWorkspaceCommon = NCRichWorkspaceCommon()
                         if let viewController = self.activeViewController {
-                            if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView LIKE[c] %@", appDelegate.account, appDelegate.activeServerUrl, k_fileNameRichWorkspace.lowercased())) == nil {
+                            if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView LIKE[c] %@", appDelegate.account, appDelegate.activeServerUrl, NCBrandGlobal.shared.fileNameRichWorkspace.lowercased())) == nil {
                                 richWorkspaceCommon.createViewerNextcloudText(serverUrl: appDelegate.activeServerUrl, viewController: viewController)
                             } else {
                                 richWorkspaceCommon.openViewerNextcloudText(serverUrl: appDelegate.activeServerUrl, viewController: viewController)
@@ -188,22 +175,20 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
             )
         }
                
-        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_docx}) && !isEncrypted {
-            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_docx})!
+        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficeDocx}) && !isEncrypted {
+            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficeDocx})!
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_create_new_document_", comment: ""),
-                    icon: UIImage(named: "create_file_document")!,
-                    action: { menuAction in
+                    title: NSLocalizedString("_create_new_document_", comment: ""), icon: UIImage(named: "create_file_document")!, action: { menuAction in
                         guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                             return
                         }
                         navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                         let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                        viewController.editorId = k_editor_onlyoffice
+                        viewController.editorId = NCBrandGlobal.shared.editorOnlyoffice
                         viewController.creatorId = directEditingCreator.identifier
-                        viewController.typeTemplate = k_template_document
+                        viewController.typeTemplate = NCBrandGlobal.shared.templateDocument
                         viewController.serverUrl = appDelegate.activeServerUrl
                         viewController.titleForm = NSLocalizedString("_create_new_document_", comment: "")
 
@@ -213,22 +198,20 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
             )
         }
         
-        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_xlsx}) && !isEncrypted {
-            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_xlsx})!
+        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficeXlsx}) && !isEncrypted {
+            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficeXlsx})!
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_create_new_spreadsheet_", comment: ""),
-                    icon: UIImage(named: "create_file_xls")!,
-                    action: { menuAction in
+                    title: NSLocalizedString("_create_new_spreadsheet_", comment: ""), icon: UIImage(named: "create_file_xls")!, action: { menuAction in
                         guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                             return
                         }
                         navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                         let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                        viewController.editorId = k_editor_onlyoffice
+                        viewController.editorId = NCBrandGlobal.shared.editorOnlyoffice
                         viewController.creatorId = directEditingCreator.identifier
-                        viewController.typeTemplate = k_template_spreadsheet
+                        viewController.typeTemplate = NCBrandGlobal.shared.templateSpreadsheet
                         viewController.serverUrl = appDelegate.activeServerUrl
                         viewController.titleForm = NSLocalizedString("_create_new_spreadsheet_", comment: "")
 
@@ -238,22 +221,20 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
             )
         }
         
-        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_pptx}) && !isEncrypted {
-            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == k_editor_onlyoffice && $0.identifier == k_onlyoffice_pptx})!
+        if NCCommunication.shared.isNetworkReachable() && directEditingCreators != nil && directEditingCreators!.contains(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficePptx}) && !isEncrypted {
+            let directEditingCreator = directEditingCreators!.first(where: { $0.editor == NCBrandGlobal.shared.editorOnlyoffice && $0.identifier == NCBrandGlobal.shared.onlyofficePptx})!
             actions.append(
                 NCMenuAction(
-                    title: NSLocalizedString("_create_new_presentation_", comment: ""),
-                    icon: UIImage(named: "create_file_ppt")!,
-                    action: { menuAction in
+                    title: NSLocalizedString("_create_new_presentation_", comment: ""), icon: UIImage(named: "create_file_ppt")!, action: { menuAction in
                         guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                             return
                         }
                         navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                         let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                        viewController.editorId = k_editor_onlyoffice
+                        viewController.editorId = NCBrandGlobal.shared.editorOnlyoffice
                         viewController.creatorId = directEditingCreator.identifier
-                        viewController.typeTemplate = k_template_presentation
+                        viewController.typeTemplate = NCBrandGlobal.shared.templatePresentation
                         viewController.serverUrl = appDelegate.activeServerUrl
                         viewController.titleForm = NSLocalizedString("_create_new_presentation_", comment: "")
 
@@ -267,17 +248,15 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
             if richdocumentsMimetypes.count > 0 &&  NCCommunication.shared.isNetworkReachable() && !isEncrypted {
                 actions.append(
                     NCMenuAction(
-                        title: NSLocalizedString("_create_new_document_", comment: ""),
-                        icon: UIImage(named: "create_file_document")!,
-                        action: { menuAction in
+                        title: NSLocalizedString("_create_new_document_", comment: ""), icon: UIImage(named: "create_file_document")!, action: { menuAction in
                             guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                                 return
                             }
                             navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                             let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                            viewController.editorId = k_editor_collabora
-                            viewController.typeTemplate = k_template_document
+                            viewController.editorId = NCBrandGlobal.shared.editorCollabora
+                            viewController.typeTemplate = NCBrandGlobal.shared.templateDocument
                             viewController.serverUrl = appDelegate.activeServerUrl
                             viewController.titleForm = NSLocalizedString("_create_nextcloudtext_document_", comment: "")
 
@@ -288,17 +267,15 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
 
                 actions.append(
                     NCMenuAction(
-                        title: NSLocalizedString("_create_new_spreadsheet_", comment: ""),
-                        icon: UIImage(named: "create_file_xls")!,
-                        action: { menuAction in
+                        title: NSLocalizedString("_create_new_spreadsheet_", comment: ""), icon: UIImage(named: "create_file_xls")!, action: { menuAction in
                             guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                                 return
                             }
                             navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                             let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                            viewController.editorId = k_editor_collabora
-                            viewController.typeTemplate = k_template_spreadsheet
+                            viewController.editorId = NCBrandGlobal.shared.editorCollabora
+                            viewController.typeTemplate = NCBrandGlobal.shared.templateSpreadsheet
                             viewController.serverUrl = appDelegate.activeServerUrl
                             viewController.titleForm = NSLocalizedString("_create_new_spreadsheet_", comment: "")
 
@@ -309,17 +286,15 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
                 
                 actions.append(
                     NCMenuAction(
-                        title: NSLocalizedString("_create_new_presentation_", comment: ""),
-                        icon: UIImage(named: "create_file_ppt")!,
-                        action: { menuAction in
+                        title: NSLocalizedString("_create_new_presentation_", comment: ""), icon: UIImage(named: "create_file_ppt")!, action: { menuAction in
                             guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController() else {
                                 return
                             }
                             navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
 
                             let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
-                            viewController.editorId = k_editor_collabora
-                            viewController.typeTemplate = k_template_presentation
+                            viewController.editorId = NCBrandGlobal.shared.editorCollabora
+                            viewController.typeTemplate = NCBrandGlobal.shared.templatePresentation
                             viewController.serverUrl = appDelegate.activeServerUrl
                             viewController.titleForm = NSLocalizedString("_create_new_presentation_", comment: "")
 

+ 132 - 56
iOSClient/Main/Menu/NCCollectionViewCommon+Menu.swift

@@ -51,7 +51,7 @@ extension NCCollectionViewCommon {
         let appDelegate = UIApplication.shared.delegate as! AppDelegate
         let serverUrl = metadata.serverUrl+"/"+metadata.fileName
         let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase)
-        let serverUrlHome = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
+        let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account)
         var isOffline = false
         
         var titleDelete = NSLocalizedString("_delete_", comment: "")
@@ -64,8 +64,8 @@ extension NCCollectionViewCommon {
         }
         
         if let metadataFolder = metadataFolder {
-            let isShare = metadata.permissions.contains(k_permission_shared) && !metadataFolder.permissions.contains(k_permission_shared)
-            let isMounted = metadata.permissions.contains(k_permission_mounted) && !metadataFolder.permissions.contains(k_permission_mounted)
+            let isShare = metadata.permissions.contains(NCBrandGlobal.shared.permissionShared) && !metadataFolder.permissions.contains(NCBrandGlobal.shared.permissionShared)
+            let isMounted = metadata.permissions.contains(NCBrandGlobal.shared.permissionMounted) && !metadataFolder.permissions.contains(NCBrandGlobal.shared.permissionMounted)
             if isShare || isMounted {
                 titleDelete = NSLocalizedString("_leave_share_", comment: "")
             }
@@ -110,11 +110,11 @@ extension NCCollectionViewCommon {
         actions.append(
             NCMenuAction(
                 title: metadata.favorite ? NSLocalizedString("_remove_favorites_", comment: "") : NSLocalizedString("_add_favorites_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "favorite"), width: 50, height: 50, color: NCBrandColor.shared.yellowFavorite),
+                icon: UIImage(named: "favorite")!.image(color: NCBrandColor.shared.yellowFavorite, size: 50),
                 action: { menuAction in
                     NCNetworking.shared.favoriteMetadata(metadata, urlBase: appDelegate.urlBase) { (errorCode, errorDescription) in
                         if errorCode != 0 {
-                            NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                            NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                         }
                     }
                 }
@@ -128,7 +128,7 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_details_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "details"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "details")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         NCNetworkingNotificationCenter.shared.openShare(ViewController: self, metadata: metadata, indexPage: 0)
                     }
@@ -136,6 +136,38 @@ extension NCCollectionViewCommon {
             )
         }
         
+        //
+        // OFFLINE
+        //
+        if !isFolderEncrypted {
+            actions.append(
+                NCMenuAction(
+                    title: isOffline ? NSLocalizedString("_remove_available_offline_", comment: "") :  NSLocalizedString("_set_available_offline_", comment: ""),
+                    icon: UIImage(named: "offline")!.image(color: NCBrandColor.shared.icon, size: 50),
+                    action: { menuAction in
+                        if isOffline {
+                            if metadata.directory {
+                                NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, offline: false, account: self.appDelegate.account)
+                            } else {
+                                NCManageDatabase.shared.setLocalFile(ocId: metadata.ocId, offline: false)
+                            }
+                        } else {
+                            if metadata.directory {
+                                NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, offline: true, account: self.appDelegate.account)
+                                NCOperationQueue.shared.synchronizationMetadata(metadata, selector: NCBrandGlobal.shared.selectorDownloadAllFile)
+                            } else {
+                                NCNetworking.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorLoadOffline) { (_) in }
+                                if let metadataLivePhoto = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+                                    NCNetworking.shared.download(metadata: metadataLivePhoto, selector: NCBrandGlobal.shared.selectorLoadOffline) { (_) in }
+                                }
+                            }
+                        }
+                        self.reloadDataSource()
+                    }
+                )
+            )
+        }
+        
         //
         // OPEN IN
         //
@@ -143,9 +175,40 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_open_in_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "openFile"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "openFile")!.image(color: NCBrandColor.shared.icon, size: 50),
+                    action: { menuAction in
+                        NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: NCBrandGlobal.shared.selectorOpenIn)
+                    }
+                )
+            )
+        }
+        
+        //
+        // SAVE
+        //
+        if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo {
+            var title: String = NSLocalizedString("_save_selected_files_", comment: "")
+            var icon = UIImage(named: "saveSelectedFiles")!.image(color: NCBrandColor.shared.icon, size: 50)
+            let metadataMOV = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
+            if metadataMOV != nil {
+                title = NSLocalizedString("_livephoto_save_", comment: "")
+                icon = UIImage(named: "livePhoto")!.image(color: NCBrandColor.shared.icon, size: 50)
+            }
+            
+            actions.append(
+                NCMenuAction(
+                    title: title,
+                    icon: icon,
                     action: { menuAction in
-                        NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: selectorOpenIn)
+                        if metadataMOV != nil {
+                            NCCollectionCommon.shared.saveLivePhoto(metadata: metadata, metadataMOV: metadataMOV!)
+                        } else {
+                            if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+                                NCCollectionCommon.shared.saveAlbum(metadata: metadata)
+                            } else {
+                                NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorSaveAlbum)
+                            }
+                        }
                     }
                 )
             )
@@ -158,7 +221,7 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_rename_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "rename"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "rename")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
                         
@@ -172,7 +235,7 @@ extension NCCollectionViewCommon {
                             if let fileNameNew = alertController.textFields?.first?.text {
                                 NCNetworking.shared.renameMetadata(metadata, fileNameNew: fileNameNew, urlBase: appDelegate.urlBase, viewController: self) { (errorCode, errorDescription) in
                                     if errorCode != 0 {
-                                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                                     }
                                 }
                             }
@@ -186,7 +249,7 @@ extension NCCollectionViewCommon {
                 )
             )
         }
-
+        
         //
         // COPY - MOVE
         //
@@ -194,41 +257,25 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_move_or_copy_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "move"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "move")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
-                        NCCollectionCommon.shared.openSelectView(items: [metadata])
+                        NCCollectionCommon.shared.openSelectView(items: [metadata], viewController: self)
                     }
                 )
             )
         }
         
         //
-        // OFFLINE
+        // COPY
         //
-        if !isFolderEncrypted {
+        if !metadata.directory {
             actions.append(
                 NCMenuAction(
-                    title: isOffline ? NSLocalizedString("_remove_available_offline_", comment: "") :  NSLocalizedString("_set_available_offline_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "offline"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    title: NSLocalizedString("_copy_file_", comment: ""),
+                    icon: UIImage(named: "copy")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
-                        if isOffline {
-                            if metadata.directory {
-                                NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, offline: false, account: self.appDelegate.account)
-                            } else {
-                                NCManageDatabase.shared.setLocalFile(ocId: metadata.ocId, offline: false)
-                            }
-                        } else {
-                            if metadata.directory {
-                                NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, offline: true, account: self.appDelegate.account)
-                                NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadAllFile)
-                            } else {
-                                NCNetworking.shared.download(metadata: metadata, selector: selectorLoadOffline) { (_) in }
-                                if let metadataLivePhoto = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
-                                    NCNetworking.shared.download(metadata: metadataLivePhoto, selector: selectorLoadOffline) { (_) in }
-                                }
-                            }
-                        }
-                        self.reloadDataSource()
+                        self.appDelegate.pasteboardOcIds = [metadata.ocId];
+                        NCCollectionCommon.shared.copyPasteboard()
                     }
                 )
             )
@@ -237,11 +284,11 @@ extension NCCollectionViewCommon {
         //
         // VIEW IN FOLDER
         //
-        if layoutKey == k_layout_view_recent && appDelegate.activeFileViewInFolder == nil {
+        if layoutKey == NCBrandGlobal.shared.layoutViewRecent && appDelegate.activeFileViewInFolder == nil {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_view_in_folder_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "viewInFolder"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "viewInFolder")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         NCCollectionCommon.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileName: metadata.fileName)
                     }
@@ -255,7 +302,7 @@ extension NCCollectionViewCommon {
         actions.append(
             NCMenuAction(
                 title: titleDelete,
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "trash"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "trash")!.image(color: NCBrandColor.shared.icon, size: 50),
                 action: { menuAction in
                     let alertController = UIAlertController(title: "", message: NSLocalizedString("_want_delete_", comment: ""), preferredStyle: .alert)
                     alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_delete_", comment: ""), style: .default) { (action:UIAlertAction) in
@@ -277,7 +324,7 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_e2e_set_folder_encrypted_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "lock"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "lock")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         NCCommunication.shared.markE2EEFolder(fileId: metadata.fileId, delete: false) { (account, errorCode, errorDescription) in
                             if errorCode == 0 {
@@ -285,9 +332,9 @@ extension NCCollectionViewCommon {
                                 NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: nil, ocId: nil, fileId: nil, encrypted: true, richWorkspace: nil, account: metadata.account)
                                 NCManageDatabase.shared.setMetadataEncrypted(ocId: metadata.ocId, encrypted: true)
                                 
-                                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_changeStatusFolderE2EE, userInfo: ["serverUrl":metadata.serverUrl])
+                                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl":metadata.serverUrl])
                             } else {
-                                NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_mark_folder_", comment: ""), description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: .error, errorCode: errorCode)
+                                NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_mark_folder_", comment: ""), description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: .error, errorCode: errorCode)
                             }
                         }
                     }
@@ -302,7 +349,7 @@ extension NCCollectionViewCommon {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_e2e_remove_folder_encrypted_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "lock"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "lock")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         NCCommunication.shared.markE2EEFolder(fileId: metadata.fileId, delete: true) { (account, errorCode, errorDescription) in
                             if errorCode == 0 {
@@ -310,9 +357,9 @@ extension NCCollectionViewCommon {
                                 NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: nil, ocId: nil, fileId: nil, encrypted: false, richWorkspace: nil, account: metadata.account)
                                 NCManageDatabase.shared.setMetadataEncrypted(ocId: metadata.ocId, encrypted: false)
                                 
-                                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_changeStatusFolderE2EE, userInfo: ["serverUrl":metadata.serverUrl])
+                                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl":metadata.serverUrl])
                             } else {
-                                NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_delete_mark_folder_", comment: ""), description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: .error, errorCode: errorCode)
+                                NCContentPresenter.shared.messageNotification(NSLocalizedString("_e2e_error_delete_mark_folder_", comment: ""), description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: .error, errorCode: errorCode)
                             }
                         }
                     }
@@ -340,23 +387,54 @@ extension NCCollectionViewCommon {
     private func initMenuSelect(viewController: UIViewController, selectOcId: [String]) -> [NCMenuAction] {
         var actions = [NCMenuAction]()
        
+        //
+        // SELECT ALL
+        //
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_select_all_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "selectFull"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "selectFull")!.image(color: NCBrandColor.shared.icon, size: 50),
                 action: { menuAction in
                     self.collectionViewSelectAll()
                 }
             )
         )
         
+        //
+        // SAVE TO PHOTO GALLERY
+        //
+        actions.append(
+            NCMenuAction(
+                title: NSLocalizedString("_save_selected_files_", comment: ""),
+                icon: UIImage(named: "saveSelectedFiles")!.image(color: NCBrandColor.shared.icon, size: 50),
+                action: { menuAction in
+                    for ocId in selectOcId {
+                        if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
+                            if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo {
+                                if let metadataMOV = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+                                    NCCollectionCommon.shared.saveLivePhoto(metadata: metadata, metadataMOV: metadataMOV)
+                                } else {
+                                    if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+                                        NCCollectionCommon.shared.saveAlbum(metadata: metadata)
+                                    } else {
+                                        NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorSaveAlbum)
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    self.tapSelect(sender: self)
+                }
+            )
+        )
+        
         //
         // COPY - MOVE
         //
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_move_or_copy_selected_files_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "move"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "move")!.image(color: NCBrandColor.shared.icon, size: 50),
                 action: { menuAction in
                     var meradatasSelect = [tableMetadata]()
                     for ocId in selectOcId {
@@ -365,7 +443,7 @@ extension NCCollectionViewCommon {
                         }
                     }
                     if meradatasSelect.count > 0 {
-                        NCCollectionCommon.shared.openSelectView(items: meradatasSelect)
+                        NCCollectionCommon.shared.openSelectView(items: meradatasSelect, viewController: self)
                     }
                     self.tapSelect(sender: self)
                 }
@@ -373,20 +451,18 @@ extension NCCollectionViewCommon {
         )
         
         //
-        // SAVE TO PHOTO GALLERY
+        // COPY
         //
         actions.append(
             NCMenuAction(
-                title: NSLocalizedString("_save_selected_files_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "saveSelectedFiles"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                title: NSLocalizedString("_copy_file_", comment: ""),
+                icon: UIImage(named: "copy")!.image(color: NCBrandColor.shared.icon, size: 50),
                 action: { menuAction in
+                    self.appDelegate.pasteboardOcIds.removeAllObjects()
                     for ocId in selectOcId {
-                        if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                            if metadata.typeFile == k_metadataTypeFile_image || metadata.typeFile == k_metadataTypeFile_video && !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
-                                NCOperationQueue.shared.download(metadata: metadata, selector: selectorSaveAlbum, setFavorite: false)
-                            }
-                        }
+                        self.appDelegate.pasteboardOcIds.add(ocId)
                     }
+                    NCCollectionCommon.shared.copyPasteboard()
                     self.tapSelect(sender: self)
                 }
             )
@@ -398,7 +474,7 @@ extension NCCollectionViewCommon {
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_delete_selected_files_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "trash"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "trash")!.image(color: NCBrandColor.shared.icon, size: 50),
                 action: { menuAction in
                     let alertController = UIAlertController(title: "", message: NSLocalizedString("_want_delete_", comment: ""), preferredStyle: .alert)
                     alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_delete_", comment: ""), style: .default) { (action:UIAlertAction) in

+ 8 - 8
iOSClient/Main/Menu/NCSortMenu.swift

@@ -77,7 +77,7 @@ class NCSortMenu: NSObject {
         
         NCUtility.shared.setLayoutForView(key: key, serverUrl: serverUrl, layout: layout, sort: sort, ascending: ascending, groupBy: groupBy, directoryOnTop: directoryOnTop, titleButton: titleButton, itemForLine: itemForLine)
         
-        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":self.serverUrl])
+        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterReloadDataSource, userInfo: ["serverUrl":self.serverUrl])
     }
 
     private func initSortMenu() -> [NCMenuAction] {
@@ -86,9 +86,9 @@ class NCSortMenu: NSObject {
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_order_by_name_a_z_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameAZ"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "sortFileNameAZ")!.image(color: NCBrandColor.shared.icon, size: 50),
                 onTitle: NSLocalizedString("_order_by_name_z_a_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortFileNameZA"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                onIcon: UIImage(named: "sortFileNameZA")!.image(color: NCBrandColor.shared.icon, size: 50),
                 selected: self.sort == "fileName",
                 on: self.sort == "fileName",
                 action: { menuAction in
@@ -105,9 +105,9 @@ class NCSortMenu: NSObject {
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_order_by_date_more_recent_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateMoreRecent"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "sortDateMoreRecent")!.image(color: NCBrandColor.shared.icon, size: 50),
                 onTitle: NSLocalizedString("_order_by_date_less_recent_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortDateLessRecent"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                onIcon: UIImage(named: "sortDateLessRecent")!.image(color: NCBrandColor.shared.icon, size: 50),
                 selected: self.sort == "date",
                 on: self.sort == "date",
                 action: { menuAction in
@@ -124,9 +124,9 @@ class NCSortMenu: NSObject {
         actions.append(
             NCMenuAction(
                 title: NSLocalizedString("_order_by_size_smallest_", comment: ""),
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortSmallest"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                icon: UIImage(named: "sortSmallest")!.image(color: NCBrandColor.shared.icon, size: 50),
                 onTitle: NSLocalizedString("_order_by_size_largest_", comment: ""),
-                onIcon: CCGraphics.changeThemingColorImage(UIImage(named: "sortLargest"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                onIcon: UIImage(named: "sortLargest")!.image(color: NCBrandColor.shared.icon, size: 50),
                 selected: self.sort == "size",
                 on: self.sort == "size",
                 action: { menuAction in
@@ -144,7 +144,7 @@ class NCSortMenu: NSObject {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_directory_on_top_no_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "foldersOnTop"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "foldersOnTop")!.image(color: NCBrandColor.shared.icon, size: 50),
                     selected: self.directoryOnTop,
                     on: self.directoryOnTop,
                     action: { menuAction in

+ 105 - 74
iOSClient/Main/Menu/NCViewer+Menu.swift

@@ -70,11 +70,11 @@ extension NCViewer {
         actions.append(
             NCMenuAction(
                 title: titleFavorite,
-                icon: CCGraphics.changeThemingColorImage(UIImage(named: "favorite"), width: 50, height: 50, color: NCBrandColor.shared.yellowFavorite),
+                icon: UIImage(named: "favorite")!.image(color: NCBrandColor.shared.yellowFavorite, size: 50),
                 action: { menuAction in
                     NCNetworking.shared.favoriteMetadata(metadata, urlBase: self.appDelegate.urlBase) { (errorCode, errorDescription) in
                         if errorCode != 0 {
-                            NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                            NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                         }
                     }
                 }
@@ -88,7 +88,7 @@ extension NCViewer {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_details_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "details"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "details")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         NCNetworkingNotificationCenter.shared.openShare(ViewController: viewController, metadata: metadata, indexPage: 0)
                     }
@@ -96,15 +96,64 @@ extension NCViewer {
             )
         }
         
+        //
+        // OFFLINE
+        //
+        if metadata.session == "" && !webView {
+            actions.append(
+                NCMenuAction(
+                    title: titleOffline,
+                    icon: UIImage(named: "offline")!.image(color: NCBrandColor.shared.icon, size: 50),
+                    action: { menuAction in
+                        if ((localFile == nil || !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView)) && metadata.session == "") {
+                            
+                            NCNetworking.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorLoadOffline) { (_) in }
+                        } else {
+                            NCManageDatabase.shared.setLocalFile(ocId: metadata.ocId, offline: !localFile!.offline)
+                        }
+                    }
+                )
+            )
+        }
+        
         //
         // OPEN IN
         //
         if metadata.session == "" && !webView {
             actions.append(
-                NCMenuAction(title: NSLocalizedString("_open_in_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "openFile"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                NCMenuAction(
+                    title: NSLocalizedString("_open_in_", comment: ""),
+                    icon: UIImage(named: "openFile")!.image(color: NCBrandColor.shared.icon, size: 50),
+                    action: { menuAction in
+                        NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: NCBrandGlobal.shared.selectorOpenIn)
+                    }
+                )
+            )
+        }
+        
+        //
+        // SAVE IMAGE / VIDEO
+        //
+        if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo {
+            
+            var title: String = NSLocalizedString("_save_selected_files_", comment: "")
+            var icon = UIImage(named: "saveSelectedFiles")!.image(color: NCBrandColor.shared.icon, size: 50)
+            let metadataMOV = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
+            if metadataMOV != nil {
+                title = NSLocalizedString("_livephoto_save_", comment: "")
+                icon = UIImage(named: "livePhoto")!.image(color: NCBrandColor.shared.icon, size: 50)
+            }
+            
+            actions.append(
+                NCMenuAction(
+                    title: title,
+                    icon: icon,
                     action: { menuAction in
-                        NCNetworkingNotificationCenter.shared.downloadOpen(metadata: metadata, selector: selectorOpenIn)
+                        if metadataMOV != nil {
+                            NCCollectionCommon.shared.saveLivePhoto(metadata: metadata, metadataMOV: metadataMOV!)
+                        } else {
+                            NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorSaveAlbum)
+                        }
                     }
                 )
             )
@@ -117,7 +166,7 @@ extension NCViewer {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_rename_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "rename"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "rename")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
 
@@ -127,7 +176,7 @@ extension NCViewer {
                             let fileNameNew = alertController.textFields![0].text
                             NCNetworking.shared.renameMetadata(metadata, fileNameNew: fileNameNew!, urlBase: self.appDelegate.urlBase, viewController: viewController) { (errorCode, errorDescription) in
                                 if errorCode != 0 {
-                                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                                 }
                             }
                         })
@@ -147,7 +196,7 @@ extension NCViewer {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_move_or_copy_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "move"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "move")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         
                         let storyboard = UIStoryboard(name: "NCSelect", bundle: nil)
@@ -174,24 +223,18 @@ extension NCViewer {
         }
         
         //
-        // OFFLINE
+        // COPY
         //
-        if metadata.session == "" && !webView {
-            actions.append(
-                NCMenuAction(
-                    title: titleOffline,
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "offline"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                    action: { menuAction in
-                        if ((localFile == nil || !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView)) && metadata.session == "") {
-                            
-                            NCNetworking.shared.download(metadata: metadata, selector: selectorLoadOffline) { (_) in }
-                        } else {
-                            NCManageDatabase.shared.setLocalFile(ocId: metadata.ocId, offline: !localFile!.offline)
-                        }
-                    }
-                )
+        actions.append(
+            NCMenuAction(
+                title: NSLocalizedString("_copy_file_", comment: ""),
+                icon: UIImage(named: "copy")!.image(color: NCBrandColor.shared.icon, size: 50),
+                action: { menuAction in
+                    self.appDelegate.pasteboardOcIds = [metadata.ocId];
+                    NCCollectionCommon.shared.copyPasteboard()
+                }
             )
-        }
+        )
         
         //
         // VIEW IN FOLDER
@@ -201,7 +244,7 @@ extension NCViewer {
                 actions.append(
                     NCMenuAction(
                         title: NSLocalizedString("_view_in_folder_", comment: ""),
-                        icon: CCGraphics.changeThemingColorImage(UIImage(named: "viewInFolder"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                        icon: UIImage(named: "viewInFolder")!.image(color: NCBrandColor.shared.icon, size: 50),
                         action: { menuAction in
                             NCCollectionCommon.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileName: metadata.fileName)
                         }
@@ -210,13 +253,46 @@ extension NCViewer {
             }
         }
         
+        //
+        // DOWNLOAD IMAGE MAX RESOLUTION
+        //
+        if metadata.session == "" {
+            if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImage && !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && metadata.session == "" {
+                actions.append(
+                    NCMenuAction(
+                        title: NSLocalizedString("_download_image_max_", comment: ""),
+                        icon: UIImage(named: "downloadImageFullRes")!.image(color: NCBrandColor.shared.icon, size: 50),
+                        action: { menuAction in
+                            NCNetworking.shared.download(metadata: metadata, selector: "") { (_) in }
+                        }
+                    )
+                )
+            }
+        }
+        
+        //
+        // PDF
+        //
+        if (metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileDocument && metadata.contentType == "application/pdf" ) {
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_search_", comment: ""),
+                    icon: UIImage(named: "search")!.image(color: NCBrandColor.shared.icon, size: 50),
+                    action: { menuAction in
+                        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterMenuSearchTextPDF)
+                    }
+                )
+            )
+        }
+        
         //
         // DELETE
         //
         if !webView {
             actions.append(
-                NCMenuAction(title: titleDelete,
-                             icon: CCGraphics.changeThemingColorImage(UIImage(named: "trash"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                NCMenuAction(
+                    title: titleDelete,
+                    icon: UIImage(named: "trash")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         
                         let alertController = UIAlertController(title: "", message: NSLocalizedString("_want_delete_", comment: ""), preferredStyle: .alert)
@@ -225,7 +301,7 @@ extension NCViewer {
                             
                             NCNetworking.shared.deleteMetadata(metadata, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, onlyLocal: false) { (errorCode, errorDescription) in
                                 if errorCode != 0 {
-                                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                                 }
                             }
                         })
@@ -238,51 +314,6 @@ extension NCViewer {
             )
         }
         
-        //
-        // PDF
-        //
-        if (metadata.typeFile == k_metadataTypeFile_document && metadata.contentType == "application/pdf" ) {
-            actions.append(
-                NCMenuAction(title: NSLocalizedString("_search_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "search"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                    action: { menuAction in
-                        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_menuSearchTextPDF)
-                    }
-                )
-            )
-        }
-        
-        //
-        // IMAGE - VIDEO - AUDIO
-        //
-        if metadata.session == "" {
-            if metadata.typeFile == k_metadataTypeFile_image && !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && metadata.session == "" {
-                actions.append(
-                    NCMenuAction(title: NSLocalizedString("_download_image_max_", comment: ""),
-                        icon: CCGraphics.changeThemingColorImage(UIImage(named: "downloadImageFullRes"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                        action: { menuAction in
-                            NCNetworking.shared.download(metadata: metadata, selector: "") { (_) in }
-                        }
-                    )
-                )
-            }
-        }
-        
-        if metadata.typeFile == k_metadataTypeFile_image || metadata.typeFile == k_metadataTypeFile_video || metadata.typeFile == k_metadataTypeFile_audio {
-            if let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
-                if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && CCUtility.fileProviderStorageExists(metadataLive.ocId, fileNameView: metadataLive.fileNameView) {
-                    actions.append(
-                        NCMenuAction(title: NSLocalizedString("_livephoto_save_", comment: ""),
-                            icon: CCGraphics.changeThemingColorImage(UIImage(named: "livePhoto"), width: 50, height: 50, color: NCBrandColor.shared.icon),
-                            action: { menuAction in
-                                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_menuSaveLivePhoto, userInfo: ["ocId": metadata.ocId, "ocIdMov": metadataLive.ocId])
-                            }
-                        )
-                    )
-                }
-            }
-        }
-         
         return actions
     }
 }

+ 17 - 1
iOSClient/Main/NCMainNavigationController.swift

@@ -25,14 +25,30 @@ import Foundation
 
 class NCMainNavigationController: UINavigationController {
     
+    var isPushing = false
+
     required init?(coder: NSCoder) {
         super.init(coder: coder)
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
     
+    // https://stackoverflow.com/questions/37829721/pushing-view-controller-twice
+    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
+        
+        if !isPushing {
+            isPushing = true
+            CATransaction.begin()
+            CATransaction.setCompletionBlock {
+                self.isPushing = false
+            }
+            super.pushViewController(viewController, animated: animated)
+            CATransaction.commit()
+        }
+    }
+    
     @objc func changeTheming() {
                   
         if #available(iOS 13.0, *) {

+ 42 - 12
iOSClient/Main/NCMainTabBar.swift

@@ -28,6 +28,7 @@ class NCMainTabBar: UITabBar {
     private var fillColor: UIColor!
     private var shapeLayer: CALayer?
     private let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    private var timer: Timer?
     
 //    override var traitCollection: UITraitCollection {
 //        return UITraitCollection(horizontalSizeClass: .compact)
@@ -36,7 +37,9 @@ class NCMainTabBar: UITabBar {
     required init?(coder: NSCoder) {
         super.init(coder: coder)
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: (#selector(updateBadgeNumber)), userInfo: nil, repeats: true)
+            
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
@@ -137,37 +140,37 @@ class NCMainTabBar: UITabBar {
     private func createButtons() {
        
         // File
-        if let item = items?[Int(k_tabBarApplicationIndexFile)] {
+        if let item = items?[0] {
             item.title = NSLocalizedString("_home_", comment: "")
-            item.image = CCGraphics.changeThemingColorImage(UIImage(named: "tabBarFiles"), width: 50, height: 50, color: NCBrandColor.shared.brandElement)
+            item.image = UIImage(named: "tabBarFiles")?.image(color: NCBrandColor.shared.brandElement, size: 25)
             item.selectedImage = item.image
         }
         
         // Favorite
-        if let item = items?[Int(k_tabBarApplicationIndexFavorite)] {
+        if let item = items?[1] {
             item.title = NSLocalizedString("_favorites_", comment: "")
-            item.image = CCGraphics.changeThemingColorImage(UIImage(named: "favorite"), width: 50, height: 50, color: NCBrandColor.shared.brandElement)
+            item.image = UIImage(named: "favorite")?.image(color: NCBrandColor.shared.brandElement, size: 25)
             item.selectedImage = item.image
         }
         
         // +
-        if let item = items?[Int(k_tabBarApplicationIndexPlusHide)] {
+        if let item = items?[2] {
             item.title = ""
             item.image = nil
             item.isEnabled = false
         }
         
         // Media
-        if let item = items?[Int(k_tabBarApplicationIndexMedia)] {
+        if let item = items?[3] {
             item.title = NSLocalizedString("_media_", comment: "")
-            item.image = CCGraphics.changeThemingColorImage(UIImage(named: "media"), width: 50, height: 50, color: NCBrandColor.shared.brandElement)
+            item.image = UIImage(named: "media")?.image(color: NCBrandColor.shared.brandElement, size: 25)
             item.selectedImage = item.image
         }
         
         // More
-        if let item = items?[Int(k_tabBarApplicationIndexMore)] {
+        if let item = items?[4] {
             item.title = NSLocalizedString("_more_", comment: "")
-            item.image = CCGraphics.changeThemingColorImage(UIImage(named: "tabBarMore"), width: 50, height: 50, color: NCBrandColor.shared.brandElement)
+            item.image = UIImage(named: "tabBarMore")?.image(color: NCBrandColor.shared.brandElement, size: 25)
             item.selectedImage = item.image
         }
         
@@ -182,7 +185,7 @@ class NCMainTabBar: UITabBar {
         let centerButton = UIButton(frame: CGRect(x: (self.bounds.width / 2)-(centerButtonHeight/2), y: centerButtonY, width: centerButtonHeight, height: centerButtonHeight))
         
         centerButton.setTitle("", for: .normal)
-        centerButton.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "tabBarPlus"), width: 100, height: 100, color: .white), for: .normal)
+        centerButton.setImage(UIImage(named: "tabBarPlus")?.image(color: .white, size: 100), for: .normal)
         centerButton.backgroundColor = NCBrandColor.shared.brandElement
         centerButton.tintColor = UIColor.white
         centerButton.tag = 99
@@ -204,7 +207,7 @@ class NCMainTabBar: UITabBar {
         if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, appDelegate.activeServerUrl)) {
             
             if !directory.permissions.contains("CK") {
-                NCContentPresenter.shared.messageNotification("_warning_", description: "_no_permission_add_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
+                NCContentPresenter.shared.messageNotification("_warning_", description: "_no_permission_add_file_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                 return
             }
         }
@@ -213,5 +216,32 @@ class NCMainTabBar: UITabBar {
             appDelegate.showMenuIn(viewController: viewController)
         }
     }
+    
+    @objc func updateBadgeNumber() {
+        
+        if appDelegate.account == nil || appDelegate.account.count == 0 { return }
+        
+        let counterDownload = NCOperationQueue.shared.downloadCount()
+        let counterUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d OR status == %d", NCBrandGlobal.shared.metadataStatusWaitUpload, NCBrandGlobal.shared.metadataStatusInUpload, NCBrandGlobal.shared.metadataStatusUploading)).count
+        let total = counterDownload + counterUpload
+        
+        UIApplication.shared.applicationIconBadgeNumber = total
+        
+        if let item = items?[0] {
+            if total > 0 {
+                item.badgeValue = String(total)
+            } else {
+                item.badgeValue = nil
+            }
+        }
+    }
+    
+    func getCenterButton() -> UIView? {
+        if let centerButton = self.viewWithTag(99) {
+            return centerButton
+        } else {
+            return nil
+        }
+    }
 }
 

+ 9 - 9
iOSClient/Main/NCPickerViewController.swift

@@ -85,15 +85,15 @@ class NCPhotosPickerViewController: NSObject {
         }, didCancel: nil)
         
         viewController.didExceedMaximumNumberOfSelection = { (picker) in
-            NCContentPresenter.shared.messageNotification("_info_", description: "_limited_dimension_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+            NCContentPresenter.shared.messageNotification("_info_", description: "_limited_dimension_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
         }
         
         viewController.handleNoAlbumPermissions = { (picker) in
-            NCContentPresenter.shared.messageNotification("_info_", description: "_denied_album_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+            NCContentPresenter.shared.messageNotification("_info_", description: "_denied_album_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
         }
         
         viewController.handleNoCameraPermissions = { (picker) in
-            NCContentPresenter.shared.messageNotification("_info_", description: "_denied_camera_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+            NCContentPresenter.shared.messageNotification("_info_", description: "_denied_camera_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
         }
         
         viewController.configure = configure
@@ -157,11 +157,11 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate {
                         let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, fileName: fileName, ocId: ocId, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "", livePhoto: false)
                         
                         metadataForUpload.session = NCNetworking.shared.sessionIdentifierBackground
-                        metadataForUpload.sessionSelector = selectorUploadFile
-                        metadataForUpload.size = Double(data?.count ?? 0)
-                        metadataForUpload.status = Int(k_metadataStatusWaitUpload)
+                        metadataForUpload.sessionSelector = NCBrandGlobal.shared.selectorUploadFile
+                        metadataForUpload.size = Int64(data?.count ?? 0)
+                        metadataForUpload.status = NCBrandGlobal.shared.metadataStatusWaitUpload
                         
-                        if NCUtility.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileName) != nil {
+                        if NCManageDatabase.shared.getMetadataConflict(account: appDelegate.account, serverUrl: serverUrl, fileName: fileName) != nil {
                             
                             if let conflict = UIStoryboard.init(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict {
                                 
@@ -178,10 +178,10 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate {
                         }
                         
                     } catch {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_write_file_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_write_file_error_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                     }
                 } else {
-                    NCContentPresenter.shared.messageNotification("_error_", description: "_read_file_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+                    NCContentPresenter.shared.messageNotification("_error_", description: "_read_file_error_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                 }
             }
         }

+ 4 - 4
iOSClient/Main/Section Header Footer/NCSectionHeaderFooter.swift

@@ -45,12 +45,12 @@ class NCSectionHeaderMenu: UICollectionReusableView, UIGestureRecognizerDelegate
     override func awakeFromNib() {
         super.awakeFromNib()
         
-        buttonSwitch.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "switchList"), width: 50, height: 50, color: NCBrandColor.shared.icon), for: .normal)
+        buttonSwitch.setImage(UIImage.init(named: "switchList")!.image(color: NCBrandColor.shared.icon, size: 25), for: .normal)
         
         buttonOrder.setTitle("", for: .normal)
         buttonOrder.setTitleColor(NCBrandColor.shared.brandElement, for: .normal)
         
-        buttonMore.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), width: 50, height: 50, color: NCBrandColor.shared.icon), for: .normal)
+        buttonMore.setImage(UIImage.init(named: "more")!.image(color:  NCBrandColor.shared.icon, size: 25), for: .normal)
                 
         // Gradient
         gradient.startPoint = CGPoint(x: 0, y: 0.60)
@@ -61,7 +61,7 @@ class NCSectionHeaderMenu: UICollectionReusableView, UIGestureRecognizerDelegate
         tap.delegate = self
         viewRichWorkspace?.addGestureRecognizer(tap)
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
@@ -158,7 +158,7 @@ class NCSectionFooter: UICollectionReusableView {
         labelSection.textColor = NCBrandColor.shared.icon
     }
     
-    func setTitleLabel(directories: Int, files: Int, size: Double) {
+    func setTitleLabel(directories: Int, files: Int, size: Int64) {
         
         var foldersText = ""
         var filesText = ""

+ 58 - 68
iOSClient/Media/NCMedia.swift

@@ -47,7 +47,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     private var filterTypeFileImage = false
     private var filterTypeFileVideo = false
             
-    private let kMaxImageGrid: CGFloat = 7
+    private let maxImageGrid: CGFloat = 7
     private var cellHeigth: CGFloat = 0
 
     private var oldInProgress = false
@@ -63,7 +63,6 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     struct cacheImages {
         static var cellLivePhotoImage = UIImage()
         static var cellPlayImage = UIImage()
-        static var cellFavouriteImage = UIImage()
     }
 
     // MARK: - View Life Cycle
@@ -73,7 +72,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
 
         appDelegate.activeMedia = self
         
-        NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground), name: NSNotification.Name(rawValue: k_notificationCenter_applicationWillEnterForeground), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterApplicationWillEnterForeground), object: nil)
     }
     
     override func viewDidLoad() {
@@ -92,23 +91,18 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
         
         // Empty
         emptyDataSet = NCEmptyDataSet.init(view: collectionView, offset: 0, delegate: self)
-                
-        // 3D Touch peek and pop
-        if traitCollection.forceTouchCapability == .available {
-            registerForPreviewing(with: self, sourceView: view)
-        }
-        
+      
         // Notification
-        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_deleteFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_moveFile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_renameFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDeleteFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(moveFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterMoveFile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterRenameFile), object: nil)
             
         mediaCommandView = Bundle.main.loadNibNamed("NCMediaCommandView", owner: self, options: nil)?.first as? NCMediaCommandView
         self.view.addSubview(mediaCommandView!)
         mediaCommandView?.mediaView = self
-        mediaCommandView?.zoomInButton.isEnabled = !(self.gridLayout.itemForLine == 1)
-        mediaCommandView?.zoomOutButton.isEnabled = !(self.gridLayout.itemForLine == self.kMaxImageGrid - 1)
+        mediaCommandView?.zoomInButton.isEnabled = !(gridLayout.itemForLine == 1)
+        mediaCommandView?.zoomOutButton.isEnabled = !(gridLayout.itemForLine == maxImageGrid - 1)
         mediaCommandView?.collapseControlButtonView(true)
         mediaCommandView?.translatesAutoresizingMaskIntoConstraints = false
         mediaCommandView?.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
@@ -176,11 +170,11 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     
     @objc func zoomOutGrid() {
         UIView.animate(withDuration: 0.0, animations: {
-            if(self.gridLayout.itemForLine + 1 < self.kMaxImageGrid) {
+            if(self.gridLayout.itemForLine + 1 < self.maxImageGrid) {
                 self.gridLayout.itemForLine += 1
                 self.mediaCommandView?.zoomInButton.isEnabled = true
             }
-            if(self.gridLayout.itemForLine == self.kMaxImageGrid - 1) {
+            if(self.gridLayout.itemForLine == self.maxImageGrid - 1) {
                 self.mediaCommandView?.zoomOutButton.isEnabled = false
             }
 
@@ -213,7 +207,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
                 actions.append(
                     NCMenuAction(
                         title: NSLocalizedString("_select_", comment: ""),
-                        icon: CCGraphics.changeThemingColorImage(UIImage(named: "selectFull"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                        icon: UIImage(named: "selectFull")!.image(color: NCBrandColor.shared.icon, size: 50),
                         action: { menuAction in
                             self.isEditMode = true
                         }
@@ -224,7 +218,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString(filterTypeFileImage ? "_media_viewimage_show_" : "_media_viewimage_hide_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: filterTypeFileImage ? "imageno" : "imageyes"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: filterTypeFileImage ? "imageno" : "imageyes")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         self.filterTypeFileImage = !self.filterTypeFileImage
                         self.filterTypeFileVideo = false
@@ -236,7 +230,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString(filterTypeFileVideo ? "_media_viewvideo_show_" : "_media_viewvideo_hide_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: filterTypeFileVideo ? "videono" : "videoyes"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: filterTypeFileVideo ? "videono" : "videoyes")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         self.filterTypeFileVideo = !self.filterTypeFileVideo
                         self.filterTypeFileImage = false
@@ -248,7 +242,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_select_media_folder_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "folderAutomaticUpload"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "folderAutomaticUpload")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         let navigationController = UIStoryboard(name: "NCSelect", bundle: nil).instantiateInitialViewController() as! UINavigationController
                         let viewController = navigationController.topViewController as! NCSelect
@@ -270,7 +264,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_media_by_modified_date_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortModifiedDate"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "sortModifiedDate")!.image(color: NCBrandColor.shared.icon, size: 50),
                     selected: CCUtility.getMediaSortDate() == "date",
                     on: true,
                     action: { menuAction in
@@ -283,7 +277,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_media_by_created_date_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortCreatedDate"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "sortCreatedDate")!.image(color: NCBrandColor.shared.icon, size: 50),
                     selected: CCUtility.getMediaSortDate() == "creationDate",
                     on: true,
                     action: { menuAction in
@@ -296,7 +290,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_media_by_upload_date_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "sortUploadDate"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "sortUploadDate")!.image(color: NCBrandColor.shared.icon, size: 50),
                     selected: CCUtility.getMediaSortDate() == "uploadDate",
                     on: true,
                     action: { menuAction in
@@ -311,7 +305,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_cancel_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "cancel"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "cancel")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         self.isEditMode = false
                         self.selectOcId.removeAll()
@@ -326,7 +320,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_move_or_copy_selected_files_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "move"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "move")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         self.isEditMode = false
                         var meradatasSelect = [tableMetadata]()
@@ -336,7 +330,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
                             }
                         }
                         if meradatasSelect.count > 0 {
-                            NCCollectionCommon.shared.openSelectView(items: meradatasSelect)
+                            NCCollectionCommon.shared.openSelectView(items: meradatasSelect, viewController: self)
                         }
                         self.selectOcId.removeAll()
                     }
@@ -349,14 +343,14 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_delete_selected_files_", comment: ""),
-                    icon: CCGraphics.changeThemingColorImage(UIImage(named: "trash"), width: 50, height: 50, color: NCBrandColor.shared.icon),
+                    icon: UIImage(named: "trash")!.image(color: NCBrandColor.shared.icon, size: 50),
                     action: { menuAction in
                         self.isEditMode = false
                         for ocId in self.selectOcId {
                             if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
                                 NCNetworking.shared.deleteMetadata(metadata, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, onlyLocal: false) { (errorCode, errorDescription) in
                                     if errorCode != 0 {
-                                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                                     }
                                 }
                             }
@@ -396,9 +390,8 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
         collectionView.backgroundColor = NCBrandColor.shared.backgroundView
         collectionView.reloadData()
         
-        cacheImages.cellLivePhotoImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "livePhoto"), width: 100, height: 100, color: .white)
-        cacheImages.cellPlayImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "play"), width: 100, height: 100, color: .white)
-        cacheImages.cellFavouriteImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "favorite"), width: 100, height: 100, color: NCBrandColor.shared.yellowFavorite)
+        cacheImages.cellLivePhotoImage = UIImage.init(named: "livePhoto")!.image(color: .white, size: 50)
+        cacheImages.cellPlayImage = UIImage.init(named: "play")!.image(color: .white, size: 50)
     }
 
     @objc func deleteFile(_ notification: NSNotification) {
@@ -465,7 +458,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     
     func emptyDataSetView(_ view: NCEmptyView) {
         
-        view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "media"), width: 300, height: 300, color: .gray)
+        view.emptyImage.image = UIImage.init(named: "media")?.image(color: .gray, size: UIScreen.main.bounds.width)
         if oldInProgress || newInProgress {
             view.emptyTitle.text = NSLocalizedString("_search_in_progress_", comment: "")
         } else {
@@ -475,35 +468,6 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     }
 }
 
-// MARK: - 3D Touch peek and pop
-
-extension NCMedia: UIViewControllerPreviewingDelegate {
-    
-    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
-        
-        guard let point = collectionView?.convert(location, from: collectionView?.superview) else { return nil }
-        guard let indexPath = collectionView?.indexPathForItem(at: point) else { return nil }
-        let metadata = metadatas[indexPath.row]
-        guard let cell = collectionView?.cellForItem(at: indexPath) as? NCGridMediaCell  else { return nil }
-        guard let viewController = UIStoryboard(name: "CCPeekPop", bundle: nil).instantiateViewController(withIdentifier: "PeekPopImagePreview") as? CCPeekPop else { return nil }
-        
-        previewingContext.sourceRect = cell.frame
-        viewController.metadata = metadata
-        viewController.imageFile = cell.imageItem.image
-        viewController.showOpenIn = true
-        viewController.showShare = false
-        viewController.showOpenQuickLook = false
-
-        return viewController
-    }
-    
-    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
-        
-        guard let indexPath = collectionView?.indexPathForItem(at: previewingContext.sourceRect.origin) else { return }
-        collectionView(collectionView, didSelectItemAt: indexPath)
-    }
-}
-
 // MARK: - Collection View
 
 extension NCMedia: UICollectionViewDelegate {
@@ -529,6 +493,32 @@ extension NCMedia: UICollectionViewDelegate {
             NCViewer.shared.view(viewController: self, metadata: metadataTouch!, metadatas: metadatas)
         }
     }
+    
+    @available(iOS 13.0, *)
+    func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
+        
+        let metadata = metadatas[indexPath.row]
+        let identifier = indexPath as NSCopying
+
+        return UIContextMenuConfiguration(identifier: identifier, previewProvider: {
+            
+            return NCViewerProviderContextMenu(metadata: metadata)
+            
+        }, actionProvider: { suggestedActions in
+            
+            return NCCollectionCommon.shared.contextMenuConfiguration(metadata: metadata, viewController: self, enableDeleteLocal: false, enableViewInFolder: true)
+        })
+    }
+    
+    @available(iOS 13.0, *)
+    func collectionView(_ collectionView: UICollectionView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
+        animator.addCompletion {
+
+            if let indexPath = configuration.identifier as? IndexPath {
+                self.collectionView(collectionView, didSelectItemAt: indexPath)
+            }
+        }
+    }
 }
 
 extension NCMedia: UICollectionViewDataSourcePrefetching {
@@ -587,7 +577,7 @@ extension NCMedia: UICollectionViewDataSource {
             }
             cell.date = metadata.date as Date
 
-            if metadata.typeFile == k_metadataTypeFile_video || metadata.typeFile == k_metadataTypeFile_audio {
+            if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileVideo || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileAudio {
                 cell.imageStatus.image = cacheImages.cellPlayImage
             } else if metadata.livePhoto && livePhoto {
                 cell.imageStatus.image = cacheImages.cellLivePhotoImage
@@ -647,14 +637,14 @@ extension NCMedia {
         if let tableAccount = NCManageDatabase.shared.getAccountActive() {
             self.mediaPath = tableAccount.mediaPath
         }
-        let startServerUrl = NCUtility.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) + mediaPath
+        let startServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, account: appDelegate.account) + mediaPath
         
-        predicateDefault = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (typeFile == %@ OR typeFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, k_metadataTypeFile_image, k_metadataTypeFile_video)
+        predicateDefault = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (typeFile == %@ OR typeFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NCBrandGlobal.shared.metadataTypeFileImage, NCBrandGlobal.shared.metadataTypeFileVideo)
         
         if filterTypeFileImage {
-            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, k_metadataTypeFile_video)
+            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NCBrandGlobal.shared.metadataTypeFileVideo)
         } else if filterTypeFileVideo {
-            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, k_metadataTypeFile_image)
+            predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NCBrandGlobal.shared.metadataTypeFileImage)
         } else {
             predicate = predicateDefault
         }
@@ -892,7 +882,7 @@ class NCMediaCommandView: UIView {
         gradient.endPoint = CGPoint(x: 0, y: 0.9)
         gradient.colors = [UIColor.black.withAlphaComponent(0.4).cgColor , UIColor.clear.cgColor]
         layer.insertSublayer(gradient, at: 0)
-        moreButton.setImage(CCGraphics.changeThemingColorImage(UIImage.init(named: "more"), width: 50, height: 50, color: .white), for: .normal)
+        moreButton.setImage(UIImage.init(named: "more")!.image(color: .white, size: 25), for: .normal)
         title.text = ""
     }
     

+ 11 - 11
iOSClient/More/NCMore.swift

@@ -64,8 +64,8 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
         labelQuotaExternalSite.addGestureRecognizer(tapQuota)
 
         // Notification
-        NotificationCenter.default.addObserver(self, selector: #selector(changeUserProfile), name: NSNotification.Name(rawValue: k_notificationCenter_changeUserProfile), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeUserProfile), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeUserProfile), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
@@ -138,7 +138,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
         
         // ITEM : Trash
         let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-        if serverVersionMajor >= Int(k_trash_version_available) {
+        if serverVersionMajor >= NCBrandGlobal.shared.nextcloudVersion15 {
 
             item = NCCommunicationExternalSite()
             item.name = "_trash_view_"
@@ -214,18 +214,18 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
             progressQuota.progress = 0
         }
 
-        switch Double(tabAccount.quotaTotal) {
-        case Double(-1):
+        switch tabAccount.quotaTotal {
+        case -1:
             quota = "0"
-        case Double(-2):
+        case -2:
             quota = NSLocalizedString("_quota_space_unknown_", comment: "")
-        case Double(-3):
+        case -3:
             quota = NSLocalizedString("_quota_space_unlimited_", comment: "")
         default:
-            quota = CCUtility.transformedSize(Double(tabAccount.quotaTotal))
+            quota = CCUtility.transformedSize(tabAccount.quotaTotal)
         }
 
-        let quotaUsed: String = CCUtility.transformedSize(Double(tabAccount.quotaUsed))
+        let quotaUsed: String = CCUtility.transformedSize(tabAccount.quotaUsed)
 
         labelQuota.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_", comment: ""), quotaUsed, quota)
         
@@ -349,7 +349,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
                 item = settingsMenu[indexPath.row]
             }
 
-            cell.imageIcon?.image = CCGraphics.changeThemingColorImage(UIImage.init(named: item.icon), width: 50, height: 50, color: NCBrandColor.shared.icon)
+            cell.imageIcon?.image = UIImage.init(named: item.icon)?.image(color: NCBrandColor.shared.icon, size: 25)
             cell.labelText?.text = NSLocalizedString(item.name, comment: "")
             cell.labelText.textColor = NCBrandColor.shared.textView
             
@@ -417,7 +417,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource {
                 let manageAccount = CCManageAccount()
                 manageAccount.delete(self.appDelegate.account)
 
-                self.appDelegate.openLoginView(self, selector: Int(k_intro_login), openLoginWeb: false)
+                self.appDelegate.openLoginView(self, selector: NCBrandGlobal.shared.introLogin, openLoginWeb: false)
             }
 
             let actionNo = UIAlertAction(title: NSLocalizedString("_no_delete_", comment: ""), style: .default) { (action: UIAlertAction) in

+ 121 - 107
iOSClient/Networking/NCNetworking.swift

@@ -30,7 +30,7 @@ import Queuer
 @objc public protocol NCNetworkingDelegate {
     @objc optional func downloadProgress(_ progress: Double, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask)
     @objc optional func uploadProgress(_ progress: Double, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask)
-    @objc optional func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Double, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String)
+    @objc optional func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String)
     @objc optional func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String)
 }
 
@@ -43,6 +43,7 @@ import Queuer
     var delegate: NCNetworkingDelegate?
     
     var lastReachability: Bool = true
+    var networkReachability: NCCommunicationCommon.typeReachability?
     var downloadRequest: [String: DownloadRequest] = [:]
     var uploadRequest: [String: UploadRequest] = [:]
     var uploadMetadataInBackground: [String: tableMetadata] = [:]
@@ -116,12 +117,13 @@ import Queuer
         } else {
             
             if lastReachability {
-                NCContentPresenter.shared.messageNotification("_network_not_available_", description: nil, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: -1009)
+                NCContentPresenter.shared.messageNotification("_network_not_available_", description: nil, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: -1009)
             }
             lastReachability = false
         }
         
-        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_setTitleMain)
+        networkReachability = typeReachability
+        
         #endif
     }
     
@@ -138,7 +140,7 @@ import Queuer
         delegate?.downloadProgress?(progress, totalBytes: totalBytes, totalBytesExpected: totalBytesExpected, fileName: fileName, serverUrl: serverUrl, session: session, task: task)
     }
     
-    func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Double, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String) {
+    func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String) {
         delegate?.downloadComplete?(fileName: fileName, serverUrl: serverUrl, etag: etag, date: date, dateLastModified: dateLastModified, length: length, description: description, task: task, errorCode: errorCode, errorDescription: errorDescription)
     }
     
@@ -171,8 +173,9 @@ import Queuer
     
     @objc func wrtiteCertificate(directoryCertificate: String) {
         
+        let stringDate: String = String(Date().timeIntervalSince1970)
         let certificateAtPath = directoryCertificate + "/tmp.der"
-        let certificateToPath = directoryCertificate + "/" + CCUtility.getTimeIntervalSince197() + ".der"
+        let certificateToPath = directoryCertificate + "/" + stringDate + ".der"
         
         do {
             try FileManager.default.moveItem(atPath: certificateAtPath, toPath: certificateToPath)
@@ -229,14 +232,14 @@ import Queuer
             request.cancel()
         } else {
             if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                NCManageDatabase.shared.setMetadataSession(ocId: ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal))
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadCancelFile, userInfo: ["ocId":metadata.ocId])
+                NCManageDatabase.shared.setMetadataSession(ocId: ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusNormal)
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDownloadCancelFile, userInfo: ["ocId":metadata.ocId])
                 
             }
         }
     }
     
-    @objc func download(metadata: tableMetadata, selector: String, setFavorite: Bool = false, completion: @escaping (_ errorCode: Int)->()) {
+    @objc func download(metadata: tableMetadata, selector: String, completion: @escaping (_ errorCode: Int)->()) {
         
         let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
         let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)!
@@ -245,32 +248,32 @@ import Queuer
             NCManageDatabase.shared.addMetadata(tableMetadata.init(value: metadata))
         }
             
-        if metadata.status == Int(k_metadataStatusInDownload) || metadata.status == Int(k_metadataStatusDownloading) { return }
+        if metadata.status == NCBrandGlobal.shared.metadataStatusInDownload || metadata.status == NCBrandGlobal.shared.metadataStatusDownloading { return }
                 
-        NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierDownload, sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: Int(k_metadataStatusInDownload))
+        NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierDownload, sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusInDownload)
                     
         NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (request) in
             
             self.downloadRequest[fileNameLocalPath] = request
             
-            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, status: Int(k_metadataStatusDownloading))
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadStartFile, userInfo: ["ocId":metadata.ocId])
+            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, status: NCBrandGlobal.shared.metadataStatusDownloading)
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDownloadStartFile, userInfo: ["ocId":metadata.ocId])
             
         }, taskHandler: { (_) in
             
         }, progressHandler: { (progress) in
             
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, object: nil, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: k_metadataStatusInDownload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterProgressTask, object: nil, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: NCBrandGlobal.shared.metadataStatusInDownload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
             
         }) { (account, etag, date, length, allHeaderFields, error, errorCode, errorDescription) in
                        
             if error?.isExplicitlyCancelledError ?? false {
                             
-                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal))
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusNormal)
             
             } else if errorCode == 0 {
                
-                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal), etag: etag, setFavorite: setFavorite)
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: selector, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusNormal, etag: etag)
                 NCManageDatabase.shared.addLocalFile(metadata: metadata)
                 
                 #if !EXTENSION
@@ -283,7 +286,7 @@ import Queuer
                                 
             } else {
                                 
-                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: errorDescription, sessionSelector: selector, sessionTaskIdentifier: 0, status: Int(k_metadataStatusDownloadError))
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: errorDescription, sessionSelector: selector, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusDownloadError)
                 
                 #if !EXTENSION
                 if errorCode == 401 || errorCode == 403 {
@@ -296,9 +299,9 @@ import Queuer
             
             self.downloadRequest[fileNameLocalPath] = nil
             if error?.isExplicitlyCancelledError ?? false {
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadCancelFile, userInfo: ["ocId":metadata.ocId])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDownloadCancelFile, userInfo: ["ocId":metadata.ocId])
             } else {
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadedFile, userInfo: ["ocId":metadata.ocId, "selector":selector, "errorCode":errorCode, "errorDescription":errorDescription])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDownloadedFile, userInfo: ["ocId":metadata.ocId, "selector":selector, "errorCode":errorCode, "errorDescription":errorDescription])
             }
             
             completion(errorCode)
@@ -314,11 +317,10 @@ import Queuer
 
         guard let account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", metadata.account)) else {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            completion(Int(k_CCErrorInternalError), "Internal error")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "Internal error")
             return
         }
         
-        let internalContenType = NCCommunicationCommon.shared.getInternalContenType(fileName: metadata.fileNameView, contentType: metadata.contentType, directory: false)
         var fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
                    
         if CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) {
@@ -328,9 +330,10 @@ import Queuer
         if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
             let metadata = tableMetadata.init(value: metadata)
             
-            metadata.contentType = internalContenType.contentType
-            metadata.iconName = internalContenType.iconName
-            metadata.typeFile = internalContenType.typeFile
+            let results = NCCommunicationCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false)
+            metadata.contentType = results.mimeType
+            metadata.iconName = results.iconName
+            metadata.typeFile = results.typeFile
             if let date = NCUtilityFileSystem.shared.getFileCreationDate(filePath: fileNameLocalPath) {
                  metadata.creationDate = date
             }
@@ -357,7 +360,7 @@ import Queuer
                    
                 guard let extractMetadata = extractMetadata else {
                     NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                    completion(Int(k_CCErrorInternalError), "Internal error")
+                    completion(NCBrandGlobal.shared.ErrorInternalError, "Internal error")
                     return
                 }
                        
@@ -393,12 +396,12 @@ import Queuer
         }, taskHandler: { (task) in
             
             uploadTask = task
-            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task.taskIdentifier, status: Int(k_metadataStatusUploading))
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["ocId":metadata.ocId])
+            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task.taskIdentifier, status: NCBrandGlobal.shared.metadataStatusUploading)
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadStartFile, userInfo: ["ocId":metadata.ocId])
             
         }, progressHandler: { (progress) in
             
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterProgressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":metadata.serverUrl, "status":NSNumber(value: NCBrandGlobal.shared.metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
             
         }) { (account, ocId, etag, date, size, allHeaderFields, error, errorCode, errorDescription) in
          
@@ -422,18 +425,27 @@ import Queuer
             session = sessionManagerBackgroundWWan
         }
         
-        if let task = NCCommunicationBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: metadata.creationDate as Date, dateModificationFile: metadata.date as Date, description: metadata.ocId, session: session!) {
-                     
-            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task.taskIdentifier, status: Int(k_metadataStatusUploading))
-            
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["ocId":metadata.ocId])
-            
-            completion(0, "")
-            
-        } else {
-            
+        // Check file dim > 0
+        if NCUtilityFileSystem.shared.getFileSize(filePath: fileNameLocalPath) == 0 {
+        
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            completion(Int(k_CCErrorInternalError), "task null")
+            completion(404, NSLocalizedString("_error_not_found_", value: "The requested resource could not be found", comment: ""))
+        
+        } else {
+        
+            if let task = NCCommunicationBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: metadata.creationDate as Date, dateModificationFile: metadata.date as Date, description: metadata.ocId, session: session!) {
+                         
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, sessionError: "", sessionTaskIdentifier: task.taskIdentifier, status: NCBrandGlobal.shared.metadataStatusUploading)
+                
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadStartFile, userInfo: ["ocId":metadata.ocId])
+                
+                completion(0, "")
+                
+            } else {
+                
+                NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                completion(NCBrandGlobal.shared.ErrorInternalError, "task null")
+            }
         }
     }
     
@@ -451,7 +463,7 @@ import Queuer
         }
         
         if metadata != nil {
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata!.account, "ocId":metadata!.ocId, "serverUrl":serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress), "totalBytes":NSNumber(value: totalBytes), "totalBytesExpected":NSNumber(value: totalBytesExpected)])
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterProgressTask, userInfo: ["account":metadata!.account, "ocId":metadata!.ocId, "serverUrl":serverUrl, "status":NSNumber(value: NCBrandGlobal.shared.metadataStatusInUpload), "progress":NSNumber(value: progress), "totalBytes":NSNumber(value: totalBytes), "totalBytesExpected":NSNumber(value: totalBytesExpected)])
         }
     }
     
@@ -482,10 +494,10 @@ import Queuer
                 metadata.session = ""
                 metadata.sessionError = ""
                 metadata.sessionTaskIdentifier = 0
-                metadata.status = Int(k_metadataStatusNormal)
+                metadata.status = NCBrandGlobal.shared.metadataStatusNormal
                 
                 // Delete Asset on Photos album
-                if tableAccount.autoUploadDeleteAssetLocalIdentifier && metadata.assetLocalIdentifier != "" && metadata.sessionSelector == selectorUploadAutoUpload {
+                if tableAccount.autoUploadDeleteAssetLocalIdentifier && metadata.assetLocalIdentifier != "" && metadata.sessionSelector == NCBrandGlobal.shared.selectorUploadAutoUpload {
                     metadata.deleteAssetLocalIdentifier = true;
                 }
                 
@@ -508,15 +520,15 @@ import Queuer
                 #endif                
                 
                 NCCommunicationCommon.shared.writeLog("Upload complete " + serverUrl + "/" + fileName + ", result: success(\(size) bytes)")
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
                 
             } else {
                 
                 if errorCode == NSURLErrorCancelled {
                 
-                    if metadata.status == k_metadataStatusUploadForcedStart {
+                    if metadata.status == NCBrandGlobal.shared.metadataStatusUploadForcedStart {
                         
-                        NCManageDatabase.shared.setMetadataSession(ocId: ocId!, session: sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusInUpload))
+                        NCManageDatabase.shared.setMetadataSession(ocId: ocId!, session: sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusInUpload)
                         NCNetworking.shared.upload(metadata: metadata) { (_, _) in }
                                                 
                     } else {
@@ -525,7 +537,7 @@ import Queuer
                         NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
                     }
                     
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadCancelFile, userInfo: ["ocId":metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadCancelFile, userInfo: ["ocId":metadata.ocId])
                 
                 } else if errorCode == 401 || errorCode == 403 {
                     
@@ -533,12 +545,12 @@ import Queuer
                     NCNetworkingCheckRemoteUser.shared.checkRemoteUser(account: metadata.account)
                     #endif
                     
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
 
                 } else if errorCode == Int(CFNetworkErrors.cfurlErrorServerCertificateUntrusted.rawValue) {
                     
                     CCUtility.setCertificateError(metadata.account, error: true)
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
 
                 } else {
                     
@@ -547,10 +559,10 @@ import Queuer
                         NCCommunicationCommon.shared.writeLog("Upload error 0 length " + serverUrl + "/" + fileName + ", result: success(\(size) bytes)")
                     }
                     
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
                 }
                 
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
             }
             
             // Delete
@@ -562,18 +574,18 @@ import Queuer
         
         var session: URLSession?
         
-        // verify k_metadataStatusInUpload (BACKGROUND)
-        let metadatasInUploadBackground = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d AND sessionTaskIdentifier == 0", sessionIdentifierBackground, sessionIdentifierBackgroundExtension, sessionIdentifierBackgroundWWan, k_metadataStatusInUpload))
+        // verify metadataStatusInUpload (BACKGROUND)
+        let metadatasInUploadBackground = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d AND sessionTaskIdentifier == 0", sessionIdentifierBackground, sessionIdentifierBackgroundExtension, sessionIdentifierBackgroundWWan, NCBrandGlobal.shared.metadataStatusInUpload))
         for metadata in metadatasInUploadBackground {
             DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
-                if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d AND sessionTaskIdentifier == 0", metadata.ocId, k_metadataStatusInUpload)) {
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: self.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload))
+                if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d AND sessionTaskIdentifier == 0", metadata.ocId, NCBrandGlobal.shared.metadataStatusInUpload)) {
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: self.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusWaitUpload)
                 }
             }
         }
         
-        // k_metadataStatusUploading (BACKGROUND)
-        let metadatasUploadingBackground = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d", sessionIdentifierBackground, sessionIdentifierBackgroundWWan, sessionIdentifierBackgroundExtension, k_metadataStatusUploading))
+        // metadataStatusUploading (BACKGROUND)
+        let metadatasUploadingBackground = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d", sessionIdentifierBackground, sessionIdentifierBackgroundWWan, sessionIdentifierBackgroundExtension, NCBrandGlobal.shared.metadataStatusUploading))
         for metadata in metadatasUploadingBackground {
             
             if metadata.session == sessionIdentifierBackground {
@@ -592,19 +604,19 @@ import Queuer
                 }
                 
                 if taskUpload == nil {
-                    if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d", metadata.ocId, k_metadataStatusUploading)) {
-                        NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: self.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload))
+                    if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d", metadata.ocId, NCBrandGlobal.shared.metadataStatusUploading)) {
+                        NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: self.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusWaitUpload)
                     }
                 }
             })
         }
         
-        // k_metadataStatusUploading
-        let metadatasUploading = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "session == %@ AND status == %d", NCCommunicationCommon.shared.sessionIdentifierUpload, k_metadataStatusUploading))
+        // metadataStatusUploading
+        let metadatasUploading = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "session == %@ AND status == %d", NCCommunicationCommon.shared.sessionIdentifierUpload, NCBrandGlobal.shared.metadataStatusUploading))
         for metadata in metadatasUploading {
             let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
             if uploadRequest[fileNameLocalPath] == nil {
-                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload))
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusWaitUpload)
             }
         }
     }
@@ -654,7 +666,7 @@ import Queuer
             } else {
                 CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
                 NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadCancelFile, userInfo: ["ocId":metadata.ocId])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadCancelFile, userInfo: ["ocId":metadata.ocId])
             }
             
             completion()
@@ -669,7 +681,7 @@ import Queuer
         }
         if session == nil {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadCancelFile, userInfo: ["ocId":metadata.ocId])
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadCancelFile, userInfo: ["ocId":metadata.ocId])
             completion()
             return
         }
@@ -690,7 +702,7 @@ import Queuer
                     }
                     catch { }
                     NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadCancelFile, userInfo: ["ocId":metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadCancelFile, userInfo: ["ocId":metadata.ocId])
                 }
             }
             completion()
@@ -699,20 +711,20 @@ import Queuer
     
     @objc func cancelAllTransfer(account: String, completion: @escaping ()->()) {
        
-        NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "status == %d OR status == %d", account, k_metadataStatusWaitUpload, k_metadataStatusUploadError))
+        NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "status == %d OR status == %d", account, NCBrandGlobal.shared.metadataStatusWaitUpload, NCBrandGlobal.shared.metadataStatusUploadError))
         
-        let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status != %d", k_metadataStatusNormal))
+        let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status != %d", NCBrandGlobal.shared.metadataStatusNormal))
         
         var counter = 0
         for metadata in metadatas {
             counter += 1
 
-            if (metadata.status == k_metadataStatusWaitDownload || metadata.status == k_metadataStatusDownloadError) {
+            if (metadata.status == NCBrandGlobal.shared.metadataStatusWaitDownload || metadata.status == NCBrandGlobal.shared.metadataStatusDownloadError) {
                 
-                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal))
+                NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusNormal)
             }
             
-            if metadata.status == k_metadataStatusDownloading || metadata.status == k_metadataStatusUploading {
+            if metadata.status == NCBrandGlobal.shared.metadataStatusDownloading || metadata.status == NCBrandGlobal.shared.metadataStatusUploading {
                 
                 self.cancelTransferMetadata(metadata) {
                     if counter == metadatas.count {
@@ -751,7 +763,7 @@ import Queuer
                         NCManageDatabase.shared.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: metadata.richWorkspace, account: account)
                     }
                     
-                    let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
+                    let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCBrandGlobal.shared.metadataStatusNormal))
                     let metadatasChanged = NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult, addCompareEtagLocal: true)
                     
                     completion(account, metadataFolder, metadatas, metadatasChanged.metadatasUpdate, metadatasChanged.metadatasLocalUpdate, errorCode, "")
@@ -833,7 +845,7 @@ import Queuer
         var fileNameFolder = CCUtility.removeForbiddenCharactersServer(fileName)!
         
         if (!overwrite) {
-            fileNameFolder = NCUtility.shared.createFileName(fileNameFolder, serverUrl: serverUrl, account: account)
+            fileNameFolder = NCUtilityFileSystem.shared.createFileName(fileNameFolder, serverUrl: serverUrl, account: account)
         }
         if fileNameFolder.count == 0 {
             completion(0, "")
@@ -856,7 +868,7 @@ import Queuer
                         }
                         
                         if let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadataFolder?.ocId) {
-                            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_createFolder, userInfo: ["ocId": metadata.ocId])
+                            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId])
                         }
                     }
                     
@@ -911,22 +923,32 @@ import Queuer
                 
         if (onlyLocal) {
             
-            NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            NCUtilityFileSystem.shared.deleteFile(filePath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
+            var metadatas = [metadata]
             
-            if let metadataLivePhoto = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
-                NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadataLivePhoto.ocId))
-                NCUtilityFileSystem.shared.deleteFile(filePath: CCUtility.getDirectoryProviderStorageOcId(metadataLivePhoto.ocId))
+            if metadata.directory {
+                let serverUrl = metadata.serverUrl + "/" + metadata.fileName
+                metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND directory == false", account, serverUrl))
             }
             
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_deleteFile, userInfo: ["ocId": metadata.ocId, "fileNameView": metadata.fileNameView, "typeFile": metadata.typeFile, "onlyLocal": true])
+            for metadata in metadatas {
+            
+                NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                NCUtilityFileSystem.shared.deleteFile(filePath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
+            
+                if let metadataLivePhoto = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
+                    NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadataLivePhoto.ocId))
+                    NCUtilityFileSystem.shared.deleteFile(filePath: CCUtility.getDirectoryProviderStorageOcId(metadataLivePhoto.ocId))
+                }
+            
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": metadata.ocId, "fileNameView": metadata.fileNameView, "typeFile": metadata.typeFile, "onlyLocal": true])
+            }
             completion(0, "")
             
             return
         }
         
         let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: urlBase)
-        let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata)
+        let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
         
         if isDirectoryEncrypted {
             #if !EXTENSION
@@ -960,17 +982,17 @@ import Queuer
     func deleteMetadataPlain(_ metadata: tableMetadata, addCustomHeaders: [String: String]?, completion: @escaping (_ errorCode: Int, _ errorDescription: String)->()) {
         
         // verify permission
-        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: k_permission_can_delete)
+        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCBrandGlobal.shared.permissionCanDelete)
         if metadata.permissions != "" && permission == false {
             
-            completion(Int(k_CCErrorInternalError), "_no_permission_delete_file_")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_no_permission_delete_file_")
             return
         }
                 
         let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
         NCCommunication.shared.deleteFileOrFolder(serverUrlFileName, customUserAgent: nil, addCustomHeaders: addCustomHeaders) { (account, errorCode, errorDescription) in
         
-            if errorCode == 0 || errorCode == k_CCErrorResourceNotFound {
+            if errorCode == 0 || errorCode == NCBrandGlobal.shared.ErrorResourceNotFound {
                 
                 do {
                     try FileManager.default.removeItem(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
@@ -983,7 +1005,7 @@ import Queuer
                     NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName), account: metadata.account)
                 }
                 
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_deleteFile, userInfo: ["ocId": metadata.ocId, "fileNameView": metadata.fileNameView, "typeFile": metadata.typeFile, "onlyLocal": true])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": metadata.ocId, "fileNameView": metadata.fileNameView, "typeFile": metadata.typeFile, "onlyLocal": true])
             }
             
             completion(errorCode, errorDescription)
@@ -994,7 +1016,7 @@ import Queuer
 
     @objc func favoriteMetadata(_ metadata: tableMetadata, urlBase: String, completion: @escaping (_ errorCode: Int, _ errorDescription: String)->()) {
         
-        if let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
             favoriteMetadataPlain(metadataLive, urlBase: urlBase) { (errorCode, errorDescription) in
                 if errorCode == 0 {
                     self.favoriteMetadataPlain(metadata, urlBase: urlBase, completion: completion)
@@ -1018,23 +1040,15 @@ import Queuer
             if errorCode == 0 && metadata.account == account {
                 
                 NCManageDatabase.shared.setMetadataFavorite(ocId: metadata.ocId, favorite: favorite)
-                if !favorite && metadata.directory {
-                    let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-                    NCManageDatabase.shared.removeDirectoriesSynchronized(serverUrl: serverUrl, account: account)
-                }
-                
+               
                 #if !EXTENSION
                 if favorite {
-                    if CCUtility.getFavoriteOffline() {
-                        NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadAllFile)
-                    } else {
-                        NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorReadFile)
-                    }
+                    NCOperationQueue.shared.synchronizationMetadata(metadata, selector: NCBrandGlobal.shared.selectorReadFile)
                 }
                 #endif
                 
                 if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_favoriteFile, userInfo: ["ocId": metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterFavoriteFile, userInfo: ["ocId": metadata.ocId])
                 }
             }
             
@@ -1047,7 +1061,7 @@ import Queuer
             if errorCode == 0 {
                 NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: account) { (_, _, metadatas) in
                     NCManageDatabase.shared.updateMetadatasFavorite(account: account, metadatas: metadatas)
-                    if selector != selectorListingFavorite {
+                    if selector != NCBrandGlobal.shared.selectorListingFavorite {
                         #if !EXTENSION
                         for metadata in metadatas {
                             NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selector)
@@ -1067,7 +1081,7 @@ import Queuer
     @objc func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, urlBase: String, viewController: UIViewController?, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
         
         let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: urlBase)
-        let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata)
+        let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata)
         let fileNameNewLive = (fileNameNew as NSString).deletingPathExtension + ".mov"
 
         if isDirectoryEncrypted {
@@ -1101,9 +1115,9 @@ import Queuer
     
     private func renameMetadataPlain(_ metadata: tableMetadata, fileNameNew: String, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
         
-        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: k_permission_can_rename)
+        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCBrandGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
-            completion(Int(k_CCErrorInternalError), "_no_permission_modify_file_")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_no_permission_modify_file_")
             return
         }
         guard let fileNameNew = CCUtility.removeForbiddenCharactersServer(fileNameNew) else {
@@ -1146,7 +1160,7 @@ import Queuer
                 }
                 
                 if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_renameFile, userInfo: ["ocId": metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId])
                 }
             }
                     
@@ -1158,7 +1172,7 @@ import Queuer
     
     @objc func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
         
-        if let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
             moveMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
                 if errorCode == 0 {
                     self.moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
@@ -1173,9 +1187,9 @@ import Queuer
 
     private func moveMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
     
-        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: k_permission_can_rename)
+        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCBrandGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
-            completion(Int(k_CCErrorInternalError), "_no_permission_modify_file_")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_no_permission_modify_file_")
             return
         }
         
@@ -1193,7 +1207,7 @@ import Queuer
                 
                 NCManageDatabase.shared.moveMetadata(ocId: metadata.ocId, serverUrlTo: serverUrlTo)
 
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_moveFile, userInfo: ["ocId": metadata.ocId, "serverUrlFrom": serverUrlFrom])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterMoveFile, userInfo: ["ocId": metadata.ocId, "serverUrlFrom": serverUrlFrom])
             }
             
             completion(errorCode, errorDescription)
@@ -1204,7 +1218,7 @@ import Queuer
     
     @objc func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
         
-        if let metadataLive = NCManageDatabase.shared.isLivePhoto(metadata: metadata) {
+        if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
             copyMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
                 if errorCode == 0 {
                     self.copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite, completion: completion)
@@ -1219,9 +1233,9 @@ import Queuer
 
     private func copyMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) {
     
-        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: k_permission_can_rename)
+        let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCBrandGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
-            completion(Int(k_CCErrorInternalError), "_no_permission_modify_file_")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_no_permission_modify_file_")
             return
         }
         
@@ -1232,7 +1246,7 @@ import Queuer
                    
             if errorCode == 0 {
                 
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_copyFile, userInfo: ["ocId": metadata.ocId, "serverUrlTo": serverUrlTo])
+                NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterCopyFile, userInfo: ["ocId": metadata.ocId, "serverUrlTo": serverUrlTo])
             }
             
             completion(errorCode, errorDescription)

+ 40 - 12
iOSClient/Networking/NCNetworkingAutoUpload.swift

@@ -41,7 +41,7 @@ class NCNetworkingAutoUpload: NSObject {
     }
     
     func startTimer() {
-        timerProcess = Timer.scheduledTimer(timeInterval: TimeInterval(k_timerAutoUpload), target: self, selector: #selector(process), userInfo: nil, repeats: true)
+        timerProcess = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(process), userInfo: nil, repeats: true)
     }
 
     @objc private func process() {
@@ -51,14 +51,14 @@ class NCNetworkingAutoUpload: NSObject {
         var counterUpload: Int = 0
         var sizeUpload = 0
         var maxConcurrentOperationUpload = 5
-        let sessionSelectors = [selectorUploadFile, selectorUploadAutoUpload, selectorUploadAutoUploadAll]
+        let sessionSelectors = [NCBrandGlobal.shared.selectorUploadFile, NCBrandGlobal.shared.selectorUploadAutoUpload, NCBrandGlobal.shared.selectorUploadAutoUploadAll]
         
-        let metadatasUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", k_metadataStatusInUpload, k_metadataStatusUploading))
+        let metadatasUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", NCBrandGlobal.shared.metadataStatusInUpload, NCBrandGlobal.shared.metadataStatusUploading))
         counterUpload = metadatasUpload.count
         for metadata in metadatasUpload {
             sizeUpload = sizeUpload + Int(metadata.size)
         }
-        if sizeUpload > k_maxSizeOperationUpload { return }
+        if sizeUpload > NCBrandGlobal.shared.uploadMaxFileSize { return }
         
         timerProcess?.invalidate()
         
@@ -71,9 +71,9 @@ class NCNetworkingAutoUpload: NSObject {
                     let limit = maxConcurrentOperationUpload - counterUpload
                     var predicate = NSPredicate()
                     if UIApplication.shared.applicationState == .background {
-                        predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d AND (typeFile != %@ || livePhoto == true)", sessionSelector, k_metadataStatusWaitUpload, k_metadataTypeFile_video)
+                        predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d AND (typeFile != %@ || livePhoto == true)", sessionSelector, NCBrandGlobal.shared.metadataStatusWaitUpload, NCBrandGlobal.shared.metadataTypeFileVideo)
                     } else {
-                        predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d", sessionSelector, k_metadataStatusWaitUpload)
+                        predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d", sessionSelector, NCBrandGlobal.shared.metadataStatusWaitUpload)
                     }
                     let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: predicate, page: 1, limit: limit, sorted: "date", ascending: true)
                     if metadatas.count > 0 {
@@ -97,18 +97,18 @@ class NCNetworkingAutoUpload: NSObject {
                             if UIApplication.shared.applicationState == .background { break }
                             maxConcurrentOperationUpload = 1
                             counterUpload += 1
-                            if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: Int(k_metadataStatusInUpload)) {
+                            if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCBrandGlobal.shared.metadataStatusInUpload) {
                                 NCNetworking.shared.upload(metadata: metadata) { (_, _) in }
                             }
                             self.startTimer()
                             return
                         } else {
                             counterUpload += 1
-                            if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: Int(k_metadataStatusInUpload)) {
+                            if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCBrandGlobal.shared.metadataStatusInUpload) {
                                 NCNetworking.shared.upload(metadata: metadata) { (_, _) in }
                             }
                             sizeUpload = sizeUpload + Int(metadata.size)
-                            if sizeUpload > k_maxSizeOperationUpload {
+                            if sizeUpload > NCBrandGlobal.shared.uploadMaxFileSize {
                                 self.startTimer()
                                 return
                             }
@@ -123,15 +123,15 @@ class NCNetworkingAutoUpload: NSObject {
             
             // No upload available ? --> Retry Upload in Error
             if counterUpload == 0 {
-                let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d", k_metadataStatusUploadError))
+                let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d", NCBrandGlobal.shared.metadataStatusUploadError))
                 for metadata in metadatas {
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCNetworking.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0 ,status: Int(k_metadataStatusWaitUpload))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCNetworking.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0 ,status: NCBrandGlobal.shared.metadataStatusWaitUpload)
                 }
             }
              
             // verify delete Asset Local Identifiers in auto upload (DELETE Photos album)
             if (counterUpload == 0 && self.appDelegate.passcodeViewController == nil) {
-                NCUtility.shared.deleteAssetLocalIdentifiers(account: self.appDelegate.account, sessionSelector: selectorUploadAutoUpload) {
+                self.deleteAssetLocalIdentifiers(account: self.appDelegate.account, sessionSelector: NCBrandGlobal.shared.selectorUploadAutoUpload) {
                     self.startTimer()
                 }
             } else {
@@ -139,5 +139,33 @@ class NCNetworkingAutoUpload: NSObject {
             }
         }
     }
+    
+    private func deleteAssetLocalIdentifiers(account: String, sessionSelector: String, completition: @escaping () -> ()) {
+        
+        if UIApplication.shared.applicationState != .active {
+            completition()
+            return
+        }
+        let metadatasSessionUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND session CONTAINS[cd] %@", account, "upload"))
+        if metadatasSessionUpload.count > 0 {
+            completition()
+            return
+        }
+        let localIdentifiers = NCManageDatabase.shared.getAssetLocalIdentifiersUploaded(account: account, sessionSelector: sessionSelector)
+        if localIdentifiers.count == 0 {
+            completition()
+            return
+        }
+        let assets = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil)
+        
+        PHPhotoLibrary.shared().performChanges({
+            PHAssetChangeRequest.deleteAssets(assets as NSFastEnumeration)
+        }, completionHandler: { success, error in
+            DispatchQueue.main.async {
+                NCManageDatabase.shared.clearAssetLocalIdentifiers(localIdentifiers, account: account)
+                completition()
+            }
+        })
+    }
 }
 

+ 4 - 4
iOSClient/Networking/NCNetworkingCheckRemoteUser.swift

@@ -43,7 +43,7 @@ import NCCommunication
         let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
         guard let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) else { return }
         
-        if serverVersionMajor >= k_nextcloud_version_17_0 {
+        if serverVersionMajor >= NCBrandGlobal.shared.nextcloudVersion17 {
             
             guard let token = CCUtility.getPassword(account) else { return }
             
@@ -52,7 +52,7 @@ import NCCommunication
                 if wipe {
                     
                     self.appDelegate.deleteAccount(account, wipe: true)
-                    NCContentPresenter.shared.messageNotification(tableAccount.user, description: "_wipe_account_", delay: TimeInterval(k_dismissAfterSecond*2), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+                    NCContentPresenter.shared.messageNotification(tableAccount.user, description: "_wipe_account_", delay: NCBrandGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                     NCCommunication.shared.setRemoteWipeCompletition(serverUrl: tableAccount.urlBase, token: token) { (account, errorCode, errorDescription) in
                         print("wipe");
                     }
@@ -61,7 +61,7 @@ import NCCommunication
                     
                     if UIApplication.shared.applicationState == .active &&  NCCommunication.shared.isNetworkReachable() {
                         let description = String.localizedStringWithFormat(NSLocalizedString("_error_check_remote_user_", comment: ""), tableAccount.user, tableAccount.urlBase)
-                        NCContentPresenter.shared.messageNotification("_error_", description: description, delay: TimeInterval(k_dismissAfterSecond*2), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                        NCContentPresenter.shared.messageNotification("_error_", description: description, delay: NCBrandGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                         CCUtility.setPassword(account, password: nil)
                     }
                 }
@@ -73,7 +73,7 @@ import NCCommunication
                
             if UIApplication.shared.applicationState == .active &&  NCCommunication.shared.isNetworkReachable() {
                 let description = String.localizedStringWithFormat(NSLocalizedString("_error_check_remote_user_", comment: ""), tableAccount.user, tableAccount.urlBase)
-                NCContentPresenter.shared.messageNotification("_error_", description: description, delay: TimeInterval(k_dismissAfterSecond*2), type: NCContentPresenter.messageType.error, errorCode: 403)
+                NCContentPresenter.shared.messageNotification("_error_", description: description, delay: NCBrandGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.error, errorCode: 403)
                 CCUtility.setPassword(account, password: nil)
             }
             

+ 27 - 27
iOSClient/Networking/NCNetworkingE2EE.swift

@@ -41,7 +41,7 @@ import Alamofire
         var key: NSString?
         var initializationVector: NSString?
         
-        fileNameFolder = NCUtility.shared.createFileName(fileNameFolder, serverUrl: serverUrl, account: account)
+        fileNameFolder = NCUtilityFileSystem.shared.createFileName(fileNameFolder, serverUrl: serverUrl, account: account)
         if fileNameFolder.count == 0 {
             completion(0, "")
             return
@@ -59,7 +59,7 @@ import Alamofire
                             if let tableLock = NCManageDatabase.shared.getE2ETokenLock(account: account, serverUrl: serverUrl) {
                                 NCCommunication.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, method: "DELETE") { (_, _, _, _) in }
                             }
-                            completion(Int(k_CCErrorInternalError), "Error convert ocId")
+                            completion(NCBrandGlobal.shared.ErrorInternalError, "Error convert ocId")
                             return
                         }
                         NCCommunication.shared.markE2EEFolder(fileId: fileId, delete: false) { (account, errorCode, errorDescription) in
@@ -96,7 +96,7 @@ import Alamofire
                                         NCCommunication.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, method: "DELETE") { (_, _, _, _) in }
                                     }
                                     if errorCode == 0 {
-                                        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_createFolder, userInfo: nil)
+                                        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterCreateFolder, userInfo: nil)
                                     }
                                     completion(errorCode, errorDescription ?? "")
                                 }
@@ -133,7 +133,7 @@ import Alamofire
                 let deleteE2eEncryption = NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", metadata.account, metadata.serverUrl, metadata.fileName)
                 NCNetworking.shared.deleteMetadataPlain(metadata, addCustomHeaders: ["e2e-token" :e2eToken!]) { (errorCode, errorDescription) in
                     
-                    let home = NCUtility.shared.getHomeServer(urlBase: metadata.urlBase, account: metadata.account)
+                    let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: metadata.urlBase, account: metadata.account)
                     if metadata.serverUrl != home {
                         self.sendE2EMetadata(account: metadata.account, serverUrl: metadata.serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: deleteE2eEncryption, urlBase: urlBase) { (e2eToken, errorCode, errorDescription) in
                             // unlock
@@ -163,7 +163,7 @@ import Alamofire
         // verify if exists the new fileName
         if NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, fileNameNew)) != nil {
             
-            completion(Int(k_CCErrorInternalError), "_file_already_exists_")
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_file_already_exists_")
 
         } else {
             
@@ -179,7 +179,7 @@ import Alamofire
                         try FileManager.default.moveItem(atPath: atPath, toPath: toPath)
                     } catch { }
                     
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_renameFile, userInfo: ["ocId": metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId])
                 }
                 
                 // unlock
@@ -202,11 +202,11 @@ import Alamofire
         let serverUrl = metadata.serverUrl
         
         // Verify max size
-        if metadata.size > Double(k_max_filesize_E2EE) {
+        if metadata.size > NCBrandGlobal.shared.e2eeMaxFileSize {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
 
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":k_CCErrorInternalError, "errorDescription":"E2E Error file too big"])
-            completion(Int(k_CCErrorInternalError), "E2E Error file too big")
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":NCBrandGlobal.shared.ErrorInternalError, "errorDescription":"E2E Error file too big"])
+            completion(NCBrandGlobal.shared.ErrorInternalError, "E2E Error file too big")
             return
         }
         
@@ -225,8 +225,8 @@ import Alamofire
         if NCEndToEndEncryption.sharedManager()?.encryptFileName(metadata.fileNameView, fileNameIdentifier: metadata.fileName, directory: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), key: &key, initializationVector: &initializationVector, authenticationTag: &authenticationTag) == false {
             
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":k_CCErrorInternalError, "errorDescription":"_e2e_error_create_encrypted_"])
-            completion(Int(k_CCErrorInternalError), "_e2e_error_create_encrypted_")
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":NCBrandGlobal.shared.ErrorInternalError, "errorDescription":"_e2e_error_create_encrypted_"])
+            completion(NCBrandGlobal.shared.ErrorInternalError, "_e2e_error_create_encrypted_")
             return
         }
         
@@ -258,7 +258,7 @@ import Alamofire
             return
         }
         
-        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl])
+        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterReloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl])
         
         NCNetworkingE2EE.shared.sendE2EMetadata(account: metadata.account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, urlBase: account.urlBase, upload: true) { (e2eToken, errorCode, errorDescription) in
             
@@ -267,15 +267,15 @@ import Alamofire
                 NCCommunication.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: metadata.date as Date, dateModificationFile: metadata.date as Date, addCustomHeaders: ["e2e-token":e2eToken!], requestHandler: { (request) in
                     
                     NCNetworking.shared.uploadRequest[fileNameLocalPathRequest] = request
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: nil, sessionSelector: nil, sessionTaskIdentifier: nil, status: Int(k_metadataStatusUploading))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: nil, sessionSelector: nil, sessionTaskIdentifier: nil, status: NCBrandGlobal.shared.metadataStatusUploading)
                     
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadStartFile, userInfo: ["ocId":metadata.ocId])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadStartFile, userInfo: ["ocId":metadata.ocId])
                 
                 }, taskHandler: { (_) in
                     
                 }, progressHandler: { (progress) in
                     
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterProgressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":serverUrl, "status":NSNumber(value: NCBrandGlobal.shared.metadataStatusInUpload), "progress":NSNumber(value: progress.fractionCompleted), "totalBytes":NSNumber(value: progress.totalUnitCount), "totalBytesExpected":NSNumber(value: progress.completedUnitCount)])
                     
                 }) { (account, ocId, etag, date, size, allHeaderFields, error, errorCode, errorDescription) in
                 
@@ -286,7 +286,7 @@ import Alamofire
                     
                         CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
                         NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
+                        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
 
                     } else if errorCode == 0 && ocId != nil {
                         
@@ -302,34 +302,34 @@ import Alamofire
                         metadata.session = ""
                         metadata.sessionError = ""
                         metadata.sessionTaskIdentifier = 0
-                        metadata.status = Int(k_metadataStatusNormal)
+                        metadata.status = NCBrandGlobal.shared.metadataStatusNormal
                         
                         NCManageDatabase.shared.addMetadata(metadata)
                         NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
                         NCManageDatabase.shared.addLocalFile(metadata: metadata)
                         
-                        CCGraphics.createNewImage(from: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, typeFile: metadata.typeFile)
-                        
-                        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp ,"errorCode":errorCode, "errorDescription":""])
+                        NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, typeFile: metadata.typeFile)
+                                                
+                        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp ,"errorCode":errorCode, "errorDescription":""])
                                                                                     
                     } else {
                         
                         if errorCode == 401 || errorCode == 403 {
                         
                             NCNetworkingCheckRemoteUser.shared.checkRemoteUser(account: metadata.account)
-                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
                         
                         } else if errorCode == Int(CFNetworkErrors.cfurlErrorServerCertificateUntrusted.rawValue) {
                         
                             CCUtility.setCertificateError(metadata.account, error: true)
-                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
                                                 
                         } else {
                         
-                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
                         }
                         
-                        NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
+                        NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":""])
                     }
                     
                     NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: serverUrl) { (_, _, _, _) in }
@@ -340,9 +340,9 @@ import Alamofire
             } else {
                 
                 if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocIdTemp) {
-                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError))
+                    NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: NCBrandGlobal.shared.metadataStatusUploadError)
 
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":errorDescription ?? ""])
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId":metadata.ocId, "ocIdTemp":ocIdTemp, "errorCode":errorCode, "errorDescription":errorDescription ?? ""])
                 }
                 
                 completion(errorCode, errorDescription ?? "")
@@ -405,7 +405,7 @@ import Alamofire
                     
                     if errorCode == 0 && e2eMetadata != nil {
                         if !NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata!, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: serverUrl, account: account, urlBase: urlBase) {
-                            completion(e2eToken, Int(k_CCErrorInternalError), NSLocalizedString("_e2e_error_encode_metadata_", comment: ""))
+                            completion(e2eToken, NCBrandGlobal.shared.ErrorInternalError, NSLocalizedString("_e2e_error_encode_metadata_", comment: ""))
                             return
                         }
                         method = "PUT"

+ 32 - 52
iOSClient/Networking/NCNetworkingNotificationCenter.swift

@@ -27,8 +27,8 @@ import Foundation
     @objc public static let shared: NCNetworkingNotificationCenter = {
         let instance = NCNetworkingNotificationCenter()
         
-        NotificationCenter.default.addObserver(instance, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_downloadedFile), object: nil)
-        NotificationCenter.default.addObserver(instance, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: k_notificationCenter_uploadedFile), object: nil)
+        NotificationCenter.default.addObserver(instance, selector: #selector(downloadedFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterDownloadedFile), object: nil)
+        NotificationCenter.default.addObserver(instance, selector: #selector(uploadedFile(_:)), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterUploadedFile), object: nil)
         
         return instance
     }()
@@ -53,7 +53,7 @@ import Foundation
                     documentController?.delegate = self
 
                     switch selector {
-                    case selectorLoadFileQuickLook:
+                    case NCBrandGlobal.shared.selectorLoadFileQuickLook:
                         
                         let fileNamePath = NSTemporaryDirectory() + metadata.fileNameView
                         CCUtility.copyFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView), toPath: fileNamePath)
@@ -61,7 +61,7 @@ import Foundation
                         viewerQuickLook = NCViewerQuickLook.init()
                         viewerQuickLook?.quickLook(url: URL(fileURLWithPath: fileNamePath))
                         
-                    case selectorLoadFileView:
+                    case NCBrandGlobal.shared.selectorLoadFileView:
                         
                         if UIApplication.shared.applicationState == UIApplication.State.active {
                                                         
@@ -71,13 +71,13 @@ import Foundation
                                     documentController?.presentOptionsMenu(from: CGRect.zero, in: view, animated: true)
                                 }
                                 
-                            } else if metadata.typeFile == k_metadataTypeFile_compress || metadata.typeFile == k_metadataTypeFile_unknown {
+                            } else if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileCompress || metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileUnknown {
 
                                 if let view = appDelegate.window?.rootViewController?.view {
                                     documentController?.presentOptionsMenu(from: CGRect.zero, in: view, animated: true)
                                 }
                                 
-                            } else if metadata.typeFile == k_metadataTypeFile_imagemeter {
+                            } else if metadata.typeFile == NCBrandGlobal.shared.metadataTypeFileImagemeter {
                                 
                                 if let view = appDelegate.window?.rootViewController?.view {
                                     documentController?.presentOptionsMenu(from: CGRect.zero, in: view, animated: true)
@@ -89,7 +89,7 @@ import Foundation
                             }
                         }
                         
-                    case selectorOpenIn:
+                    case NCBrandGlobal.shared.selectorOpenIn:
                         
                         if UIApplication.shared.applicationState == UIApplication.State.active {
                             
@@ -98,47 +98,34 @@ import Foundation
                             }
                         }
                         
-                    case selectorLoadCopy:
+                    case NCBrandGlobal.shared.selectorLoadCopy:
                         
-                        var items = UIPasteboard.general.items
+                        NCCollectionCommon.shared.copyPasteboard()
                         
-                        do {
-                            let etagPasteboard = try NSKeyedArchiver.archivedData(withRootObject: metadata.ocId, requiringSecureCoding: false)
-                            items.append([k_metadataKeyedUnarchiver:etagPasteboard])
-                        } catch {
-                            print("error")
-                        }
-                        
-                        UIPasteboard.general.setItems(items, options: [:])
-                        
-                    case selectorLoadOffline:
+                    case NCBrandGlobal.shared.selectorLoadOffline:
                         
                         NCManageDatabase.shared.setLocalFile(ocId: metadata.ocId, offline: true)
                        
-                    case selectorSaveAlbum:
+                    case NCBrandGlobal.shared.selectorSaveAlbum:
                         
-                        let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
-                        let status = PHPhotoLibrary.authorizationStatus()
-
-                        if metadata.typeFile == k_metadataTypeFile_image && status == PHAuthorizationStatus.authorized {
-                            
-                            if let image = UIImage.init(contentsOfFile: fileNamePath) {
-                                UIImageWriteToSavedPhotosAlbum(image, self, #selector(SaveAlbum(_:didFinishSavingWithError:contextInfo:)), nil)
-                            } else {
-                                NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorFileNotSaved))
-                            }
-                            
-                        } else if metadata.typeFile == k_metadataTypeFile_video && status == PHAuthorizationStatus.authorized {
-                            
-                            if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(fileNamePath) {
-                                UISaveVideoAtPathToSavedPhotosAlbum(fileNamePath, self, #selector(SaveAlbum(_:didFinishSavingWithError:contextInfo:)), nil)
-                            } else {
-                                NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorFileNotSaved))
-                            }
-                            
-                        } else if status != PHAuthorizationStatus.authorized {
+                        NCCollectionCommon.shared.saveAlbum(metadata: metadata)
+                        
+                    case NCBrandGlobal.shared.selectorSaveAlbumLivePhotoIMG, NCBrandGlobal.shared.selectorSaveAlbumLivePhotoMOV:
+                        
+                        var metadata = metadata
+                        var metadataMOV = metadata
+                        guard let metadataTMP = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) else { break }
+                        
+                        if selector == NCBrandGlobal.shared.selectorSaveAlbumLivePhotoIMG {
+                            metadataMOV = metadataTMP
+                        }
+                        
+                        if selector == NCBrandGlobal.shared.selectorSaveAlbumLivePhotoMOV {
+                            metadata = metadataTMP
+                        }
                             
-                            NCContentPresenter.shared.messageNotification("_access_photo_not_enabled_", description: "_access_photo_not_enabled_msg_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorFileNotSaved))
+                        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && CCUtility.fileProviderStorageExists(metadataMOV.ocId, fileNameView: metadataMOV.fileNameView) {
+                            NCCollectionCommon.shared.saveLivePhotoToDisk(metadata: metadata, metadataMov: metadataMOV, progressView: nil, viewActivity: self.appDelegate.window.rootViewController?.view)
                         }
                         
                     default:
@@ -149,7 +136,7 @@ import Foundation
                 } else {
                     
                     // File do not exists on server, remove in local
-                    if (errorCode == k_CCErrorResourceNotFound || errorCode == k_CCErrorBadServerResponse) {
+                    if (errorCode == NCBrandGlobal.shared.ErrorResourceNotFound || errorCode == NCBrandGlobal.shared.ErrorBadServerResponse) {
                         
                         do {
                             try FileManager.default.removeItem(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
@@ -160,7 +147,7 @@ import Foundation
                         
                     } else {
                         
-                        NCContentPresenter.shared.messageNotification("_download_file_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                        NCContentPresenter.shared.messageNotification("_download_file_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                     }
                 }
             }
@@ -183,7 +170,7 @@ import Foundation
         
         if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
             
-            NotificationCenter.default.postOnMainThread(name: k_notificationCenter_downloadedFile, userInfo: ["ocId": metadata.ocId, "selector": selector, "errorCode": 0, "errorDescription": "" ])
+            NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterDownloadedFile, userInfo: ["ocId": metadata.ocId, "selector": selector, "errorCode": 0, "errorDescription": "" ])
                                     
         } else {
             
@@ -191,13 +178,6 @@ import Foundation
         }
     }
     
-    @objc func SaveAlbum(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
-        
-        if error != nil {
-            NCContentPresenter.shared.messageNotification("_save_selected_files_", description: "_file_not_saved_cameraroll_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorFileNotSaved))
-        }
-    }
-    
     //MARK: - Upload
 
     @objc func uploadedFile(_ notification: NSNotification) {
@@ -208,7 +188,7 @@ import Foundation
                 if metadata.account == appDelegate.account {
                     if errorCode != 0 {
                         if errorCode != -999 && errorCode != 401 && errorDescription != "" {
-                            NCContentPresenter.shared.messageNotification("_upload_file_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                            NCContentPresenter.shared.messageNotification("_upload_file_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                         }
                     }
                 }

+ 25 - 31
iOSClient/Networking/NCOperationQueue.swift

@@ -50,13 +50,13 @@ import NCCommunication
     
     // Download file
     
-    @objc func download(metadata: tableMetadata, selector: String, setFavorite: Bool) {
+    func download(metadata: tableMetadata, selector: String) {
         for operation in downloadQueue.operations as! [NCOperationDownload]  {
             if operation.metadata.ocId == metadata.ocId {
                 return
             }
         }
-        downloadQueue.addOperation(NCOperationDownload.init(metadata: metadata, selector: selector, setFavorite: setFavorite))
+        downloadQueue.addOperation(NCOperationDownload.init(metadata: metadata, selector: selector))
     }
     @objc func downloadCancelAll() {
         downloadQueue.cancelAll()
@@ -124,7 +124,7 @@ import NCCommunication
     // Download Thumbnail
     
     @objc func downloadThumbnail(metadata: tableMetadata, urlBase: String, view: Any, indexPath: IndexPath) {
-        if metadata.hasPreview && metadata.status == k_metadataStatusNormal && (!CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
+        if metadata.hasPreview && metadata.status == NCBrandGlobal.shared.metadataStatusNormal && (!CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
             for operation in downloadThumbnailQueue.operations as! [NCOperationDownloadThumbnail] {
                 if operation.metadata.ocId == metadata.ocId {
                     return
@@ -153,19 +153,17 @@ class NCOperationDownload: ConcurrentOperation {
    
     var metadata: tableMetadata
     var selector: String
-    var setFavorite: Bool
     
-    init(metadata: tableMetadata, selector: String, setFavorite: Bool) {
+    init(metadata: tableMetadata, selector: String) {
         self.metadata = tableMetadata.init(value: metadata)
         self.selector = selector
-        self.setFavorite = setFavorite
     }
     
     override func start() {
         if isCancelled {
             self.finish()
         } else {
-            NCNetworking.shared.download(metadata: metadata, selector: self.selector, setFavorite: self.setFavorite) { (_) in
+            NCNetworking.shared.download(metadata: metadata, selector: self.selector) { (_) in
                 self.finish()
             }
         }
@@ -190,7 +188,7 @@ class NCOperationDelete: ConcurrentOperation {
         } else {
             NCNetworking.shared.deleteMetadata(metadata, account: metadata.account, urlBase: metadata.urlBase, onlyLocal: onlyLocal) { (errorCode, errorDescription) in
                 if errorCode != 0 {
-                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                    NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                 }
                 self.finish()
             }
@@ -221,14 +219,14 @@ class NCOperationCopyMove: ConcurrentOperation {
             if move {
                 NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
                     if errorCode != 0 {
-                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                     }
                     self.finish()
                 }
             } else {
                 NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
                     if errorCode != 0 {
-                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                        NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                     }
                     self.finish()
                 }
@@ -248,7 +246,7 @@ class NCOperationSynchronization: ConcurrentOperation {
     init(metadata: tableMetadata, selector: String) {
         self.metadata = tableMetadata.init(value: metadata)
         self.selector = selector
-        if selector == selectorDownloadFile {
+        if selector == NCBrandGlobal.shared.selectorDownloadFile || selector == NCBrandGlobal.shared.selectorDownloadAllFile {
             self.download = true
         } else {
             self.download = false
@@ -266,7 +264,7 @@ class NCOperationSynchronization: ConcurrentOperation {
 
                 NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
 
-                    if (errorCode == 0) && (directory?.etag != files.first?.etag || directory?.synchronized == false) {
+                    if (errorCode == 0) && (directory?.etag != files.first?.etag || self.selector == NCBrandGlobal.shared.selectorDownloadAllFile) {
                         
                         NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
                             
@@ -274,9 +272,9 @@ class NCOperationSynchronization: ConcurrentOperation {
                             
                                 NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in
                                     
-                                    let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
+                                    let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCBrandGlobal.shared.metadataStatusNormal))
                                     
-                                    if self.selector == selectorDownloadAllFile {
+                                    if self.selector == NCBrandGlobal.shared.selectorDownloadAllFile {
                                         
                                         NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
 
@@ -284,9 +282,8 @@ class NCOperationSynchronization: ConcurrentOperation {
                                             if metadata.directory {
                                                 NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
                                             } else {
-                                                let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                                                if localFile == nil || localFile?.etag != metadata.etag {
-                                                    NCOperationQueue.shared.download(metadata: metadata, selector: self.selector, setFavorite: false)
+                                                if NCManageDatabase.shared.isDownloadMetadata(metadata, download: true) {
+                                                    NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
                                                 }
                                             }
                                         }
@@ -302,17 +299,15 @@ class NCOperationSynchronization: ConcurrentOperation {
                                         }
                                         
                                         for metadata in metadatasChanged.metadatasLocalUpdate {
-                                            NCOperationQueue.shared.download(metadata: metadata, selector: self.selector, setFavorite: false)
+                                            NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
                                         }
                                     }
                                     
                                     // Update etag directory
                                     NCManageDatabase.shared.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, richWorkspace: metadataFolder.richWorkspace, account: metadataFolder.account)
-                                    // Update
-                                    NCManageDatabase.shared.setDirectory(synchronized: true, serverUrl: serverUrl, account: account)
                                 }
                             
-                            } else if errorCode == k_CCErrorResourceNotFound && self.metadata.directory {
+                            } else if errorCode == NCBrandGlobal.shared.ErrorResourceNotFound && self.metadata.directory {
                                 NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: self.metadata.serverUrl, account: self.metadata.account)
                             }
                             
@@ -321,12 +316,14 @@ class NCOperationSynchronization: ConcurrentOperation {
                         
                     } else {
                         
-                        let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", account, serverUrl))
+                        let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
                         for metadata in metadatas {
-                            let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-                            let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, serverUrl))
-                            if directory?.synchronized == false {
+                            if metadata.directory {
                                 NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
+                            } else {
+                                if NCManageDatabase.shared.isDownloadMetadata(metadata, download: self.download) {
+                                    NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
+                                }
                             }
                         }
                         
@@ -335,11 +332,8 @@ class NCOperationSynchronization: ConcurrentOperation {
                 }
                 
             } else {
-                if self.download {
-                    let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                    if localFile == nil || localFile?.etag != metadata.etag {
-                        NCOperationQueue.shared.download(metadata: metadata, selector: self.selector, setFavorite: false)
-                    }
+                if NCManageDatabase.shared.isDownloadMetadata(metadata, download: self.download) {
+                    NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
                 }
                 self.finish()
             }
@@ -372,7 +366,7 @@ class NCOperationDownloadThumbnail: ConcurrentOperation {
             let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
             let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
 
-            NCCommunication.shared.downloadPreview(fileNamePathOrFileId: fileNamePath, fileNamePreviewLocalPath: fileNamePreviewLocalPath , widthPreview: CGFloat(k_sizePreview), heightPreview: CGFloat(k_sizePreview), fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: CGFloat(k_sizeIcon)) { (account, imagePreview, imageIcon,  errorCode, errorDescription) in
+            NCCommunication.shared.downloadPreview(fileNamePathOrFileId: fileNamePath, fileNamePreviewLocalPath: fileNamePreviewLocalPath , widthPreview: NCBrandGlobal.shared.sizePreview, heightPreview: NCBrandGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCBrandGlobal.shared.sizeIcon) { (account, imagePreview, imageIcon,  errorCode, errorDescription) in
                 
                 var cell: NCImageCellProtocol?
                 

+ 24 - 26
iOSClient/Networking/NCService.swift

@@ -57,7 +57,7 @@ class NCService: NSObject {
                 
                     // Update User (+ userProfile.id) & active account & account network
                     guard let tableAccount = NCManageDatabase.shared.setAccountUserProfile(userProfile!) else {
-                        NCContentPresenter.shared.messageNotification("Account", description: "Internal error : account not found on DB",  delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
+                        NCContentPresenter.shared.messageNotification("Account", description: "Internal error : account not found on DB",  delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                         return
                     }
                 
@@ -67,12 +67,8 @@ class NCService: NSObject {
                     
                     self.appDelegate.settingAccount(tableAccount.account, urlBase: tableAccount.urlBase, user: tableAccount.user, userID: tableAccount.userID, password: CCUtility.getPassword(tableAccount.account))
                        
-                    // Synchronize favorite
-                    var selector = selectorReadFile
-                    if CCUtility.getFavoriteOffline() {
-                        selector = selectorDownloadFile
-                    }
-                    NCNetworking.shared.listingFavoritescompletion(selector: selector) { (_, _, _, _) in }
+                    // Synchronize favorite                    
+                    NCNetworking.shared.listingFavoritescompletion(selector: NCBrandGlobal.shared.selectorReadFile) { (_, _, _, _) in }
                 
                     // Synchronize Offline Directory
                     if let directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", tableAccount.account), sorted: "serverUrl", ascending: true) {
@@ -80,7 +76,7 @@ class NCService: NSObject {
                             guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(directory.ocId) else {
                                 continue
                             }
-                            NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadFile)
+                            NCOperationQueue.shared.synchronizationMetadata(metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                         }
                     }
                 
@@ -90,11 +86,11 @@ class NCService: NSObject {
                         guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(file.ocId) else {
                             continue
                         }
-                        NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadFile)
+                        NCOperationQueue.shared.synchronizationMetadata(metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                     }
                              
                     // Get Avatar
-                    let avatarUrl = "\(self.appDelegate.urlBase!)/index.php/avatar/\(self.appDelegate.user!)/\(k_avatar_size)".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
+                    let avatarUrl = "\(self.appDelegate.urlBase!)/index.php/avatar/\(self.appDelegate.user!)/\(NCBrandGlobal.shared.avatarSize)".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
                     let fileNamePath = CCUtility.getDirectoryUserData() + "/" + stringUser + "-" + self.appDelegate.user + ".png"
                     NCCommunication.shared.downloadContent(serverUrl: avatarUrl) { (account, data, errorCode, errorMessage) in
                         
@@ -112,7 +108,7 @@ class NCService: NSObject {
                         }
                     }
                           
-                    NotificationCenter.default.postOnMainThread(name: k_notificationCenter_changeUserProfile)
+                    NotificationCenter.default.postOnMainThread(name: NCBrandGlobal.shared.notificationCenterChangeUserProfile)
                                         
                     self.requestServerCapabilities()
                 }
@@ -136,9 +132,9 @@ class NCService: NSObject {
                     
                     if extendedSupport == false {
                         if serverProductName == "owncloud" {
-                            NCContentPresenter.shared.messageNotification("_warning_", description: "_warning_owncloud_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_dismissAfterSecondLong))
+                            NCContentPresenter.shared.messageNotification("_warning_", description: "_warning_owncloud_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                         } else if versionMajor <=  NCBrandGlobal.shared.nextcloud_unsupported_version {
-                            NCContentPresenter.shared.messageNotification("_warning_", description: "_warning_unsupported_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_dismissAfterSecondLong))
+                            NCContentPresenter.shared.messageNotification("_warning_", description: "_warning_unsupported_", delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCBrandGlobal.shared.ErrorInternalError)
                         }
                     }
                 }
@@ -158,9 +154,15 @@ class NCService: NSObject {
                 
                     NCManageDatabase.shared.addCapabilitiesJSon(data!, account: account)
                 
+                    let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
+                    
                     // Setup communication
-                    self.appDelegate.settingSetupCommunication(account)
-                
+                    if serverVersionMajor > 0 {
+                        NCCommunicationCommon.shared.setup(nextcloudVersion: serverVersionMajor)
+                    }
+                    NCCommunicationCommon.shared.setup(webDav: NCUtilityFileSystem.shared.getWebDAV(account: account))
+                    NCCommunicationCommon.shared.setup(dav: NCUtilityFileSystem.shared.getDAV())
+                    
                     // Theming
                     NCBrandColor.shared.settingThemingColor(account: account)
                 
@@ -170,17 +172,14 @@ class NCService: NSObject {
                         NCCommunication.shared.readShares { (account, shares, errorCode, ErrorDescription) in
                             if errorCode == 0 {
                                 
-                                DispatchQueue.global().async {
-                                    
-                                    NCManageDatabase.shared.deleteTableShare(account: account)
-                                    if shares != nil {
-                                        NCManageDatabase.shared.addShare(urlBase: self.appDelegate.urlBase, account: account, shares: shares!)
-                                    }
-                                    self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: account)
+                                NCManageDatabase.shared.deleteTableShare(account: account)
+                                if shares != nil {
+                                    NCManageDatabase.shared.addShare(urlBase: self.appDelegate.urlBase, account: account, shares: shares!)
                                 }
-                                
+                                self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: account)
+                               
                             } else {
-                                NCContentPresenter.shared.messageNotification("_share_", description: ErrorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                NCContentPresenter.shared.messageNotification("_share_", description: ErrorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                             }
                         }
                     }
@@ -195,8 +194,7 @@ class NCService: NSObject {
                     }
                 
                     // Text direct editor detail
-                    let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-                    if serverVersionMajor >= k_nextcloud_version_18_0 {
+                    if serverVersionMajor >= NCBrandGlobal.shared.nextcloudVersion18 {
                         NCCommunication.shared.NCTextObtainEditorDetails() { (account, editors, creators, errorCode, errorMessage) in
                             if errorCode == 0 && account == self.appDelegate.account {
                                 

+ 2 - 2
iOSClient/Nextcloud-Bridging-Header.h

@@ -4,8 +4,8 @@
 
 #import "AppDelegate.h"
 #import "CCManageAccount.h"
-#import "CCGraphics.h"
 #import "NCAutoUpload.h"
 #import "NCEndToEndEncryption.h"
 #import "NYMnemonic.h"
-#import "CCPeekPop.h"
+#import "UIImage+animatedGIF.h"
+#import "CCUtility.h"

+ 5 - 14
iOSClient/Notification/NCNotification.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="c26-Us-IIn">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="c26-Us-IIn">
     <device id="retina4_7" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
@@ -69,7 +69,7 @@
                                                 <action selector="touchUpInsideRemove:" destination="R1c-h5-BOp" eventType="touchUpInside" id="Wlp-VM-Vf2"/>
                                             </connections>
                                         </button>
-                                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sMh-G7-FLo">
+                                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sMh-G7-FLo">
                                             <rect key="frame" x="245" y="147" width="120" height="30"/>
                                             <constraints>
                                                 <constraint firstAttribute="height" constant="30" id="n50-CF-ODl"/>
@@ -80,7 +80,7 @@
                                                 <action selector="touchUpInsidePrimary:" destination="R1c-h5-BOp" eventType="touchUpInside" id="fi2-DV-cKK"/>
                                             </connections>
                                         </button>
-                                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="obR-h7-TUC">
+                                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="obR-h7-TUC">
                                             <rect key="frame" x="115" y="147" width="120" height="30"/>
                                             <constraints>
                                                 <constraint firstAttribute="height" constant="30" id="Vko-Ob-nuj"/>
@@ -91,20 +91,12 @@
                                                 <action selector="touchUpInsideSecondary:" destination="R1c-h5-BOp" eventType="touchUpInside" id="Vy9-uI-sth"/>
                                             </connections>
                                         </button>
-                                        <imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="j3P-Mn-NRk" userLabel="avatar" customClass="NCAvatar" customModule="Nextcloud" customModuleProvider="target">
+                                        <imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="j3P-Mn-NRk" userLabel="avatar" customClass="NCAvatar" customModule="Nextcloud" customModuleProvider="target">
                                             <rect key="frame" x="10" y="40" width="25" height="25"/>
                                             <constraints>
                                                 <constraint firstAttribute="width" constant="25" id="Lzx-AE-IwQ"/>
                                                 <constraint firstAttribute="height" constant="25" id="t3A-Qm-8VW"/>
                                             </constraints>
-                                            <userDefinedRuntimeAttributes>
-                                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
-                                                    <integer key="value" value="1"/>
-                                                </userDefinedRuntimeAttribute>
-                                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
-                                                    <color key="value" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                                </userDefinedRuntimeAttribute>
-                                            </userDefinedRuntimeAttributes>
                                         </imageView>
                                     </subviews>
                                     <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -161,7 +153,6 @@
         </scene>
     </scenes>
     <resources>
-        <image name="avatar" width="25" height="25"/>
         <image name="exit" width="300" height="300"/>
     </resources>
 </document>

+ 7 - 7
iOSClient/Notification/NCNotification.swift

@@ -44,7 +44,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
         // Empty
         emptyDataSet = NCEmptyDataSet.init(view: tableView, offset: 0, delegate: self)
         
-        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCBrandGlobal.shared.notificationCenterChangeTheming), object: nil)
         
         changeTheming()
     }
@@ -73,7 +73,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
     
     func emptyDataSetView(_ view: NCEmptyView) {
         
-        view.emptyImage.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "notification"), width: 300, height: 300, color: .gray)
+        view.emptyImage.image = UIImage.init(named: "notification")?.image(color: .gray, size: UIScreen.main.bounds.width)
         view.emptyTitle.text = NSLocalizedString("_no_notification_", comment: "")
         view.emptyDescription.text = ""
     }
@@ -104,9 +104,9 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
         }
         
         if let image = image {
-            cell.icon.image = CCGraphics.changeThemingColorImage(image, multiplier: 2, color: NCBrandColor.shared.brandElement)
+            cell.icon.image = image.image(color:  NCBrandColor.shared.brandElement, size: 25)
         } else {
-            cell.icon.image = CCGraphics.changeThemingColorImage(#imageLiteral(resourceName: "notification"), multiplier:2, color: NCBrandColor.shared.brandElement)
+            cell.icon.image = #imageLiteral(resourceName: "notification").image(color: NCBrandColor.shared.brandElement, size: 25)
         }
         
         // Avatar
@@ -158,7 +158,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
         cell.message.text = notification.message.replacingOccurrences(of: "<br />", with: "\n")
         cell.message.textColor = .gray
         
-        cell.remove.setImage(CCGraphics.changeThemingColorImage(UIImage(named: "exit")!, width: 40, height: 40, color: .gray), for: .normal)
+        cell.remove.setImage(UIImage(named: "exit")!.image(color: .gray, size: 20), for: .normal)
         
         cell.primary.isEnabled = false
         cell.primary.isHidden = true
@@ -243,7 +243,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
                 self.reloadDatasource()
                 
             } else if errorCode != 0 {
-                NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
             } else {
                 print("[LOG] It has been changed user during networking process, error.")
             }
@@ -270,7 +270,7 @@ class NCNotification: UITableViewController, NCNotificationCellDelegate, NCEmpty
                                 self.reloadDatasource()
                                 
                             } else if errorCode != 0 {
-                                NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCBrandGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
                             } else {
                                 print("[LOG] It has been changed user during networking process, error.")
                             }

+ 4 - 5
iOSClient/Offline/NCOffline.swift

@@ -31,9 +31,9 @@ class NCOffline: NCCollectionViewCommon  {
         
         appDelegate.activeOffline = self
         titleCurrentFolder = NSLocalizedString("_manage_file_offline_", comment: "")
-        layoutKey = k_layout_view_offline
+        layoutKey = NCBrandGlobal.shared.layoutViewOffline
         enableSearchBar = true
-        emptyImage = CCGraphics.changeThemingColorImage(UIImage.init(named: "folder"), width: 300, height: 300, color: NCBrandColor.shared.brandElement)
+        emptyImage = UIImage.init(named: "folder")?.image(color: NCBrandColor.shared.brandElement, size: UIScreen.main.bounds.width)
         emptyTitle = "_files_no_files_"
         emptyDescription = "_tutorial_offline_view_"
     }
@@ -100,9 +100,8 @@ class NCOffline: NCCollectionViewCommon  {
                 if errorCode == 0 {
                     for metadata in metadatas ?? [] {
                         if !metadata.directory {
-                            let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                            if localFile == nil || localFile?.etag != metadata.etag {
-                                NCOperationQueue.shared.download(metadata: metadata, selector: selectorDownloadFile, setFavorite: false)
+                            if NCManageDatabase.shared.isDownloadMetadata(metadata, download: true) {
+                                NCOperationQueue.shared.download(metadata: metadata, selector: NCBrandGlobal.shared.selectorDownloadFile)
                             }
                         }
                     }

+ 0 - 39
iOSClient/PeekPop/CCPeekPop.h

@@ -1,39 +0,0 @@
-//
-//  CCPeekPop.h
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 26/08/16.
-//  Copyright (c) 2016 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 <UIKit/UIKit.h>
-
-@class tableMetadata;
-
-@interface CCPeekPop : UIViewController
-
-@property (nonatomic, strong) tableMetadata *metadata;
-@property (nonatomic, strong) UIImage *imageFile;
-@property BOOL showShare;
-@property BOOL showOpenIn;
-@property BOOL showOpenQuickLook;
-
-@property (nonatomic, weak) IBOutlet UILabel *fileName;
-@property (nonatomic, weak) IBOutlet UIImageView *imagePreview;
-
-@end

+ 0 - 117
iOSClient/PeekPop/CCPeekPop.m

@@ -1,117 +0,0 @@
-//
-//  CCPeekPop.m
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 26/08/16.
-//  Copyright (c) 2016 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 "CCPeekPop.h"
-
-#import "AppDelegate.h"
-#import "CCGraphics.h"
-#import "NCBridgeSwift.h"
-
-@interface CCPeekPop ()
-{
-    AppDelegate *appDelegate;
-    NSInteger highLabelFileName;
-}
-@end
-
-@implementation CCPeekPop
-
-- (void)viewDidLoad
-{
-    [super viewDidLoad];
-    
-    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
-    UIImage *image = self.imageFile;
-
-    self.fileName.text = self.metadata.fileNameView;
-    self.fileName.textColor = NCBrandColor.shared.textView;
-    highLabelFileName = self.fileName.bounds.size.height + 5;
-    
-    if (self.metadata.hasPreview) {
-        
-        if ([CCUtility fileProviderStoragePreviewIconExists:self.metadata.ocId etag:self.metadata.etag]) {
-            
-            UIImage *fullImage = [UIImage imageWithContentsOfFile:[CCUtility getDirectoryProviderStorageOcId:self.metadata.ocId fileNameView:self.metadata.fileNameView]];
-            if (fullImage != nil) {
-                image = fullImage;
-            }
-            
-        } else {
-            
-            [self downloadThumbnail];
-        }
-    }
-    
-    self.view.backgroundColor = NCBrandColor.shared.backgroundForm;
-    self.imagePreview.image = [CCGraphics scaleImage:image toSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height) isAspectRation:true];
-    self.preferredContentSize = CGSizeMake(self.imagePreview.image.size.width,  self.imagePreview.image.size.height + highLabelFileName);
-}
-
-- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
-{
-    NSMutableArray *items = [NSMutableArray new];
- 
-    if (self.showOpenIn && !self.metadata.directory) {
-        UIPreviewAction *item = [UIPreviewAction actionWithTitle:NSLocalizedString(@"_open_in_", nil) style:UIPreviewActionStyleDefault handler:^(UIPreviewAction *action,  UIViewController *previewViewController) {
-            [[NCNetworkingNotificationCenter shared] downloadOpenWithMetadata:self.metadata selector:selectorOpenIn];
-        }];
-        [items addObject:item];
-    }
-    
-    if (self.showOpenQuickLook) {
-        UIPreviewAction *item = [UIPreviewAction actionWithTitle:NSLocalizedString(@"_open_quicklook_", nil) style:UIPreviewActionStyleDefault handler:^(UIPreviewAction *action,  UIViewController *previewViewController) {
-            [[NCNetworkingNotificationCenter shared] downloadOpenWithMetadata:self.metadata selector:selectorLoadFileQuickLook];
-        }];
-        [items addObject:item];
-    }
-    
-    if (self.showShare) {
-        UIPreviewAction *item = [UIPreviewAction actionWithTitle:NSLocalizedString(@"_share_", nil) style:UIPreviewActionStyleDefault handler:^(UIPreviewAction *action,  UIViewController *previewViewController) {
-            [[NCNetworkingNotificationCenter shared] openShareWithViewController:appDelegate.activeFiles metadata:self.metadata indexPage:2];
-        }];
-        [items addObject:item];
-    }
-    
-    return items;
-}
-
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ==== Download Thumbnail ====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)downloadThumbnail
-{
-    NSString *fileNamePath = [CCUtility returnFileNamePathFromFileName:self.metadata.fileName serverUrl:self.metadata.serverUrl urlBase:appDelegate.urlBase account:appDelegate.account];
-    NSString *fileNamePreviewLocalPath = [CCUtility getDirectoryProviderStoragePreviewOcId:self.metadata.ocId etag:self.metadata.etag];
-    NSString *fileNameIconLocalPath = [CCUtility getDirectoryProviderStorageIconOcId:self.metadata.ocId etag:self.metadata.etag];
-    
-    [[NCCommunication shared] downloadPreviewWithFileNamePathOrFileId:fileNamePath fileNamePreviewLocalPath:fileNamePreviewLocalPath widthPreview:k_sizePreview heightPreview:k_sizePreview fileNameIconLocalPath:fileNameIconLocalPath sizeIcon:k_sizeIcon customUserAgent:nil addCustomHeaders:nil endpointTrashbin:false useInternalEndpoint:true completionHandler:^(NSString *account, UIImage *imagePreview, UIImage *imageIcon, NSInteger errorCode,  NSString *errorDescription) {
-        
-        if (errorCode == 0 && imagePreview != nil) {
-            self.imagePreview.image = [CCGraphics scaleImage:imagePreview toSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height) isAspectRation:true];
-            self.preferredContentSize = CGSizeMake(self.imagePreview.image.size.width, self.imagePreview.image.size.height + highLabelFileName);
-        }
-    }];
-}
-
-@end

+ 0 - 58
iOSClient/PeekPop/CCPeekPop.storyboard

@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina5_9" orientation="portrait">
-        <adaptation id="fullscreen"/>
-    </device>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <scenes>
-        <!--Peek Pop-->
-        <scene sceneID="5Lc-Fr-djg">
-            <objects>
-                <viewController storyboardIdentifier="PeekPopImagePreview" id="Coy-68-IJm" customClass="CCPeekPop" sceneMemberID="viewController">
-                    <layoutGuides>
-                        <viewControllerLayoutGuide type="top" id="XUP-z1-l8k"/>
-                        <viewControllerLayoutGuide type="bottom" id="7Bs-Vb-lqH"/>
-                    </layoutGuides>
-                    <view key="view" contentMode="scaleToFill" id="jEt-cG-Pua">
-                        <rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
-                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <subviews>
-                            <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="e9H-uI-9UA" userLabel="ImagePreview">
-                                <rect key="frame" x="0.0" y="129" width="375" height="649"/>
-                            </imageView>
-                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="characterWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dhr-ST-vvT">
-                                <rect key="frame" x="5" y="49" width="365" height="75"/>
-                                <constraints>
-                                    <constraint firstAttribute="height" constant="75" id="2I2-hl-qUk"/>
-                                </constraints>
-                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                                <nil key="textColor"/>
-                                <nil key="highlightedColor"/>
-                            </label>
-                        </subviews>
-                        <constraints>
-                            <constraint firstItem="e9H-uI-9UA" firstAttribute="bottom" secondItem="7Bs-Vb-lqH" secondAttribute="top" id="8Qt-fp-Vch"/>
-                            <constraint firstItem="e9H-uI-9UA" firstAttribute="top" secondItem="Dhr-ST-vvT" secondAttribute="bottom" constant="5" id="CKM-T4-VWH"/>
-                            <constraint firstItem="Dhr-ST-vvT" firstAttribute="top" secondItem="XUP-z1-l8k" secondAttribute="bottom" constant="5" id="Hdx-ZN-efJ"/>
-                            <constraint firstItem="e9H-uI-9UA" firstAttribute="leading" secondItem="jEt-cG-Pua" secondAttribute="leading" id="Rsd-3j-a5W"/>
-                            <constraint firstAttribute="trailing" secondItem="Dhr-ST-vvT" secondAttribute="trailing" constant="5" id="Uf6-8E-ZeD"/>
-                            <constraint firstAttribute="trailing" secondItem="e9H-uI-9UA" secondAttribute="trailing" id="oOm-Av-GmM"/>
-                            <constraint firstItem="Dhr-ST-vvT" firstAttribute="leading" secondItem="jEt-cG-Pua" secondAttribute="leading" constant="5" id="pJ9-JE-AEz"/>
-                        </constraints>
-                    </view>
-                    <nil key="simulatedStatusBarMetrics"/>
-                    <connections>
-                        <outlet property="fileName" destination="Dhr-ST-vvT" id="W5d-40-MAq"/>
-                        <outlet property="imagePreview" destination="e9H-uI-9UA" id="Mut-gu-5wH"/>
-                    </connections>
-                </viewController>
-                <placeholder placeholderIdentifier="IBFirstResponder" id="Y26-DR-wTE" userLabel="First Responder" sceneMemberID="firstResponder"/>
-            </objects>
-            <point key="canvasLocation" x="562.39999999999998" y="468.4729064039409"/>
-        </scene>
-    </scenes>
-</document>

+ 41 - 0
iOSClient/PushNotification/NCPushNotification.h

@@ -0,0 +1,41 @@
+//
+//  NCPushNotification.h
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 26/12/20.
+//  Copyright © 2020 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 <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NCPushNotification : NSObject
+
++ (instancetype)shared;
+@property (nonatomic, strong) NSString *pushKitToken;
+
+- (void)pushNotification;
+- (void)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
+- (void)unsubscribingNextcloudServerPushNotification:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user withSubscribing:(BOOL)subscribing;
+- (void)removeNotificationWithNotificationId:(NSInteger)notificationId usingDecryptionKey:(NSData *)key;
+- (void)registerForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 215 - 0
iOSClient/PushNotification/NCPushNotification.m

@@ -0,0 +1,215 @@
+//
+//  NCPushNotification.m
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 26/12/20.
+//  Copyright © 2020 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 "AppDelegate.h"
+#import "NCBridgeSwift.h"
+#import "NCPushNotification.h"
+#import "NCPushNotificationEncryption.h"
+
+@interface NCPushNotification ()
+{
+    AppDelegate *appDelegate;
+}
+@end
+
+@implementation NCPushNotification
+
++ (instancetype)shared
+{
+    static NCPushNotification *pushNotification = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        pushNotification = [self new];
+        pushNotification->appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
+
+    });
+    return pushNotification;
+}
+
+- (void)pushNotification
+{
+    if (appDelegate.account == nil || appDelegate.account.length == 0 || self.pushKitToken.length == 0) { return; }
+    
+    for (tableAccount *result in [[NCManageDatabase shared] getAllAccount]) {
+        
+        NSString *token = [CCUtility getPushNotificationToken:result.account];
+        
+        if (![token isEqualToString:self.pushKitToken]) {
+            if (token != nil) {
+                // unsubscribing + subscribing
+                [self unsubscribingNextcloudServerPushNotification:result.account urlBase:result.urlBase user:result.user withSubscribing:true];
+            } else {
+                [self subscribingNextcloudServerPushNotification:result.account urlBase:result.urlBase user:result.user];
+            }
+        }
+    }
+}
+
+- (void)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
+    
+    NSString *message = [userInfo objectForKey:@"subject"];
+    if (message) {
+        NSArray *results = [[NCManageDatabase shared] getAllAccount];
+        for (tableAccount *result in results) {
+            if ([CCUtility getPushNotificationPrivateKey:result.account]) {
+                NSData *decryptionKey = [CCUtility getPushNotificationPrivateKey:result.account];
+                NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:decryptionKey];
+                if (decryptedMessage) {
+                    NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
+                    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
+                    NSInteger nid = [[json objectForKey:@"nid"] integerValue];
+                    BOOL delete = [[json objectForKey:@"delete"] boolValue];
+                    BOOL deleteAll = [[json objectForKey:@"delete-all"] boolValue];
+                    if (delete) {
+                        [[NCPushNotification shared] removeNotificationWithNotificationId:nid usingDecryptionKey:decryptionKey];
+                    } else if (deleteAll) {
+                        [[NCPushNotification shared] cleanAllNotifications];
+                    }
+                }
+            }
+        }
+    }
+    
+    completionHandler(UIBackgroundFetchResultNoData);
+}
+
+- (void)subscribingNextcloudServerPushNotification:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user
+{
+    if (appDelegate.account == nil || appDelegate.account.length == 0 || self.pushKitToken.length == 0) { return; }
+    
+    [[NCPushNotificationEncryption shared] generatePushNotificationsKeyPair:account];
+
+    NSString *pushTokenHash = [[NCEndToEndEncryption sharedManager] createSHA512:self.pushKitToken];
+    NSData *pushPublicKey = [CCUtility getPushNotificationPublicKey:account];
+    NSString *pushDevicePublicKey = [[NSString alloc] initWithData:pushPublicKey encoding:NSUTF8StringEncoding];
+    NSString *proxyServerPath = [NCBrandOptions shared].pushNotificationServerProxy;
+    
+    [[NCCommunication shared] subscribingPushNotificationWithServerUrl:urlBase account:account user:user password:[CCUtility getPassword:account] pushTokenHash:pushTokenHash devicePublicKey:pushDevicePublicKey proxyServerUrl:proxyServerPath customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSString *deviceIdentifier, NSString *signature, NSString *publicKey, NSInteger errorCode, NSString *errorDescription) {
+        if (errorCode == 0) {
+            NSString *userAgent = [NSString stringWithFormat:@"%@  (Strict VoIP)", [CCUtility getUserAgent]];
+            [[NCCommunication shared] subscribingPushProxyWithProxyServerUrl:proxyServerPath pushToken:self.pushKitToken deviceIdentifier:deviceIdentifier signature:signature publicKey:publicKey userAgent:userAgent completionHandler:^(NSInteger errorCode, NSString *errorDescription) {
+                if (errorCode == 0) {
+                    
+                    [[NCCommunicationCommon shared] writeLog:@"Subscribed to Push Notification server & proxy successfully"];
+
+                    [CCUtility setPushNotificationToken:account token:self.pushKitToken];
+                    [CCUtility setPushNotificationDeviceIdentifier:account deviceIdentifier:deviceIdentifier];
+                    [CCUtility setPushNotificationDeviceIdentifierSignature:account deviceIdentifierSignature:signature];
+                    [CCUtility setPushNotificationSubscribingPublicKey:account publicKey:publicKey];
+                }
+            }];
+        }
+    }];
+}
+
+- (void)unsubscribingNextcloudServerPushNotification:(NSString *)account urlBase:(NSString *)urlBase user:(NSString *)user withSubscribing:(BOOL)subscribing
+{
+    if (appDelegate.account == nil || appDelegate.account.length == 0) { return; }
+    
+    NSString *deviceIdentifier = [CCUtility getPushNotificationDeviceIdentifier:account];
+    NSString *signature = [CCUtility getPushNotificationDeviceIdentifierSignature:account];
+    NSString *publicKey = [CCUtility getPushNotificationSubscribingPublicKey:account];
+
+    [[NCCommunication shared] unsubscribingPushNotificationWithServerUrl:urlBase account:account user:user password:[CCUtility getPassword:account] customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) {
+        if (errorCode == 0) {
+            NSString *userAgent = [NSString stringWithFormat:@"%@  (Strict VoIP)", [CCUtility getUserAgent]];
+            NSString *proxyServerPath = [NCBrandOptions shared].pushNotificationServerProxy;
+            [[NCCommunication shared] unsubscribingPushProxyWithProxyServerUrl:proxyServerPath deviceIdentifier:deviceIdentifier signature:signature publicKey:publicKey userAgent:userAgent completionHandler:^(NSInteger errorCode, NSString *errorDescription) {
+                if (errorCode == 0) {
+                
+                    [[NCCommunicationCommon shared] writeLog:@"Unsubscribed to Push Notification server & proxy successfully."];
+                    
+                    [CCUtility setPushNotificationPublicKey:account data:nil];
+                    [CCUtility setPushNotificationSubscribingPublicKey:account publicKey:nil];
+                    [CCUtility setPushNotificationPrivateKey:account data:nil];
+                    [CCUtility setPushNotificationToken:account token:nil];
+                    [CCUtility setPushNotificationDeviceIdentifier:account deviceIdentifier:nil];
+                    [CCUtility setPushNotificationDeviceIdentifierSignature:account deviceIdentifierSignature:nil];
+                    
+                    if (self.pushKitToken != nil && subscribing) {
+                        [self subscribingNextcloudServerPushNotification:account urlBase:urlBase user:user];
+                    }
+                }
+            }];
+        }
+    }];
+}
+
+- (void)cleanAllNotifications
+{
+    [[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
+}
+
+- (void)removeNotificationWithNotificationId:(NSInteger)notificationId usingDecryptionKey:(NSData *)key
+{
+    // Check in pending notifications
+    [[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
+        for (UNNotificationRequest *notificationRequest in requests) {
+            NSString *message = [notificationRequest.content.userInfo objectForKey:@"subject"];
+            NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:key];
+            if (decryptedMessage) {
+                NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
+                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
+                NSInteger nid = [[json objectForKey:@"nid"] integerValue];
+                if (nid == notificationId) {
+                    [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[notificationRequest.identifier]];
+                }
+            }
+        }
+    }];
+    // Check in delivered notifications
+    [[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
+        for (UNNotification *notification in notifications) {
+            NSString *message = [notification.request.content.userInfo objectForKey:@"subject"];
+            NSString *decryptedMessage = [[NCPushNotificationEncryption shared] decryptPushNotification:message withDevicePrivateKey:key];
+            if (decryptedMessage) {
+                NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
+                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
+                NSInteger nid = [[json objectForKey:@"nid"] integerValue];
+                if (nid == notificationId) {
+                    [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notification.request.identifier]];
+                }
+            }
+        }
+    }];
+}
+
+- (void)registerForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
+{
+    self.pushKitToken = [self stringWithDeviceToken:deviceToken];
+    [self pushNotification];
+}
+
+- (NSString *)stringWithDeviceToken:(NSData *)deviceToken
+{
+    const char *data = [deviceToken bytes];
+    NSMutableString *token = [NSMutableString string];
+    
+    for (NSUInteger i = 0; i < [deviceToken length]; i++) {
+        [token appendFormat:@"%02.2hhX", data[i]];
+    }
+    
+    return [token copy];
+}
+
+@end

Some files were not shown because too many files changed in this diff