Эх сурвалжийг харах

Merge pull request #2196 from nextcloud/develop

Version 4.5
Marino Faggiana 2 жил өмнө
parent
commit
cc64ac49e9
100 өөрчлөгдсөн 3223 нэмэгдсэн , 720 устгасан
  1. 12 1
      .github/workflows/xcode.yml
  2. 10 1
      .swiftlint.yml
  3. 6 8
      File Provider Extension/FileProviderData.swift
  4. 5 5
      File Provider Extension/FileProviderEnumerator.swift
  5. 13 13
      File Provider Extension/FileProviderExtension+Actions.swift
  6. 19 13
      File Provider Extension/FileProviderExtension+Thumbnail.swift
  7. 11 11
      File Provider Extension/FileProviderExtension.swift
  8. 2 2
      File Provider Extension/FileProviderItem.swift
  9. 0 47
      MDM/AppConfig/specfile.xml
  10. 445 62
      Nextcloud.xcodeproj/project.pbxproj
  11. 2 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/File Provider Extension.xcscheme
  12. 1 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Nextcloud.xcscheme
  13. 97 0
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Notification Service Extension.xcscheme
  14. 2 1
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Share.xcscheme
  15. 124 0
      Nextcloud.xcodeproj/xcshareddata/xcschemes/Widget.xcscheme
  16. 5 5
      NextcloudTests/SharePermissionTest.swift
  17. 2 2
      README.md
  18. 4 4
      Share/NCShareCell.swift
  19. 2 2
      Share/NCShareExtension+DataSource.swift
  20. 3 3
      Share/NCShareExtension+Files.swift
  21. 3 4
      Share/NCShareExtension+NCDelegate.swift
  22. 18 18
      Share/NCShareExtension.swift
  23. 11 0
      Widget/Assets.xcassets/AccentColor.colorset/Contents.json
  24. 11 0
      Widget/Assets.xcassets/AppIcon.imageset/Contents.json
  25. 6 0
      Widget/Assets.xcassets/Contents.json
  26. 11 0
      Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json
  27. 12 0
      Widget/Assets.xcassets/activity.imageset/Contents.json
  28. BIN
      Widget/Assets.xcassets/activity.imageset/activity.png
  29. 12 0
      Widget/Assets.xcassets/widget.imageset/Contents.json
  30. BIN
      Widget/Assets.xcassets/widget.imageset/icons8-widgetsmith-250.png
  31. 223 0
      Widget/Dashboard/DashboardData.swift
  32. 53 0
      Widget/Dashboard/DashboardWidgetProvider.swift
  33. 182 0
      Widget/Dashboard/DashboardWidgetView.swift
  34. 169 0
      Widget/Dashboard/Intent/Base.lproj/Dashboard.intentdefinition
  35. 8 0
      Widget/Dashboard/Intent/ca.lproj/Dashboard.strings
  36. 8 0
      Widget/Dashboard/Intent/cs-CZ.lproj/Dashboard.strings
  37. 8 0
      Widget/Dashboard/Intent/da.lproj/Dashboard.strings
  38. 8 0
      Widget/Dashboard/Intent/de.lproj/Dashboard.strings
  39. 8 0
      Widget/Dashboard/Intent/en-GB.lproj/Dashboard.strings
  40. 8 0
      Widget/Dashboard/Intent/en.lproj/Dashboard.strings
  41. 8 0
      Widget/Dashboard/Intent/es-419.lproj/Dashboard.strings
  42. 8 0
      Widget/Dashboard/Intent/es-CL.lproj/Dashboard.strings
  43. 8 0
      Widget/Dashboard/Intent/es-CO.lproj/Dashboard.strings
  44. 8 0
      Widget/Dashboard/Intent/es-CR.lproj/Dashboard.strings
  45. 8 0
      Widget/Dashboard/Intent/es-DO.lproj/Dashboard.strings
  46. 8 0
      Widget/Dashboard/Intent/es-EC.lproj/Dashboard.strings
  47. 8 0
      Widget/Dashboard/Intent/es-GT.lproj/Dashboard.strings
  48. 8 0
      Widget/Dashboard/Intent/es-HN.lproj/Dashboard.strings
  49. 8 0
      Widget/Dashboard/Intent/es-MX.lproj/Dashboard.strings
  50. 8 0
      Widget/Dashboard/Intent/es-NI.lproj/Dashboard.strings
  51. 8 0
      Widget/Dashboard/Intent/es-PA.lproj/Dashboard.strings
  52. 8 0
      Widget/Dashboard/Intent/es-PE.lproj/Dashboard.strings
  53. 8 0
      Widget/Dashboard/Intent/es-PR.lproj/Dashboard.strings
  54. 8 0
      Widget/Dashboard/Intent/es-PY.lproj/Dashboard.strings
  55. 8 0
      Widget/Dashboard/Intent/es-SV.lproj/Dashboard.strings
  56. 8 0
      Widget/Dashboard/Intent/es-UY.lproj/Dashboard.strings
  57. 8 0
      Widget/Dashboard/Intent/es.lproj/Dashboard.strings
  58. 8 0
      Widget/Dashboard/Intent/eu.lproj/Dashboard.strings
  59. 8 0
      Widget/Dashboard/Intent/fr.lproj/Dashboard.strings
  60. 8 0
      Widget/Dashboard/Intent/gl.lproj/Dashboard.strings
  61. 8 0
      Widget/Dashboard/Intent/hu.lproj/Dashboard.strings
  62. 8 0
      Widget/Dashboard/Intent/is.lproj/Dashboard.strings
  63. 8 0
      Widget/Dashboard/Intent/it.lproj/Dashboard.strings
  64. 8 0
      Widget/Dashboard/Intent/ja-JP.lproj/Dashboard.strings
  65. 8 0
      Widget/Dashboard/Intent/ka-GE.lproj/Dashboard.strings
  66. 8 0
      Widget/Dashboard/Intent/ko.lproj/Dashboard.strings
  67. 8 0
      Widget/Dashboard/Intent/nb-NO.lproj/Dashboard.strings
  68. 8 0
      Widget/Dashboard/Intent/nl.lproj/Dashboard.strings
  69. 8 0
      Widget/Dashboard/Intent/pl.lproj/Dashboard.strings
  70. 8 0
      Widget/Dashboard/Intent/pt-BR.lproj/Dashboard.strings
  71. 8 0
      Widget/Dashboard/Intent/pt-PT.lproj/Dashboard.strings
  72. 8 0
      Widget/Dashboard/Intent/ru.lproj/Dashboard.strings
  73. 8 0
      Widget/Dashboard/Intent/sk-SK.lproj/Dashboard.strings
  74. 8 0
      Widget/Dashboard/Intent/sr.lproj/Dashboard.strings
  75. 8 0
      Widget/Dashboard/Intent/sv.lproj/Dashboard.strings
  76. 8 0
      Widget/Dashboard/Intent/tr.lproj/Dashboard.strings
  77. 8 0
      Widget/Dashboard/Intent/zh-Hans.lproj/Dashboard.strings
  78. 8 0
      Widget/Dashboard/Intent/zh-Hant-TW.lproj/Dashboard.strings
  79. 272 0
      Widget/Files/FilesData.swift
  80. 50 0
      Widget/Files/FilesWidgetProvider.swift
  81. 169 0
      Widget/Files/FilesWidgetView.swift
  82. 95 0
      Widget/Lockscreen/LockscreenData.swift
  83. 47 0
      Widget/Lockscreen/LockscreenWidgetProvider.swift
  84. 75 0
      Widget/Lockscreen/LockscreenWidgetView.swift
  85. 44 0
      Widget/Toolbar/ToolbarData.swift
  86. 47 0
      Widget/Toolbar/ToolbarWidgetProvider.swift
  87. 118 0
      Widget/Toolbar/ToolbarWidgetView.swift
  88. 5 0
      Widget/Widget-Brinding-header.h
  89. 93 0
      Widget/Widget.swift
  90. 42 0
      WidgetDashboardIntentHandler/IntentHandler.swift
  91. 5 0
      WidgetDashboardIntentHandler/WidgetDashboardIntentHandler-Brinding-header.h
  92. 7 6
      iOSClient/.tx/config
  93. 4 4
      iOSClient/Account Request/NCAccountRequest.swift
  94. 36 32
      iOSClient/Activity/NCActivity.swift
  95. 1 1
      iOSClient/Activity/NCActivityCommentView.swift
  96. 33 46
      iOSClient/Activity/NCActivityTableViewCell.swift
  97. 193 158
      iOSClient/AppDelegate.swift
  98. 9 21
      iOSClient/Brand/Intro/NCIntroViewController.swift
  99. 42 238
      iOSClient/Brand/NCBrand.swift
  100. 8 10
      iOSClient/Brand/NCBridgeSwift.h

+ 12 - 1
.github/workflows/xcode.yml

@@ -54,4 +54,15 @@ jobs:
       run: |
       run: |
         xcodebuild build -project $PROJECT -scheme "$SCHEME" -destination "$DESTINATION"
         xcodebuild build -project $PROJECT -scheme "$SCHEME" -destination "$DESTINATION"
       env:
       env:
-          SCHEME: Notification Service Extension
+          SCHEME: Notification Service Extension
+    - name: Build iOS Widget
+      run: |
+        xcodebuild build -project $PROJECT -scheme "$SCHEME" -destination "$DESTINATION"
+      env:
+          SCHEME: Widget
+    - name: Build iOS Widget Dashboard IntentHandler
+      run: |
+        xcodebuild build -project $PROJECT -scheme "$SCHEME" -destination "$DESTINATION"
+      env:
+          SCHEME: WidgetDashboardIntentHandler
+          

+ 10 - 1
.swiftlint.yml

@@ -41,6 +41,14 @@ excluded:
   - File Provider Extension/FileProviderExtension.swift
   - File Provider Extension/FileProviderExtension.swift
   - File Provider Extension/FileProviderUtility.swift
   - File Provider Extension/FileProviderUtility.swift
   - Notification Service Extension/NotificationService.swift
   - Notification Service Extension/NotificationService.swift
+  - Widget/Widget.swift
+  - Widget/Dashboard/DashboardData.swift
+  - Widget/Dashboard/DashboardWidgetView.swift
+  - Widget/Files/FilesData.swift
+  - Widget/Files/FilesWidgetView.swift
+  - Widget/Lockscreen/LockscreenData.swift
+  - Widget/Lockscreen/LockscreenWidgetView.swift
+  - Widget/Lockscreen/LockscreenWidgetProvider.swift
   - iOSClient/Activity/NCActivity.swift
   - iOSClient/Activity/NCActivity.swift
   - iOSClient/Activity/NCActivityTableViewCell.swift
   - iOSClient/Activity/NCActivityTableViewCell.swift
   - iOSClient/AppDelegate.swift
   - iOSClient/AppDelegate.swift
@@ -56,6 +64,7 @@ excluded:
   - iOSClient/Data/NCManageDatabase.swift
   - iOSClient/Data/NCManageDatabase.swift
   - iOSClient/Data/NCManageDatabase+Metadata.swift
   - iOSClient/Data/NCManageDatabase+Metadata.swift
   - iOSClient/Data/NCManageDatabase+Video.swift
   - iOSClient/Data/NCManageDatabase+Video.swift
+  - iOSClient/Data/NCManageDatabase+DashboardWidget.swift
   - iOSClient/Diagnostics/NCCapabilitiesViewController.swift
   - iOSClient/Diagnostics/NCCapabilitiesViewController.swift
   - iOSClient/EmptyView/NCEmptyDataSet.swift
   - iOSClient/EmptyView/NCEmptyDataSet.swift
   - iOSClient/Extensions/UIColor+Extensions.swift
   - iOSClient/Extensions/UIColor+Extensions.swift
@@ -122,6 +131,7 @@ excluded:
   - iOSClient/Utility/NCStoreReview.swift
   - iOSClient/Utility/NCStoreReview.swift
   - iOSClient/Utility/NCUtility.swift
   - iOSClient/Utility/NCUtility.swift
   - iOSClient/Utility/NCUtilityFileSystem.swift
   - iOSClient/Utility/NCUtilityFileSystem.swift
+  - iOSClient/Utility/NCUtilityGUI.swift
   - iOSClient/Viewer/NCViewer.swift
   - iOSClient/Viewer/NCViewer.swift
   - iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift
   - iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift
   - iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift
   - iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayerToolBar.swift
@@ -133,5 +143,4 @@ excluded:
   - iOSClient/Viewer/NCViewerProviderContextMenu.swift
   - iOSClient/Viewer/NCViewerProviderContextMenu.swift
   - iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift
   - iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift
 
 
-
 reporter: "xcode"
 reporter: "xcode"

+ 6 - 8
File Provider Extension/FileProviderData.swift

@@ -22,7 +22,7 @@
 //
 //
 
 
 import UIKit
 import UIKit
-import NCCommunication
+import NextcloudKit
 
 
 class fileProviderData: NSObject {
 class fileProviderData: NSObject {
     static let shared: fileProviderData = {
     static let shared: fileProviderData = {
@@ -77,11 +77,11 @@ class fileProviderData: NSObject {
 
 
         // LOG
         // LOG
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
-            NCCommunicationCommon.shared.pathLog = pathDirectoryGroup
+            NKCommon.shared.pathLog = pathDirectoryGroup
             let levelLog = CCUtility.getLogLevel()
             let levelLog = CCUtility.getLogLevel()
-            NCCommunicationCommon.shared.levelLog = levelLog
+            NKCommon.shared.levelLog = levelLog
             let version = NSString(format: NCBrandOptions.shared.textCopyrightNextcloudiOS as NSString, NCUtility.shared.getVersionApp()) as String
             let version = NSString(format: NCBrandOptions.shared.textCopyrightNextcloudiOS as NSString, NCUtility.shared.getVersionApp()) as String
-            NCCommunicationCommon.shared.writeLog("Start File Provider session with level \(levelLog) " + version + " (File Provider Extension)")
+            NKCommon.shared.writeLog("[INFO] Start File Provider session with level \(levelLog) " + version + " (File Provider Extension)")
         }
         }
 
 
         // NO DOMAIN -> Set default account
         // NO DOMAIN -> Set default account
@@ -89,7 +89,6 @@ class fileProviderData: NSObject {
 
 
             guard let activeAccount = NCManageDatabase.shared.getActiveAccount() else { return nil }
             guard let activeAccount = NCManageDatabase.shared.getActiveAccount() else { return nil }
             let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: activeAccount.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
             let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: activeAccount.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-            let webDav = NCUtilityFileSystem.shared.getWebDAV(account: activeAccount.account)
 
 
             account = activeAccount.account
             account = activeAccount.account
             user = activeAccount.user
             user = activeAccount.user
@@ -97,7 +96,7 @@ class fileProviderData: NSObject {
             accountUrlBase = activeAccount.urlBase
             accountUrlBase = activeAccount.urlBase
             homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account)
             homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account)
 
 
-            NCCommunicationCommon.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account), urlBase: activeAccount.urlBase, userAgent: CCUtility.getUserAgent(), webDav: webDav, nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
+            NKCommon.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account), urlBase: activeAccount.urlBase, userAgent: CCUtility.getUserAgent(), nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
             NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
             NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
 
 
             return tableAccount.init(value: activeAccount)
             return tableAccount.init(value: activeAccount)
@@ -114,7 +113,6 @@ class fileProviderData: NSObject {
             if accountDomain == domain!.identifier.rawValue {
             if accountDomain == domain!.identifier.rawValue {
 
 
                 let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: activeAccount.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
                 let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: activeAccount.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
-                let webDav = NCUtilityFileSystem.shared.getWebDAV(account: activeAccount.account)
 
 
                 account = activeAccount.account
                 account = activeAccount.account
                 user = activeAccount.user
                 user = activeAccount.user
@@ -122,7 +120,7 @@ class fileProviderData: NSObject {
                 accountUrlBase = activeAccount.urlBase
                 accountUrlBase = activeAccount.urlBase
                 homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account)
                 homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account)
 
 
-                NCCommunicationCommon.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account), urlBase: activeAccount.urlBase, userAgent: CCUtility.getUserAgent(), webDav: webDav, nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
+                NKCommon.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account), urlBase: activeAccount.urlBase, userAgent: CCUtility.getUserAgent(), nextcloudVersion: serverVersionMajor, delegate: NCNetworking.shared)
                 NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
                 NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
 
 
                 return tableAccount.init(value: activeAccount)
                 return tableAccount.init(value: activeAccount)

+ 5 - 5
File Provider Extension/FileProviderEnumerator.swift

@@ -23,7 +23,7 @@
 
 
 import UIKit
 import UIKit
 import FileProvider
 import FileProvider
-import NCCommunication
+import NextcloudKit
 
 
 class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
 class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
 
 
@@ -203,15 +203,15 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
             directoryEtag = tableDirectory.etag
             directoryEtag = tableDirectory.etag
         }
         }
 
 
-        NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, errorCode, _ in
+        NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, error in
 
 
             if directoryEtag != files.first?.etag {
             if directoryEtag != files.first?.etag {
 
 
-                NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, errorCode, _ in
+                NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, error in
 
 
-                    if errorCode == 0 {
+                    if error == .success {
                         DispatchQueue.global().async {
                         DispatchQueue.global().async {
-                            NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { _, metadatasFolder, metadatas in
+                            NCManageDatabase.shared.convertNKFilesToMetadatas(files, useMetadataFolder: true, account: account) { _, metadatasFolder, metadatas in
                                 let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCGlobal.shared.metadataStatusNormal))
                                 let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCGlobal.shared.metadataStatusNormal))
                                 NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
                                 NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
                                 for metadata in metadatasFolder {
                                 for metadata in metadatasFolder {

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

@@ -23,7 +23,7 @@
 
 
 import UIKit
 import UIKit
 import FileProvider
 import FileProvider
-import NCCommunication
+import NextcloudKit
 
 
 extension FileProviderExtension {
 extension FileProviderExtension {
 
 
@@ -37,13 +37,13 @@ extension FileProviderExtension {
         let directoryName = NCUtilityFileSystem.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
         let serverUrlFileName = tableDirectory.serverUrl + "/" + directoryName
 
 
-        NCCommunication.shared.createFolder(serverUrlFileName) { account, ocId, _, errorCode, _ in
+        NextcloudKit.shared.createFolder(serverUrlFileName) { account, ocId, _, error in
 
 
-            if errorCode == 0 {
+            if error == .success {
 
 
-                NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, errorCode, _ in
+                NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { account, files, _, error in
 
 
-                    if errorCode == 0 && files.count > 0 {
+                    if error == .success && files.count > 0 {
 
 
                         let file = files.first!
                         let file = files.first!
                         let metadata = NCManageDatabase.shared.convertNCFileToMetadata(file, isEncrypted: false, account: fileProviderData.shared.account)
                         let metadata = NCManageDatabase.shared.convertNCFileToMetadata(file, isEncrypted: false, account: fileProviderData.shared.account)
@@ -88,9 +88,9 @@ extension FileProviderExtension {
         let serverUrl = metadata.serverUrl
         let serverUrl = metadata.serverUrl
         let fileName = metadata.fileName
         let fileName = metadata.fileName
 
 
-        NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { account, errorCode, _ in
+        NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName) { account, error in
 
 
-            if errorCode == 0 { // || error == kOCErrorServerPathNotFound {
+            if error == .success { // || error == kOCErrorServerPathNotFound {
 
 
                 let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)!
                 let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)!
                 do {
                 do {
@@ -138,9 +138,9 @@ extension FileProviderExtension {
         let serverUrlTo = tableDirectoryTo.serverUrl
         let serverUrlTo = tableDirectoryTo.serverUrl
         let fileNameTo = serverUrlTo + "/" + itemFrom.filename
         let fileNameTo = serverUrlTo + "/" + itemFrom.filename
 
 
-        NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: false) { account, errorCode, _ in
+        NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: false) { account, error in
 
 
-            if errorCode == 0 {
+            if error == .success {
 
 
                 if metadataFrom.directory {
                 if metadataFrom.directory {
                     NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account)
                     NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account)
@@ -180,9 +180,9 @@ extension FileProviderExtension {
         let fileNamePathTo = metadata.serverUrl + "/" + itemName
         let fileNamePathTo = metadata.serverUrl + "/" + itemName
         let ocId = metadata.ocId
         let ocId = metadata.ocId
 
 
-        NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false) { account, errorCode, _ in
+        NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false) { account, error in
 
 
-            if errorCode == 0 {
+            if error == .success {
 
 
                 // Rename metadata
                 // Rename metadata
                 NCManageDatabase.shared.renameMetadata(fileNameTo: itemName, ocId: ocId)
                 NCManageDatabase.shared.renameMetadata(fileNameTo: itemName, ocId: ocId)
@@ -247,9 +247,9 @@ extension FileProviderExtension {
         if (favorite == true && metadata.favorite == false) || (favorite == false && metadata.favorite == true) {
         if (favorite == true && metadata.favorite == false) || (favorite == false && metadata.favorite == true) {
             let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
             let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
 
 
-            NCCommunication.shared.setFavorite(fileName: fileNamePath, favorite: favorite) { _, errorCode, _ in
+            NextcloudKit.shared.setFavorite(fileName: fileNamePath, favorite: favorite) { _, error in
 
 
-                if errorCode == 0 {
+                if error == .success {
 
 
                     guard let metadataTemp = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
                     guard let metadataTemp = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
                         completionHandler(nil, NSFileProviderError(.noSuchItem))
                         completionHandler(nil, NSFileProviderError(.noSuchItem))

+ 19 - 13
File Provider Extension/FileProviderExtension+Thumbnail.swift

@@ -23,7 +23,7 @@
 
 
 import UIKit
 import UIKit
 import FileProvider
 import FileProvider
-import NCCommunication
+import NextcloudKit
 
 
 extension FileProviderExtension {
 extension FileProviderExtension {
 
 
@@ -45,20 +45,26 @@ extension FileProviderExtension {
                 let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
                 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)!
                 let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
 
 
-                NCCommunication.shared.getPreview(fileNamePath: fileNamePath, widthPreview: NCGlobal.shared.sizeIcon, heightPreview: NCGlobal.shared.sizeIcon) { _, data, errorCode, _ in
-                    if errorCode == 0 && data != nil {
-                        do {
-                            try data!.write(to: URL(fileURLWithPath: fileNameIconLocalPath), options: .atomic)
-                        } catch { }
-                        perThumbnailCompletionHandler(itemIdentifier, data, nil)
-                    } else {
-                        perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.serverUnreachable))
-                    }
-                    counterProgress += 1
-                    if counterProgress == progress.totalUnitCount {
-                        completionHandler(nil)
+                if let urlBase = metadata.urlBase.urlEncoded,
+                   let fileNamePath = fileNamePath.urlEncoded,
+                   let url = URL(string: "\(urlBase)/index.php/core/preview.png?file=\(fileNamePath)&x=\(size)&y=\(size)&a=1&mode=cover") {
+
+                    NextcloudKit.shared.getPreview(url: url) { _, data, error in
+                        if error == .success && data != nil {
+                            do {
+                                try data!.write(to: URL(fileURLWithPath: fileNameIconLocalPath), options: .atomic)
+                            } catch { }
+                            perThumbnailCompletionHandler(itemIdentifier, data, nil)
+                        } else {
+                            perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.serverUnreachable))
+                        }
+                        counterProgress += 1
+                        if counterProgress == progress.totalUnitCount {
+                            completionHandler(nil)
+                        }
                     }
                     }
                 }
                 }
+
             } else {
             } else {
                 counterProgress += 1
                 counterProgress += 1
                 if counterProgress == progress.totalUnitCount {
                 if counterProgress == progress.totalUnitCount {

+ 11 - 11
File Provider Extension/FileProviderExtension.swift

@@ -23,7 +23,7 @@
 
 
 import UIKit
 import UIKit
 import FileProvider
 import FileProvider
-import NCCommunication
+import NextcloudKit
 import Alamofire
 import Alamofire
 
 
 /* -----------------------------------------------------------------------------------------------------------------------------------------------
 /* -----------------------------------------------------------------------------------------------------------------------------------------------
@@ -119,7 +119,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             metadata.fileName = "root"
             metadata.fileName = "root"
             metadata.fileNameView = "root"
             metadata.fileNameView = "root"
             metadata.serverUrl = fileProviderData.shared.homeServerUrl
             metadata.serverUrl = fileProviderData.shared.homeServerUrl
-            metadata.classFile = NCCommunicationCommon.typeClassFile.directory.rawValue
+            metadata.classFile = NKCommon.typeClassFile.directory.rawValue
 
 
             return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue))
             return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue))
 
 
@@ -209,7 +209,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusDownloading)
         NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusDownloading)
         fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, update: true)
         fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, update: true)
 
 
-        NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { _ in
+        NextcloudKit.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { _ in
 
 
         }, taskHandler: { task in
         }, taskHandler: { task in
 
 
@@ -218,7 +218,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
 
 
         }, progressHandler: { _ in
         }, progressHandler: { _ in
 
 
-        }) { _, etag, date, _, _, _, errorCode, errorDescription in
+        }) { _, etag, date, _, _, _, error in
 
 
             self.outstandingSessionTasks.removeValue(forKey: url)
             self.outstandingSessionTasks.removeValue(forKey: url)
             guard var metadata = fileProviderUtility.shared.getTableMetadataFromItemIdentifier(identifier) else {
             guard var metadata = fileProviderUtility.shared.getTableMetadataFromItemIdentifier(identifier) else {
@@ -227,7 +227,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             }
             }
             metadata = tableMetadata.init(value: metadata)
             metadata = tableMetadata.init(value: metadata)
 
 
-            if errorCode == 0 {
+            if error == .success {
 
 
                 metadata.status = NCGlobal.shared.metadataStatusNormal
                 metadata.status = NCGlobal.shared.metadataStatusNormal
                 metadata.date = date ?? NSDate()
                 metadata.date = date ?? NSDate()
@@ -238,7 +238,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
 
 
                 completionHandler(nil)
                 completionHandler(nil)
 
 
-            } else if errorCode == 200 {
+            } else if error.errorCode == 200 {
 
 
                 NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusNormal)
                 NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusNormal)
 
 
@@ -247,7 +247,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
             } else {
             } else {
 
 
                 metadata.status = NCGlobal.shared.metadataStatusDownloadError
                 metadata.status = NCGlobal.shared.metadataStatusDownloadError
-                metadata.sessionError = errorDescription
+                metadata.sessionError = error.errorDescription
                 NCManageDatabase.shared.addMetadata(metadata)
                 NCManageDatabase.shared.addMetadata(metadata)
 
 
                 completionHandler(NSFileProviderError(.noSuchItem))
                 completionHandler(NSFileProviderError(.noSuchItem))
@@ -277,7 +277,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         let serverUrlFileName = metadata.serverUrl + "/" + fileName
         let serverUrlFileName = metadata.serverUrl + "/" + fileName
         let fileNameLocalPath = url.path
         let fileNameLocalPath = url.path
 
 
-        if let task = NCCommunicationBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, description: metadata.ocId, session: NCNetworking.shared.sessionManagerBackgroundExtension) {
+        if let task = NKBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, description: metadata.ocId, session: NCNetworking.shared.sessionManagerBackgroundExtension) {
 
 
             fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(metadata.fileId)) { _ in }
             fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(metadata.fileId)) { _ in }
         }
         }
@@ -357,7 +357,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
                 let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName
                 let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName
                 let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)!
                 let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)!
 
 
-                if let task = NCCommunicationBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, description: ocIdTemp, session: NCNetworking.shared.sessionManagerBackgroundExtension) {
+                if let task = NKBackground.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, description: ocIdTemp, session: NCNetworking.shared.sessionManagerBackgroundExtension) {
 
 
                     self.outstandingSessionTasks[URL(fileURLWithPath: fileNameLocalPath)] = task as URLSessionTask
                     self.outstandingSessionTasks[URL(fileURLWithPath: fileNameLocalPath)] = task as URLSessionTask
 
 
@@ -371,7 +371,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         }
         }
     }
     }
 
 
-    func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String) {
+    func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, description: String?, task: URLSessionTask, error: NKError) {
 
 
         guard let ocIdTemp = description else { return }
         guard let ocIdTemp = description else { return }
         guard let metadataTemp = NCManageDatabase.shared.getMetadataFromOcId(ocIdTemp) else { return }
         guard let metadataTemp = NCManageDatabase.shared.getMetadataFromOcId(ocIdTemp) else { return }
@@ -383,7 +383,7 @@ class FileProviderExtension: NSFileProviderExtension, NCNetworkingDelegate {
         }
         }
         outstandingOcIdTemp[ocIdTemp] = ocId
         outstandingOcIdTemp[ocIdTemp] = ocId
 
 
-        if errorCode == 0 {
+        if error == .success {
 
 
             // New file
             // New file
             if ocId != ocIdTemp {
             if ocId != ocIdTemp {

+ 2 - 2
File Provider Extension/FileProviderItem.swift

@@ -23,7 +23,7 @@
 
 
 import UIKit
 import UIKit
 import FileProvider
 import FileProvider
-import NCCommunication
+import NextcloudKit
 
 
 class FileProviderItem: NSObject, NSFileProviderItem {
 class FileProviderItem: NSObject, NSFileProviderItem {
 
 
@@ -43,7 +43,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     }
     }
 
 
     var typeIdentifier: String {
     var typeIdentifier: String {
-        let results = NCCommunicationCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: "", directory: metadata.directory)
+        let results = NKCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: "", directory: metadata.directory)
         return results.typeIdentifier
         return results.typeIdentifier
     }
     }
 
 

+ 0 - 47
MDM/AppConfig/specfile.xml

@@ -1,47 +0,0 @@
-<managedAppConfiguration>
-	<version>1.0.0</version>
-	<bundleId>it.twsweb.Nextcloud</bundleId>
-	<dict>
-		<string keyName="serverUrl">
-			<defaultValue>
-				<value>https:&#x2F;&#x2F;cloud.nextcloud.com</value>
-			</defaultValue>
-		</string>
-		<string keyName="username">
-			<defaultValue>
-				<value>marino.faggiana</value>
-			</defaultValue>
-		</string>
-		<string keyName="password">
-			<defaultValue>
-				<value>password</value>
-			</defaultValue>
-		</string>
-	</dict>
-	<presentation defaultLocale="en-US">
-		<field keyName="serverUrl" type="input">
-			<label>
-				<language value="en-US">serverUrl</language>
-			</label>
-			<description>
-				<language value="en-US">Nextcloud server url</language>
-			</description>
-		</field>
-		<field keyName="username" type="input">
-			<label>
-				<language value="en-US">username</language>
-			</label>
-			<description>
-				<language value="en-US">User Name</language>
-			</description>
-		</field>
-		<field keyName="password" type="input">
-			<label>
-				<language value="en-US">password</language>
-			</label>
-			<description>
-				<language value="en-US">Password</language>
-			</description>
-		</field>
-	</presentation>
-</managedAppConfiguration>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 445 - 62
Nextcloud.xcodeproj/project.pbxproj


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

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <Scheme
-   LastUpgradeVersion = "1330"
+   LastUpgradeVersion = "1400"
    wasCreatedForAppExtension = "YES"
    wasCreatedForAppExtension = "YES"
    version = "2.0">
    version = "2.0">
    <BuildAction
    <BuildAction
@@ -93,6 +93,7 @@
       savedToolIdentifier = ""
       savedToolIdentifier = ""
       useCustomWorkingDirectory = "NO"
       useCustomWorkingDirectory = "NO"
       debugDocumentVersioning = "YES"
       debugDocumentVersioning = "YES"
+      askForAppToLaunch = "Yes"
       launchAutomaticallySubstyle = "2">
       launchAutomaticallySubstyle = "2">
       <BuildableProductRunnable
       <BuildableProductRunnable
          runnableDebuggingMode = "0">
          runnableDebuggingMode = "0">

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

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

+ 97 - 0
Nextcloud.xcodeproj/xcshareddata/xcschemes/Notification Service Extension.xcscheme

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1400"
+   wasCreatedForAppExtension = "YES"
+   version = "2.0">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "2C33C47E23E2C475005F963B"
+               BuildableName = "Notification Service Extension.appex"
+               BlueprintName = "Notification Service Extension"
+               ReferencedContainer = "container:Nextcloud.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+               BuildableName = "Nextcloud.app"
+               BlueprintName = "Nextcloud"
+               ReferencedContainer = "container:Nextcloud.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = ""
+      selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
+      launchStyle = "0"
+      askForAppToLaunch = "Yes"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES"
+      launchAutomaticallySubstyle = "2">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+            BuildableName = "Nextcloud.app"
+            BlueprintName = "Nextcloud"
+            ReferencedContainer = "container:Nextcloud.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES"
+      askForAppToLaunch = "Yes"
+      launchAutomaticallySubstyle = "2">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+            BuildableName = "Nextcloud.app"
+            BlueprintName = "Nextcloud"
+            ReferencedContainer = "container:Nextcloud.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

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

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
 <Scheme
-   LastUpgradeVersion = "1330"
+   LastUpgradeVersion = "1400"
    wasCreatedForAppExtension = "YES"
    wasCreatedForAppExtension = "YES"
    version = "2.0">
    version = "2.0">
    <BuildAction
    <BuildAction
@@ -97,6 +97,7 @@
       savedToolIdentifier = ""
       savedToolIdentifier = ""
       useCustomWorkingDirectory = "NO"
       useCustomWorkingDirectory = "NO"
       debugDocumentVersioning = "YES"
       debugDocumentVersioning = "YES"
+      askForAppToLaunch = "Yes"
       launchAutomaticallySubstyle = "2">
       launchAutomaticallySubstyle = "2">
       <BuildableProductRunnable
       <BuildableProductRunnable
          runnableDebuggingMode = "0">
          runnableDebuggingMode = "0">

+ 124 - 0
Nextcloud.xcodeproj/xcshareddata/xcschemes/Widget.xcscheme

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1400"
+   wasCreatedForAppExtension = "YES"
+   version = "2.0">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "F7346E0F28B0EF5B006CE2D2"
+               BuildableName = "Widget.appex"
+               BlueprintName = "Widget"
+               ReferencedContainer = "container:Nextcloud.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+               BuildableName = "Nextcloud.app"
+               BlueprintName = "Nextcloud"
+               ReferencedContainer = "container:Nextcloud.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = ""
+      selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
+      launchStyle = "0"
+      askForAppToLaunch = "Yes"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES"
+      launchAutomaticallySubstyle = "2">
+      <RemoteRunnable
+         runnableDebuggingMode = "2"
+         BundleIdentifier = "com.apple.springboard">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "F7346E0F28B0EF5B006CE2D2"
+            BuildableName = "Widget.appex"
+            BlueprintName = "Widget"
+            ReferencedContainer = "container:Nextcloud.xcodeproj">
+         </BuildableReference>
+      </RemoteRunnable>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+            BuildableName = "Nextcloud.app"
+            BlueprintName = "Nextcloud"
+            ReferencedContainer = "container:Nextcloud.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <EnvironmentVariables>
+         <EnvironmentVariable
+            key = "_XCWidgetKind"
+            value = ""
+            isEnabled = "YES">
+         </EnvironmentVariable>
+         <EnvironmentVariable
+            key = "_XCWidgetDefaultView"
+            value = "timeline"
+            isEnabled = "YES">
+         </EnvironmentVariable>
+         <EnvironmentVariable
+            key = "_XCWidgetFamily"
+            value = "medium"
+            isEnabled = "YES">
+         </EnvironmentVariable>
+      </EnvironmentVariables>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES"
+      askForAppToLaunch = "Yes"
+      launchAutomaticallySubstyle = "2">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
+            BuildableName = "Nextcloud.app"
+            BlueprintName = "Nextcloud"
+            ReferencedContainer = "container:Nextcloud.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 5 - 5
NextcloudTests/SharePermissionTest.swift

@@ -23,7 +23,7 @@
 
 
 @testable import Nextcloud
 @testable import Nextcloud
 import XCTest
 import XCTest
-import NCCommunication
+import NextcloudKit
 
 
 class SharePermissionTest: XCTestCase {
 class SharePermissionTest: XCTestCase {
     override func setUp() {
     override func setUp() {
@@ -35,7 +35,7 @@ class SharePermissionTest: XCTestCase {
     }
     }
 
 
     func testShareCellPermissionCell() throws {
     func testShareCellPermissionCell() throws {
-        let share = NCTableShareOptions(sharee: NCCommunicationSharee(), metadata: tableMetadata(), password: nil)
+        let share = NCTableShareOptions(sharee: NKSharee(), metadata: tableMetadata(), password: nil)
         let shareConfig = NCShareConfig(parentMetadata: tableMetadata(), share: share)
         let shareConfig = NCShareConfig(parentMetadata: tableMetadata(), share: share)
 
 
         for row in 0..<shareConfig.permissions.count {
         for row in 0..<shareConfig.permissions.count {
@@ -48,7 +48,7 @@ class SharePermissionTest: XCTestCase {
 
 
         let meta = tableMetadata()
         let meta = tableMetadata()
         meta.sharePermissionsCollaborationServices = 31
         meta.sharePermissionsCollaborationServices = 31
-        let fullShare = NCTableShareOptions(sharee: NCCommunicationSharee(), metadata: meta, password: nil)
+        let fullShare = NCTableShareOptions(sharee: NKSharee(), metadata: meta, password: nil)
         let shareFullConfig = NCShareConfig(parentMetadata: meta, share: fullShare)
         let shareFullConfig = NCShareConfig(parentMetadata: meta, share: fullShare)
 
 
         for row in 0..<shareFullConfig.permissions.count {
         for row in 0..<shareFullConfig.permissions.count {
@@ -102,7 +102,7 @@ class SharePermissionTest: XCTestCase {
     func testUserShare() throws {
     func testUserShare() throws {
         let meta = tableMetadata()
         let meta = tableMetadata()
         meta.directory = false
         meta.directory = false
-        let sharee = NCCommunicationSharee()
+        let sharee = NKSharee()
         let share = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil)
         let share = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil)
         let fileConfig = NCShareConfig(parentMetadata: meta, share: share)
         let fileConfig = NCShareConfig(parentMetadata: meta, share: share)
         XCTAssertEqual(fileConfig.advanced, NCShareDetails.forUser)
         XCTAssertEqual(fileConfig.advanced, NCShareDetails.forUser)
@@ -126,7 +126,7 @@ class SharePermissionTest: XCTestCase {
         XCTAssertEqual(fileConfig.permissions as? [NCLinkPermission], NCLinkPermission.forFile)
         XCTAssertEqual(fileConfig.permissions as? [NCLinkPermission], NCLinkPermission.forFile)
 
 
         meta.directory = true
         meta.directory = true
-        let sharee = NCCommunicationSharee()
+        let sharee = NKSharee()
         let folderShare = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil)
         let folderShare = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil)
         let folderConfig = NCShareConfig(parentMetadata: meta, share: folderShare)
         let folderConfig = NCShareConfig(parentMetadata: meta, share: folderShare)
         XCTAssertEqual(folderConfig.resharePermission, meta.sharePermissionsCollaborationServices)
         XCTAssertEqual(folderConfig.resharePermission, meta.sharePermissionsCollaborationServices)

+ 2 - 2
README.md

@@ -2,7 +2,7 @@
 [![Releases](https://img.shields.io/github/release/nextcloud/ios.svg)](https://github.com/nextcloud/ios/releases/latest) [![Build](https://github.com/nextcloud/ios/actions/workflows/xcode.yml/badge.svg)](https://github.com/nextcloud/ios/actions/workflows/xcode.yml) [![SwiftLint](https://github.com/nextcloud/ios/actions/workflows/lint.yml/badge.svg)](https://github.com/nextcloud/ios/actions/workflows/lint.yml)
 [![Releases](https://img.shields.io/github/release/nextcloud/ios.svg)](https://github.com/nextcloud/ios/releases/latest) [![Build](https://github.com/nextcloud/ios/actions/workflows/xcode.yml/badge.svg)](https://github.com/nextcloud/ios/actions/workflows/xcode.yml) [![SwiftLint](https://github.com/nextcloud/ios/actions/workflows/lint.yml/badge.svg)](https://github.com/nextcloud/ios/actions/workflows/lint.yml)
 [![irc](https://img.shields.io/badge/IRC-%23nextcloud--mobile%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-mobile)
 [![irc](https://img.shields.io/badge/IRC-%23nextcloud--mobile%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-mobile)
 
 
-<img src="Animation.gif" alt="Demo of the Nextcloud iOS files app" width="277" height="600">
+<img src="Animation.gif" alt="Demo of the Nextcloud iOS files app" width="277" height="600"><img src="widget.png" alt="Widget of the Nextcloud iOS files app" width="277" height="600">
 
 
 [<img src="https://developer.apple.com/assets/elements/badges/download-on-the-app-store.svg"
 [<img src="https://developer.apple.com/assets/elements/badges/download-on-the-app-store.svg"
 alt="Demo of the Nextcloud iOS files app"
 alt="Demo of the Nextcloud iOS files app"
@@ -38,7 +38,7 @@ branch. Maybe start working on [starter issues](https://github.com/nextcloud/ios
 
 
 Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/ios/pulls)
 Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/ios/pulls)
 
 
-### Xcode 13.4 Project Setup
+### Xcode 14 Project Setup
 
 
 #### Dependencies
 #### Dependencies
 
 

+ 4 - 4
Share/NCShareCell.swift

@@ -22,7 +22,7 @@
 //
 //
 
 
 import UIKit
 import UIKit
-import NCCommunication
+import NextcloudKit
 
 
 protocol NCShareCellDelegate: AnyObject {
 protocol NCShareCellDelegate: AnyObject {
     var uploadStarted: Bool { get }
     var uploadStarted: Bool { get }
@@ -40,9 +40,9 @@ class NCShareCell: UITableViewCell {
 
 
     func setup(fileName: String) {
     func setup(fileName: String) {
         self.fileName = fileName
         self.fileName = fileName
-        let resultInternalType = NCCommunicationCommon.shared.getInternalType(fileName: fileName, mimeType: "", directory: false)
+        let resultInternalType = NKCommon.shared.getInternalType(fileName: fileName, mimeType: "", directory: false)
 
 
-        backgroundColor = NCBrandColor.shared.systemBackground
+        backgroundColor = .systemBackground
         imageCell?.layer.cornerRadius = 6
         imageCell?.layer.cornerRadius = 6
         imageCell?.layer.masksToBounds = true
         imageCell?.layer.masksToBounds = true
 
 
@@ -61,7 +61,7 @@ class NCShareCell: UITableViewCell {
         let fileSize = NCUtilityFileSystem.shared.getFileSize(filePath: (NSTemporaryDirectory() + fileName))
         let fileSize = NCUtilityFileSystem.shared.getFileSize(filePath: (NSTemporaryDirectory() + fileName))
         sizeCell?.text = CCUtility.transformedSize(fileSize)
         sizeCell?.text = CCUtility.transformedSize(fileSize)
 
 
-        moreButton?.setImage(NCUtility.shared.loadImage(named: "more").image(color: NCBrandColor.shared.label, size: 15), for: .normal)
+        moreButton?.setImage(NCUtility.shared.loadImage(named: "more").image(color: .label, size: 15), for: .normal)
     }
     }
 
 
     @IBAction func buttonTapped(_ sender: Any) {
     @IBAction func buttonTapped(_ sender: Any) {

+ 2 - 2
Share/NCShareExtension+DataSource.swift

@@ -22,7 +22,7 @@
 //
 //
 
 
 import UIKit
 import UIKit
-import NCCommunication
+import NextcloudKit
 
 
 // MARK: - Collection View (target folder)
 // MARK: - Collection View (target folder)
 
 
@@ -67,7 +67,7 @@ extension NCShareExtension: UICollectionViewDataSource {
         cell.fileObjectId = metadata.ocId
         cell.fileObjectId = metadata.ocId
         cell.fileUser = metadata.ownerId
         cell.fileUser = metadata.ownerId
         cell.labelTitle.text = metadata.fileNameView
         cell.labelTitle.text = metadata.fileNameView
-        cell.labelTitle.textColor = NCBrandColor.shared.label
+        cell.labelTitle.textColor = .label
 
 
         cell.imageSelect.image = nil
         cell.imageSelect.image = nil
         cell.imageStatus.image = nil
         cell.imageStatus.image = nil

+ 3 - 3
Share/NCShareExtension+Files.swift

@@ -73,11 +73,11 @@ extension NCShareExtension {
         networkInProgress = true
         networkInProgress = true
         collectionView.reloadData()
         collectionView.reloadData()
 
 
-        NCNetworking.shared.readFolder(serverUrl: serverUrl, account: activeAccount.account) { _, metadataFolder, _, _, _, _, errorCode, errorDescription in
+        NCNetworking.shared.readFolder(serverUrl: serverUrl, account: activeAccount.account) { _, metadataFolder, _, _, _, _, error in
 
 
             DispatchQueue.main.async {
             DispatchQueue.main.async {
-                if errorCode != 0 {
-                    self.showAlert(description: errorDescription)
+                if error != .success {
+                    self.showAlert(description: error.errorDescription)
                 }
                 }
                 self.networkInProgress = false
                 self.networkInProgress = false
                 self.metadataFolder = metadataFolder
                 self.metadataFolder = metadataFolder

+ 3 - 4
Share/NCShareExtension+NCDelegate.swift

@@ -21,7 +21,7 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 //
 
 
-import NCCommunication
+import NextcloudKit
 import UIKit
 import UIKit
 
 
 extension NCShareExtension: NCEmptyDataSetDelegate, NCAccountRequestDelegate {
 extension NCShareExtension: NCEmptyDataSetDelegate, NCAccountRequestDelegate {
@@ -81,14 +81,13 @@ extension NCShareExtension: NCEmptyDataSetDelegate, NCAccountRequestDelegate {
         NCBrandColor.shared.createUserColors()
         NCBrandColor.shared.createUserColors()
 
 
         // NETWORKING
         // NETWORKING
-        NCCommunicationCommon.shared.setup(
+        NKCommon.shared.setup(
             account: activeAccount.account,
             account: activeAccount.account,
             user: activeAccount.user,
             user: activeAccount.user,
             userId: activeAccount.userId,
             userId: activeAccount.userId,
             password: CCUtility.getPassword(activeAccount.account),
             password: CCUtility.getPassword(activeAccount.account),
             urlBase: activeAccount.urlBase,
             urlBase: activeAccount.urlBase,
             userAgent: CCUtility.getUserAgent(),
             userAgent: CCUtility.getUserAgent(),
-            webDav: NCUtilityFileSystem.shared.getWebDAV(account: activeAccount.account),
             nextcloudVersion: 0,
             nextcloudVersion: 0,
             delegate: NCNetworking.shared)
             delegate: NCNetworking.shared)
 
 
@@ -122,7 +121,7 @@ extension NCShareExtension: NCShareCellDelegate, NCRenameFileDelegate, NCListCel
     func renameFile(named fileName: String) {
     func renameFile(named fileName: String) {
         guard let vcRename = UIStoryboard(name: "NCRenameFile", bundle: nil).instantiateInitialViewController() as? NCRenameFile else { return }
         guard let vcRename = UIStoryboard(name: "NCRenameFile", bundle: nil).instantiateInitialViewController() as? NCRenameFile else { return }
 
 
-        let resultInternalType = NCCommunicationCommon.shared.getInternalType(fileName: fileName, mimeType: "", directory: false)
+        let resultInternalType = NKCommon.shared.getInternalType(fileName: fileName, mimeType: "", directory: false)
         vcRename.delegate = self
         vcRename.delegate = self
         vcRename.fileName = fileName
         vcRename.fileName = fileName
         if let previewImage = UIImage.downsample(imageAt: URL(fileURLWithPath: NSTemporaryDirectory() + fileName), to: CGSize(width: 140, height: 140)) {
         if let previewImage = UIImage.downsample(imageAt: URL(fileURLWithPath: NSTemporaryDirectory() + fileName), to: CGSize(width: 140, height: 140)) {

+ 18 - 18
Share/NCShareExtension.swift

@@ -24,7 +24,7 @@
 //
 //
 
 
 import UIKit
 import UIKit
-import NCCommunication
+import NextcloudKit
 import JGProgressHUD
 import JGProgressHUD
 
 
 enum NCShareExtensionError: Error {
 enum NCShareExtensionError: Error {
@@ -85,27 +85,27 @@ class NCShareExtension: UIViewController {
 
 
         collectionView.addSubview(refreshControl)
         collectionView.addSubview(refreshControl)
         refreshControl.tintColor = NCBrandColor.shared.brandText
         refreshControl.tintColor = NCBrandColor.shared.brandText
-        refreshControl.backgroundColor = NCBrandColor.shared.systemBackground
+        refreshControl.backgroundColor = .systemBackground
         refreshControl.addTarget(self, action: #selector(reloadDatasource), for: .valueChanged)
         refreshControl.addTarget(self, action: #selector(reloadDatasource), for: .valueChanged)
 
 
-        commandView.backgroundColor = NCBrandColor.shared.secondarySystemBackground
-        separatorView.backgroundColor = NCBrandColor.shared.separator
+        commandView.backgroundColor = .secondarySystemBackground
+        separatorView.backgroundColor = .separator
         separatorHeightConstraint.constant = 0.5
         separatorHeightConstraint.constant = 0.5
 
 
-        tableView.separatorColor = NCBrandColor.shared.separator
+        tableView.separatorColor = .separator
         tableView.layer.cornerRadius = 10
         tableView.layer.cornerRadius = 10
         tableView.tableFooterView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 0, height: 1)))
         tableView.tableFooterView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 0, height: 1)))
         commandViewHeightConstraint.constant = heightCommandView
         commandViewHeightConstraint.constant = heightCommandView
 
 
         createFolderView.layer.cornerRadius = 10
         createFolderView.layer.cornerRadius = 10
-        createFolderImage.image = NCUtility.shared.loadImage(named: "folder.badge.plus", color: NCBrandColor.shared.label)
+        createFolderImage.image = NCUtility.shared.loadImage(named: "folder.badge.plus", color: .label)
         createFolderLabel.text = NSLocalizedString("_create_folder_", comment: "")
         createFolderLabel.text = NSLocalizedString("_create_folder_", comment: "")
         let createFolderGesture = UITapGestureRecognizer(target: self, action: #selector(actionCreateFolder))
         let createFolderGesture = UITapGestureRecognizer(target: self, action: #selector(actionCreateFolder))
         createFolderView.addGestureRecognizer(createFolderGesture)
         createFolderView.addGestureRecognizer(createFolderGesture)
 
 
         uploadView.layer.cornerRadius = 10
         uploadView.layer.cornerRadius = 10
 
 
-        // uploadImage.image = NCUtility.shared.loadImage(named: "square.and.arrow.up", color: NCBrandColor.shared.label)
+        // uploadImage.image = NCUtility.shared.loadImage(named: "square.and.arrow.up", color: .label)
         uploadLabel.text = NSLocalizedString("_upload_", comment: "")
         uploadLabel.text = NSLocalizedString("_upload_", comment: "")
         uploadLabel.textColor = .systemBlue
         uploadLabel.textColor = .systemBlue
         let uploadGesture = UITapGestureRecognizer(target: self, action: #selector(actionUpload))
         let uploadGesture = UITapGestureRecognizer(target: self, action: #selector(actionUpload))
@@ -116,14 +116,14 @@ class NCShareExtension: UIViewController {
         let isSimulatorOrTestFlight = NCUtility.shared.isSimulatorOrTestFlight()
         let isSimulatorOrTestFlight = NCUtility.shared.isSimulatorOrTestFlight()
         let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
         let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
 
 
-        NCCommunicationCommon.shared.levelLog = levelLog
+        NKCommon.shared.levelLog = levelLog
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
-            NCCommunicationCommon.shared.pathLog = pathDirectoryGroup
+            NKCommon.shared.pathLog = pathDirectoryGroup
         }
         }
         if isSimulatorOrTestFlight {
         if isSimulatorOrTestFlight {
-            NCCommunicationCommon.shared.writeLog("Start Share session with level \(levelLog) " + versionNextcloudiOS + " (Simulator / TestFlight)")
+            NKCommon.shared.writeLog("[INFO] Start Share session with level \(levelLog) " + versionNextcloudiOS + " (Simulator / TestFlight)")
         } else {
         } else {
-            NCCommunicationCommon.shared.writeLog("Start Share session with level \(levelLog) " + versionNextcloudiOS)
+            NKCommon.shared.writeLog("[INFO] Start Share session with level \(levelLog) " + versionNextcloudiOS)
         }
         }
 
 
         // Colors
         // Colors
@@ -283,9 +283,9 @@ class NCShareExtension: UIViewController {
     }
     }
 
 
     @objc func actionCreateFolder() {
     @objc func actionCreateFolder() {
-        let alertController = UIAlertController.createFolder(serverUrl: serverUrl, urlBase: activeAccount) { errorCode, errorDescription in
-            guard errorCode != 0 else { return }
-            self.showAlert(title: "_error_createsubfolders_upload_", description: errorDescription)
+        let alertController = UIAlertController.createFolder(serverUrl: serverUrl, urlBase: activeAccount) { error in
+            guard error != .success else { return }
+            self.showAlert(title: "_error_createsubfolders_upload_", description: error.errorDescription)
         }
         }
         self.present(alertController, animated: true)
         self.present(alertController, animated: true)
     }
     }
@@ -312,7 +312,7 @@ extension NCShareExtension {
                 ocId: ocId,
                 ocId: ocId,
                 serverUrl: serverUrl, urlBase: activeAccount.urlBase, url: "",
                 serverUrl: serverUrl, urlBase: activeAccount.urlBase, url: "",
                 contentType: "")
                 contentType: "")
-            metadata.session = NCCommunicationCommon.shared.sessionIdentifierUpload
+            metadata.session = NKCommon.shared.sessionIdentifierUpload
             metadata.sessionSelector = NCGlobal.shared.selectorUploadFileShareExtension
             metadata.sessionSelector = NCGlobal.shared.selectorUploadFileShareExtension
             metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: toPath)
             metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: toPath)
             metadata.status = NCGlobal.shared.metadataStatusWaitUpload
             metadata.status = NCGlobal.shared.metadataStatusWaitUpload
@@ -339,7 +339,7 @@ extension NCShareExtension {
         guard uploadStarted else { return }
         guard uploadStarted else { return }
         guard uploadMetadata.count > counterUploaded else { return finishedUploading() }
         guard uploadMetadata.count > counterUploaded else { return finishedUploading() }
         let metadata = uploadMetadata[counterUploaded]
         let metadata = uploadMetadata[counterUploaded]
-        let results = NCCommunicationCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false)
+        let results = NKCommon.shared.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false)
         metadata.contentType = results.mimeType
         metadata.contentType = results.mimeType
         metadata.iconName = results.iconName
         metadata.iconName = results.iconName
         metadata.classFile = results.classFile
         metadata.classFile = results.classFile
@@ -352,8 +352,8 @@ extension NCShareExtension {
         hud.progress = 0
         hud.progress = 0
         hud.show(in: self.view)
         hud.show(in: self.view)
 
 
-        NCNetworking.shared.upload(metadata: metadata) { } completion: { errorCode, _ in
-            if errorCode != 0 {
+        NCNetworking.shared.upload(metadata: metadata) { } completion: { error in
+            if error != .success {
                 let path = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)!
                 let path = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)!
                 NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
                 NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
                 NCManageDatabase.shared.deleteChunks(account: metadata.account, ocId: metadata.ocId)
                 NCManageDatabase.shared.deleteChunks(account: metadata.account, ocId: metadata.ocId)

+ 11 - 0
Widget/Assets.xcassets/AccentColor.colorset/Contents.json

@@ -0,0 +1,11 @@
+{
+  "colors" : [
+    {
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 11 - 0
Widget/Assets.xcassets/AppIcon.imageset/Contents.json

@@ -0,0 +1,11 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
Widget/Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 11 - 0
Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json

@@ -0,0 +1,11 @@
+{
+  "colors" : [
+    {
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 12 - 0
Widget/Assets.xcassets/activity.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "filename" : "activity.png",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
Widget/Assets.xcassets/activity.imageset/activity.png


+ 12 - 0
Widget/Assets.xcassets/widget.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "filename" : "icons8-widgetsmith-250.png",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
Widget/Assets.xcassets/widget.imageset/icons8-widgetsmith-250.png


+ 223 - 0
Widget/Dashboard/DashboardData.swift

@@ -0,0 +1,223 @@
+//
+//  DashboardData.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 20/08/22.
+//  Copyright © 2022 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 WidgetKit
+import NextcloudKit
+import RealmSwift
+import SVGKit
+
+struct DashboardDataEntry: TimelineEntry {
+    let date: Date
+    let datas: [DashboardData]
+    let dashboard: tableDashboardWidget?
+    let buttons: [tableDashboardWidgetButton]?
+    let isPlaceholder: Bool
+    let titleImage: UIImage
+    let title: String
+    let footerImage: String
+    let footerText: String
+}
+
+struct DashboardData: Identifiable, Hashable {
+    let id: Int
+    let title: String
+    let subTitle: String
+    let link: URL
+    let icon: UIImage
+    let template: Bool
+    let avatar: Bool
+}
+
+struct DashboardDataButton: Hashable {
+    let type: String
+    let Text: String
+    let link: String
+}
+
+let dashboardDatasTest: [DashboardData] = [
+    .init(id: 0, title: "title0", subTitle: "subTitle-description0", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 1, title: "title1", subTitle: "subTitle-description1", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 2, title: "title2", subTitle: "subTitle-description2", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 3, title: "title3", subTitle: "subTitle-description3", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 4, title: "title4", subTitle: "subTitle-description4", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 5, title: "title5", subTitle: "subTitle-description5", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 6, title: "title6", subTitle: "subTitle-description6", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 7, title: "title7", subTitle: "subTitle-description7", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 8, title: "title8", subTitle: "subTitle-description8", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false),
+    .init(id: 9, title: "title9", subTitle: "subTitle-description9", link: URL(string: "https://nextcloud.com/")!, icon: UIImage(named: "widget")!, template: true, avatar: false)
+]
+
+func getDashboardItems(displaySize: CGSize, withButton: Bool) -> Int {
+    
+    if withButton {
+        let height = Int((displaySize.height - 85) / 50)
+        return height
+    } else {
+        let height = Int((displaySize.height - 60) / 50)
+        return height
+    }
+}
+
+func getDashboardDataEntry(intent: Applications?, isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: DashboardDataEntry) -> Void) {
+
+    let dashboardItems = getDashboardItems(displaySize: displaySize, withButton: false)
+    let datasPlaceholder = Array(dashboardDatasTest[0...dashboardItems - 1])
+
+    if isPreview {
+        return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " dashboard"))
+    }
+
+    guard let account = NCManageDatabase.shared.getActiveAccount() else {
+        return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", comment: "")))
+    }
+
+    // Default widget
+    let result = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account).first
+    let id: String = intent?.identifier ?? (result?.id ?? "recommendations")
+
+    let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
+    guard serverVersionMajor >= NCGlobal.shared.nextcloudVersion25 else {
+        return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_widget_available_nc25_", comment: "")))
+    }
+        
+    // NETWORKING
+    let password = CCUtility.getPassword(account.account)!
+    NKCommon.shared.setup(
+        account: account.account,
+        user: account.user,
+        userId: account.userId,
+        password: password,
+        urlBase: account.urlBase,
+        userAgent: CCUtility.getUserAgent(),
+        nextcloudVersion: 0,
+        delegate: NCNetworking.shared)
+
+    // LOG
+    let levelLog = CCUtility.getLogLevel()
+    let isSimulatorOrTestFlight = NCUtility.shared.isSimulatorOrTestFlight()
+    let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
+
+    NKCommon.shared.levelLog = levelLog
+    if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
+        NKCommon.shared.pathLog = pathDirectoryGroup
+    }
+    if isSimulatorOrTestFlight {
+        NKCommon.shared.writeLog("[INFO] Start \(NCBrandOptions.shared.brand) dashboard widget session with level \(levelLog) " + versionNextcloudiOS + " (Simulator / TestFlight)")
+    } else {
+        NKCommon.shared.writeLog("[INFO] Start \(NCBrandOptions.shared.brand) dashboard widget session with level \(levelLog) " + versionNextcloudiOS)
+    }
+    
+    let (tableDashboard, tableButton) = NCManageDatabase.shared.getDashboardWidget(account: account.account, id: id)
+    let existsButton = (tableButton?.isEmpty ?? true) ? false : true
+    let options = NKRequestOptions(timeout: 15, queue: NKCommon.shared.backgroundQueue)
+    let title = tableDashboard?.title ?? id
+
+    var imagetmp = UIImage(named: "widget")!
+    if let fileName = tableDashboard?.iconClass {
+        let fileNamePath: String = CCUtility.getDirectoryUserData() + "/" + fileName + ".png"
+        if let image = UIImage(contentsOfFile: fileNamePath) {
+            imagetmp = image.withTintColor(.label, renderingMode: .alwaysOriginal)
+        }
+    }
+    let titleImage = imagetmp
+        
+    NextcloudKit.shared.getDashboardWidgetsApplication(id, options: options) { account, results, data, error in
+
+        Task {
+            var datas = [DashboardData]()
+            var numberItems = 0
+
+            if let results = results {
+                for result in results {
+                    if let items = result.items {
+                        numberItems = result.items?.count ?? 0
+                        var counter: Int = 0
+                        let dashboardItems = getDashboardItems(displaySize: displaySize, withButton: existsButton)
+                        for item in items {
+                            counter += 1
+                            let title = item.title ?? ""
+                            let subtitle = item.subtitle ?? ""
+                            var link = URL(string: "https://")!
+                            if let entryLink = item.link, let url = URL(string: entryLink) { link = url }
+                            var icon = UIImage(named: "file")!
+                            var iconFileName: String?
+                            var template: Bool = false
+                            var avatar: Bool = false
+
+                            if let iconUrl = item.iconUrl, let url = URL(string: iconUrl) {
+                                if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
+
+                                    let path = (urlComponents.path as NSString)
+                                    let pathComponents = path.components(separatedBy: "/")
+                                    let queryItems = urlComponents.queryItems
+
+                                    if (pathComponents.last as? NSString)?.pathExtension.lowercased() == "svg" {
+                                        template = true
+                                    }
+
+                                    if let item = CCUtility.value(forKey: "fileId", fromQueryItems: queryItems) {
+                                        iconFileName = item
+                                    } else if pathComponents.contains("avatar") {
+                                        iconFileName = pathComponents[pathComponents.count-2]
+                                        avatar = true
+                                    } else {
+                                        iconFileName = ((path.lastPathComponent) as NSString).deletingPathExtension
+                                    }
+                                }
+                                if let fileName = iconFileName {
+                                    let fileNamePath: String = CCUtility.getDirectoryUserData() + "/" + fileName + ".png"
+                                    if FileManager().fileExists(atPath: fileNamePath), let image = UIImage(contentsOfFile: fileNamePath) {
+                                        icon = image
+                                    } else {
+                                        let (_, data, _) = await NCNetworking.shared.getPreview(url: url)
+                                        if let image = NCUtility.shared.convertDataToImage(data: data, size: CGSize(width: 256, height: 256), fileNameToWrite: fileName) {
+                                            icon = image
+                                        }
+                                    }
+                                }
+                            }
+
+                            let data = DashboardData(id: counter, title: title, subTitle: subtitle, link: link, icon: icon, template: template, avatar: avatar)
+                            datas.append(data)
+
+                            if datas.count == dashboardItems { break }
+                        }
+                    }
+                }
+            }
+
+            var buttons = tableButton
+            if numberItems == datas.count, let tableButton = tableButton, tableButton.contains(where: { $0.type == "more"}) {
+                buttons = tableButton.filter(({ $0.type != "more" }))
+            }
+
+            if error != .success {
+                completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: tableDashboard, buttons: buttons, isPlaceholder: true, titleImage: titleImage, title: title, footerImage: "xmark.icloud", footerText: error.errorDescription))
+            } else if datas.isEmpty {
+                completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: tableDashboard, buttons: buttons, isPlaceholder: true, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: NSLocalizedString("_no_data_available_", comment: "")))
+            } else {
+                completion(DashboardDataEntry(date: Date(), datas: datas, dashboard: tableDashboard, buttons: buttons, isPlaceholder: false, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " dashboard"))
+            }
+        }
+    }
+}

+ 53 - 0
Widget/Dashboard/DashboardWidgetProvider.swift

@@ -0,0 +1,53 @@
+//
+//  DashboardWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 WidgetKit
+import SwiftUI
+import Intents
+
+struct DashboardWidgetProvider: IntentTimelineProvider {
+
+    typealias Intent = DashboardIntent
+    typealias Entry = DashboardDataEntry
+
+    func placeholder(in context: Context) -> Entry {
+        let dashboardItems = getDashboardItems(displaySize: context.displaySize, withButton: false)
+        let datasPlaceholder = Array(dashboardDatasTest[0...dashboardItems])
+        let title = "Dashboard"
+        let titleImage = UIImage(named: "widget")!
+        return Entry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " widget")
+    }
+
+    func getSnapshot(for configuration: DashboardIntent, in context: Context, completion: @escaping (DashboardDataEntry) -> Void) {
+        getDashboardDataEntry(intent: configuration.Applications, isPreview: false, displaySize: context.displaySize) { entry in
+            completion(entry)
+        }
+    }
+
+    func getTimeline(for configuration: DashboardIntent, in context: Context, completion: @escaping (Timeline<DashboardDataEntry>) -> Void) {
+        getDashboardDataEntry(intent: configuration.Applications, isPreview: context.isPreview, displaySize: context.displaySize) { entry in
+            let timeLine = Timeline(entries: [entry], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 182 - 0
Widget/Dashboard/DashboardWidgetView.swift

@@ -0,0 +1,182 @@
+//
+//  DashboardWidgetView.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 20/08/22.
+//  Copyright © 2022 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 SwiftUI
+import WidgetKit
+
+struct DashboardWidgetView: View {
+
+    var entry: DashboardDataEntry
+    
+    var body: some View {
+        
+        GeometryReader { geo in
+
+            ZStack(alignment: .topLeading) {
+
+                HStack() {
+                    
+                    Image(uiImage: entry.titleImage)
+                        .renderingMode(.template)
+                        .resizable()
+                        .scaledToFill()
+                        .frame(width: 20, height: 20)
+                    
+                    Text(entry.title)
+                        .font(.system(size: 15))
+                        .fontWeight(.bold)
+                        .multilineTextAlignment(.center)
+                        .textCase(.uppercase)
+                        .lineLimit(1)
+                }
+                .frame(width: geo.size.width - 20)
+                .padding([.top, .leading, .trailing], 10)
+                
+                VStack(alignment: .leading) {
+                    
+                    VStack(spacing: 0) {
+                                                
+                        ForEach(entry.datas, id: \.id) { element in
+                            
+                            Link(destination: element.link) {
+                                
+                                HStack {
+                                    
+                                    let subTitleColor = Color(white: 0.5)
+
+                                    if entry.isPlaceholder {
+                                        Circle()
+                                            .fill(Color(.systemGray4))
+                                            .frame(width: 35, height: 35)
+                                    } else if element.template {
+                                        if entry.dashboard?.itemIconsRound ?? false {
+                                            Image(uiImage: element.icon)
+                                                .renderingMode(.template)
+                                                .resizable()
+                                                .scaledToFill()
+                                                .frame(width: 20, height: 20)
+                                                .foregroundColor(.white)
+                                                .padding(8
+                                                )
+                                                .background(Color(.systemGray4))
+                                                .clipShape(Circle())
+                                        } else {
+                                            Image(uiImage: element.icon)
+                                                .renderingMode(.template)
+                                                .resizable()
+                                                .scaledToFill()
+                                                .frame(width: 25, height: 25)
+                                                .clipped()
+                                                .cornerRadius(5)
+                                        }
+                                    } else {
+                                        if entry.dashboard?.itemIconsRound ?? false || element.avatar {
+                                            Image(uiImage: element.icon)
+                                                .resizable()
+                                                .scaledToFill()
+                                                .frame(width: 35, height: 35)
+                                                .clipShape(Circle())
+                                        } else {
+                                            Image(uiImage: element.icon)
+                                                .resizable()
+                                                .scaledToFill()
+                                                .frame(width: 35, height: 35)
+                                                .clipped()
+                                                .cornerRadius(5)
+                                        }
+                                    }
+
+                                    VStack(alignment: .leading, spacing: 2) {
+
+                                        Text(element.title)
+                                            .font(.system(size: 12))
+                                            .fontWeight(.regular)
+
+                                        Text(element.subTitle)
+                                            .font(.system(size: CGFloat(10)))
+                                            .foregroundColor(subTitleColor)
+                                    }
+                                    Spacer()
+                                }
+                                .padding(.leading, 10)
+                                .frame(height: 50)
+                            }
+                            Divider()
+                                .padding(.leading, 54)
+                        }
+                    }
+                }
+                .padding(.top, 35)
+                .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+
+                if let buttons = entry.buttons, !buttons.isEmpty, !entry.isPlaceholder {
+
+                    HStack(spacing: 10) {
+
+                        let brandColor = Color(NCBrandColor.shared.brand)
+                        let brandTextColor = Color(NCBrandColor.shared.brandText)
+
+                        ForEach(buttons, id: \.index) { element in
+                            Link(destination: URL(string: element.link)! , label: {
+                                
+                                Text(element.text)
+                                    .font(.system(size: 15))
+                                    .padding(7)
+                                    .background(brandColor)
+                                    .foregroundColor(brandTextColor)
+                                    .border(brandColor, width: 1)
+                                    .cornerRadius(16)
+                            })
+                        }
+                    }
+                    .frame(width: geo.size.width - 10, height: geo.size.height - 25, alignment: .bottomTrailing)
+                }
+                
+                HStack {
+
+                    Image(systemName: entry.footerImage)
+                        .resizable()
+                        .scaledToFit()
+                        .frame(width: 15, height: 15)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+
+                    Text(entry.footerText)
+                        .font(.caption2)
+                        .padding(.trailing, 13.0)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                }
+                .frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
+            }
+        }
+    }
+}
+
+struct DashboardWidget_Previews: PreviewProvider {
+    static var previews: some View {
+        let datas = Array(dashboardDatasTest[0...4])
+        let title = "Dashboard"
+        let titleImage = UIImage(named: "widget")!
+        let entry = DashboardDataEntry(date: Date(), datas: datas, dashboard: nil, buttons: nil, isPlaceholder: false, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: "Nextcloud widget")
+        DashboardWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
+    }
+}

+ 169 - 0
Widget/Dashboard/Intent/Base.lproj/Dashboard.intentdefinition

@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>INEnums</key>
+	<array/>
+	<key>INIntentDefinitionModelVersion</key>
+	<string>1.2</string>
+	<key>INIntentDefinitionNamespace</key>
+	<string>88xZPY</string>
+	<key>INIntentDefinitionSystemVersion</key>
+	<string>21G115</string>
+	<key>INIntentDefinitionToolsBuildVersion</key>
+	<string>14A309</string>
+	<key>INIntentDefinitionToolsVersion</key>
+	<string>14.0</string>
+	<key>INIntents</key>
+	<array>
+		<dict>
+			<key>INIntentCategory</key>
+			<string>information</string>
+			<key>INIntentDescription</key>
+			<string>Dashboard Widget</string>
+			<key>INIntentDescriptionID</key>
+			<string>tVvJ9c</string>
+			<key>INIntentEligibleForWidgets</key>
+			<true/>
+			<key>INIntentIneligibleForSuggestions</key>
+			<true/>
+			<key>INIntentLastParameterTag</key>
+			<integer>7</integer>
+			<key>INIntentName</key>
+			<string>Dashboard</string>
+			<key>INIntentParameters</key>
+			<array>
+				<dict>
+					<key>INIntentParameterConfigurable</key>
+					<true/>
+					<key>INIntentParameterDisplayName</key>
+					<string>Widget</string>
+					<key>INIntentParameterDisplayNameID</key>
+					<string>TRaTZg</string>
+					<key>INIntentParameterDisplayPriority</key>
+					<integer>1</integer>
+					<key>INIntentParameterName</key>
+					<string>Applications</string>
+					<key>INIntentParameterObjectType</key>
+					<string>Applications</string>
+					<key>INIntentParameterObjectTypeNamespace</key>
+					<string>88xZPY</string>
+					<key>INIntentParameterPromptDialogs</key>
+					<array>
+						<dict>
+							<key>INIntentParameterPromptDialogCustom</key>
+							<true/>
+							<key>INIntentParameterPromptDialogType</key>
+							<string>Configuration</string>
+						</dict>
+						<dict>
+							<key>INIntentParameterPromptDialogCustom</key>
+							<true/>
+							<key>INIntentParameterPromptDialogType</key>
+							<string>Primary</string>
+						</dict>
+					</array>
+					<key>INIntentParameterSupportsDynamicEnumeration</key>
+					<true/>
+					<key>INIntentParameterTag</key>
+					<integer>7</integer>
+					<key>INIntentParameterType</key>
+					<string>Object</string>
+				</dict>
+			</array>
+			<key>INIntentResponse</key>
+			<dict>
+				<key>INIntentResponseCodes</key>
+				<array>
+					<dict>
+						<key>INIntentResponseCodeName</key>
+						<string>success</string>
+						<key>INIntentResponseCodeSuccess</key>
+						<true/>
+					</dict>
+					<dict>
+						<key>INIntentResponseCodeName</key>
+						<string>failure</string>
+					</dict>
+				</array>
+				<key>INIntentResponseLastParameterTag</key>
+				<integer>1</integer>
+			</dict>
+			<key>INIntentTitle</key>
+			<string>Dashboard</string>
+			<key>INIntentTitleID</key>
+			<string>gpCwrM</string>
+			<key>INIntentType</key>
+			<string>Custom</string>
+			<key>INIntentVerb</key>
+			<string>View</string>
+		</dict>
+	</array>
+	<key>INTypes</key>
+	<array>
+		<dict>
+			<key>INTypeDisplayName</key>
+			<string>Applications</string>
+			<key>INTypeDisplayNameID</key>
+			<string>l090JH</string>
+			<key>INTypeLastPropertyTag</key>
+			<integer>99</integer>
+			<key>INTypeName</key>
+			<string>Applications</string>
+			<key>INTypeProperties</key>
+			<array>
+				<dict>
+					<key>INTypePropertyDefault</key>
+					<true/>
+					<key>INTypePropertyDisplayPriority</key>
+					<integer>1</integer>
+					<key>INTypePropertyName</key>
+					<string>identifier</string>
+					<key>INTypePropertyTag</key>
+					<integer>1</integer>
+					<key>INTypePropertyType</key>
+					<string>String</string>
+				</dict>
+				<dict>
+					<key>INTypePropertyDefault</key>
+					<true/>
+					<key>INTypePropertyDisplayPriority</key>
+					<integer>2</integer>
+					<key>INTypePropertyName</key>
+					<string>displayString</string>
+					<key>INTypePropertyTag</key>
+					<integer>2</integer>
+					<key>INTypePropertyType</key>
+					<string>String</string>
+				</dict>
+				<dict>
+					<key>INTypePropertyDefault</key>
+					<true/>
+					<key>INTypePropertyDisplayPriority</key>
+					<integer>3</integer>
+					<key>INTypePropertyName</key>
+					<string>pronunciationHint</string>
+					<key>INTypePropertyTag</key>
+					<integer>3</integer>
+					<key>INTypePropertyType</key>
+					<string>String</string>
+				</dict>
+				<dict>
+					<key>INTypePropertyDefault</key>
+					<true/>
+					<key>INTypePropertyDisplayPriority</key>
+					<integer>4</integer>
+					<key>INTypePropertyName</key>
+					<string>alternativeSpeakableMatches</string>
+					<key>INTypePropertySupportsMultipleValues</key>
+					<true/>
+					<key>INTypePropertyTag</key>
+					<integer>4</integer>
+					<key>INTypePropertyType</key>
+					<string>SpeakableString</string>
+				</dict>
+			</array>
+		</dict>
+	</array>
+</dict>
+</plist>

+ 8 - 0
Widget/Dashboard/Intent/ca.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/cs-CZ.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/da.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/de.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/en-GB.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/en.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-419.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-CL.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-CO.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-CR.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-DO.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-EC.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-GT.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-HN.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-MX.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-NI.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-PA.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-PE.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-PR.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-PY.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-SV.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es-UY.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/es.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/eu.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/fr.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/gl.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/hu.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/is.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/it.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/ja-JP.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/ka-GE.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/ko.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/nb-NO.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/nl.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/pl.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/pt-BR.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/pt-PT.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/ru.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/sk-SK.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/sr.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/sv.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/tr.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/zh-Hans.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 8 - 0
Widget/Dashboard/Intent/zh-Hant-TW.lproj/Dashboard.strings

@@ -0,0 +1,8 @@
+"TRaTZg" = "Widget";
+
+"gpCwrM" = "Dashboard";
+
+"l090JH" = "Applications";
+
+"tVvJ9c" = "Dashboard Widget";
+

+ 272 - 0
Widget/Files/FilesData.swift

@@ -0,0 +1,272 @@
+//
+//  FilesData.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 WidgetKit
+import NextcloudKit
+
+struct FilesDataEntry: TimelineEntry {
+    let date: Date
+    let datas: [FilesData]
+    let isPlaceholder: Bool
+    let tile: String
+    let footerImage: String
+    let footerText: String
+}
+
+struct FilesData: Identifiable, Hashable {
+    var id: String
+    var image: UIImage
+    var title: String
+    var subTitle: String
+    var url: URL
+}
+
+let filesDatasTest: [FilesData] = [
+    .init(id: "0", image: UIImage(named: "widget")!, title: "title1", subTitle: "subTitle-description1", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "1", image: UIImage(named: "widget")!, title: "title2", subTitle: "subTitle-description2", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "2", image: UIImage(named: "widget")!, title: "title3", subTitle: "subTitle-description3", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "3", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "4", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "5", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "6", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "7", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "8", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: "9", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!)
+]
+
+func getTitleFilesWidget() -> String {
+
+    let hour = Calendar.current.component(.hour, from: Date())
+    var good = ""
+
+    switch hour {
+    case 6..<12: good = NSLocalizedString("_good_morning_", value: "Good morning", comment: "")
+    case 12: good = NSLocalizedString("_good_day_", value: "Good day", comment: "")
+    case 13..<17: good = NSLocalizedString("_good_afternoon_", value: "Good afternoon", comment: "")
+    case 17..<22: good = NSLocalizedString("_good_evening_", value: "Good evening", comment: "")
+    default: good = NSLocalizedString("_good_night_", value: "Good night", comment: "")
+    }
+
+    if let account = NCManageDatabase.shared.getActiveAccount() {
+        return good + ", " + account.displayName
+    } else {
+        return good
+    }
+}
+
+func getFilesItems(displaySize: CGSize) -> Int {
+    
+    let height = Int((displaySize.height - 100) / 50)
+    return height
+}
+
+func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: FilesDataEntry) -> Void) {
+
+    let filesItems = getFilesItems(displaySize: displaySize)
+    let datasPlaceholder = Array(filesDatasTest[0...filesItems - 1])
+    let title = getTitleFilesWidget()
+    
+    
+    if isPreview {
+        return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files"))
+    }
+
+    guard let account = NCManageDatabase.shared.getActiveAccount() else {
+        return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
+    }
+
+    @Sendable func isLive(file: NKFile, files: [NKFile]) -> Bool {
+
+        if file.ext.lowercased() != "mov" { return false }
+        if files.filter({ ($0.fileNameWithoutExt == file.fileNameWithoutExt) && ($0.ext.lowercased() == "jpg") }).first != nil {
+            return true
+        }
+        return false
+    }
+
+    // NETWORKING
+    let password = CCUtility.getPassword(account.account)!
+    NKCommon.shared.setup(
+        account: account.account,
+        user: account.user,
+        userId: account.userId,
+        password: password,
+        urlBase: account.urlBase,
+        userAgent: CCUtility.getUserAgent(),
+        nextcloudVersion: 0,
+        delegate: NCNetworking.shared)
+
+    let requestBodyRecent =
+    """
+    <?xml version=\"1.0\"?>
+    <d:searchrequest xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">
+    <d:basicsearch>
+        <d:select>
+            <d:prop>
+                <d:displayname/>
+                <d:getcontenttype/>
+                <d:resourcetype/>
+                <d:getcontentlength/>
+                <d:getlastmodified/>
+                <d:getetag/>
+                <d:quota-used-bytes/>
+                <d:quota-available-bytes/>
+                <permissions xmlns=\"http://owncloud.org/ns\"/>
+                <id xmlns=\"http://owncloud.org/ns\"/>
+                <fileid xmlns=\"http://owncloud.org/ns\"/>
+                <size xmlns=\"http://owncloud.org/ns\"/>
+                <favorite xmlns=\"http://owncloud.org/ns\"/>
+                <creation_time xmlns=\"http://nextcloud.org/ns\"/>
+                <upload_time xmlns=\"http://nextcloud.org/ns\"/>
+                <is-encrypted xmlns=\"http://nextcloud.org/ns\"/>
+                <mount-type xmlns=\"http://nextcloud.org/ns\"/>
+                <owner-id xmlns=\"http://owncloud.org/ns\"/>
+                <owner-display-name xmlns=\"http://owncloud.org/ns\"/>
+                <comments-unread xmlns=\"http://owncloud.org/ns\"/>
+                <has-preview xmlns=\"http://nextcloud.org/ns\"/>
+                <trashbin-filename xmlns=\"http://nextcloud.org/ns\"/>
+                <trashbin-original-location xmlns=\"http://nextcloud.org/ns\"/>
+                <trashbin-deletion-time xmlns=\"http://nextcloud.org/ns\"/>
+            </d:prop>
+        </d:select>
+    <d:from>
+        <d:scope>
+            <d:href>%@</d:href>
+            <d:depth>infinity</d:depth>
+        </d:scope>
+    </d:from>
+    <d:where>
+        <d:lt>
+            <d:prop>
+                <d:getlastmodified/>
+            </d:prop>
+            <d:literal>%@</d:literal>
+        </d:lt>
+    </d:where>
+    <d:orderby>
+        <d:order>
+            <d:prop>
+                <d:getlastmodified/>
+            </d:prop>
+            <d:descending/>
+        </d:order>
+    </d:orderby>
+    <d:limit>
+        <d:nresults>50</d:nresults>
+    </d:limit>
+    </d:basicsearch>
+    </d:searchrequest>
+    """
+
+    let dateFormatter = DateFormatter()
+    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
+    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
+    let lessDateString = dateFormatter.string(from: Date())
+    let requestBody = String(format: requestBodyRecent, "/files/" + account.userId, lessDateString)
+
+    // LOG
+    let levelLog = CCUtility.getLogLevel()
+    let isSimulatorOrTestFlight = NCUtility.shared.isSimulatorOrTestFlight()
+    let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
+
+    NKCommon.shared.levelLog = levelLog
+    if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
+        NKCommon.shared.pathLog = pathDirectoryGroup
+    }
+    if isSimulatorOrTestFlight {
+        NKCommon.shared.writeLog("[INFO] Start \(NCBrandOptions.shared.brand) widget session with level \(levelLog) " + versionNextcloudiOS + " (Simulator / TestFlight)")
+    } else {
+        NKCommon.shared.writeLog("[INFO] Start \(NCBrandOptions.shared.brand) widget session with level \(levelLog) " + versionNextcloudiOS)
+    }
+    
+    let options = NKRequestOptions(timeout: 15)
+    NextcloudKit.shared.searchBodyRequest(serverUrl: account.urlBase, requestBody: requestBody, showHiddenFiles: CCUtility.getShowHiddenFiles(), options: options) { _, files, data, error in
+        Task {
+            var datas: [FilesData] = []
+            var imageRecent = UIImage(named: "file")!
+
+            for file in files {
+                guard !file.directory else { continue }
+                guard !isLive(file: file, files: files) else { continue }
+
+                // SUBTITLE
+                let subTitle = CCUtility.dateDiff(file.date as Date) + " · " + CCUtility.transformedSize(file.size)
+
+                // URL: nextcloud://open-file?path=Talk/IMG_0000123.jpg&user=marinofaggiana&link=https://cloud.nextcloud.com/f/123
+                guard var path = NCUtilityFileSystem.shared.getPath(path: file.path, user: file.user, fileName: file.fileName).urlEncoded else { continue }
+                if path.first == "/" { path = String(path.dropFirst())}
+                guard let user = file.user.urlEncoded else { continue }
+                let link = file.urlBase + "/f/" + file.fileId
+                let urlString = "nextcloud://open-file?path=\(path)&user=\(user)&link=\(link)"
+                guard let url = URL(string: urlString) else { continue }
+
+                // IMAGE
+                if !file.iconName.isEmpty {
+                    imageRecent = UIImage(named: file.iconName)!
+                }
+                if let image = NCUtility.shared.createFilePreviewImage(ocId: file.ocId, etag: file.etag, fileNameView: file.fileName, classFile: file.classFile, status: 0, createPreviewMedia: false) {
+                    imageRecent = image
+                } else if file.hasPreview {
+                    let fileNamePathOrFileId = CCUtility.returnFileNamePath(fromFileName: file.fileName, serverUrl: file.serverUrl, urlBase: file.urlBase, account: account.account)!
+                    let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(file.ocId, etag: file.etag)!
+                    let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(file.ocId, etag: file.etag)!
+                    let (_, _, imageIcon, _, _, _) = await NCNetworking.shared.downloadPreview(fileNamePathOrFileId: fileNamePathOrFileId, fileNamePreviewLocalPath: fileNamePreviewLocalPath, widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon)
+                    if let image = imageIcon {
+                        imageRecent = image
+                    }
+                    /*
+                    do {
+                        let fileNamePathOrFileId = CCUtility.returnFileNamePath(fromFileName: file.fileName, serverUrl: file.serverUrl, urlBase: file.urlBase, account: account.account)!
+                        let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(file.ocId, etag: file.etag)!
+                        let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(file.ocId, etag: file.etag)!
+                        let (_, _, imageIcon, _, _) = try await NextcloudKit.shared.downloadPreview(fileNamePathOrFileId: fileNamePathOrFileId, fileNamePreviewLocalPath: fileNamePreviewLocalPath, widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon)
+                        if let image = imageIcon {
+                            imageRecent = image
+                        }
+                    } catch {
+                        print(error)
+                    }
+                    */
+                }
+
+                // DATA
+                let data = FilesData.init(id: file.ocId, image: imageRecent, title: file.fileName, subTitle: subTitle, url: url)
+                datas.append(data)
+                if datas.count == filesItems { break}
+            }
+
+            if error != .success {
+                completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "xmark.icloud", footerText: error.errorDescription))
+            } else if datas.isEmpty {
+                var footerText = NSLocalizedString("_no_data_available_", comment: "")
+                let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
+                if serverVersionMajor < NCGlobal.shared.nextcloudVersion25 {
+                    footerText = NSLocalizedString("_widget_available_nc25_", comment: "")
+                }
+                completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "checkmark.icloud", footerText: footerText))
+            } else {
+                completion(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files"))
+            }
+        }
+    }
+}

+ 50 - 0
Widget/Files/FilesWidgetProvider.swift

@@ -0,0 +1,50 @@
+//
+//  FilesWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 WidgetKit
+import SwiftUI
+
+struct FilesWidgetProvider: TimelineProvider {
+
+    typealias Entry = FilesDataEntry
+
+    func placeholder(in context: Context) -> Entry {
+        let filesItems = getFilesItems(displaySize: context.displaySize)
+        let datasPlaceholder = Array(filesDatasTest[0...filesItems - 1])
+        let title = getTitleFilesWidget()
+        return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")
+    }
+
+    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
+        getFilesDataEntry(isPreview: false, displaySize: context.displaySize) { entry in
+            completion(entry)
+        }
+    }
+
+    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
+        getFilesDataEntry(isPreview: context.isPreview, displaySize: context.displaySize) { entry in
+            let timeLine = Timeline(entries: [entry], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 169 - 0
Widget/Files/FilesWidgetView.swift

@@ -0,0 +1,169 @@
+//
+//  FilesWidgetView.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 SwiftUI
+import WidgetKit
+
+struct FilesWidgetView: View {
+    
+    var entry: FilesDataEntry
+    
+    var body: some View {
+        
+        GeometryReader { geo in
+            
+            ZStack(alignment: .topLeading) {
+                
+                HStack() {
+                    
+                    Text(entry.tile)
+                        .font(.system(size: 12))
+                        .fontWeight(.bold)
+                        .multilineTextAlignment(.center)
+                        .textCase(.uppercase)
+                        .lineLimit(1)
+                }
+                .frame(width: geo.size.width - 20)
+                .padding([.top, .leading, .trailing], 10)
+                
+                VStack(alignment: .leading) {
+                    
+                    VStack(spacing: 0) {
+                        
+                        ForEach(entry.datas, id: \.id) { element in
+                            
+                            Link(destination: element.url) {
+                                
+                                HStack {
+
+                                    Image(uiImage: element.image)
+                                        .resizable()
+                                        .scaledToFill()
+                                        .frame(width: 35, height: 35)
+                                        .clipped()
+                                        .cornerRadius(5)
+                                    
+                                    VStack(alignment: .leading, spacing: 2) {
+                                        
+                                        Text(element.title)
+                                            .font(.system(size: 12))
+                                            .fontWeight(.regular)
+                                        
+                                        Text(element.subTitle)
+                                            .font(.system(size: CGFloat(10)))
+                                            .foregroundColor(Color(.systemGray))
+                                    }
+                                    Spacer()
+                                }
+                                .padding(.leading, 10)
+                                .frame(height: 50)
+                            }
+                            Divider()
+                                .padding(.leading, 54)
+                        }
+                    }
+                }
+                .padding(.top, 30)
+                .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+
+                HStack(spacing: 0) {
+
+                    let sizeButton: CGFloat = 40
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionUploadAsset, label: {
+                        Image("addImage")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding(11)
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionScanDocument, label: {
+                        Image("scan")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding(11)
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionTextDocument, label: {
+                        Image("note.text")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding(11)
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionVoiceMemo, label: {
+                        Image("microphone")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding(11)
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+                }
+                .frame(width: geo.size.width, height: geo.size.height - 25, alignment: .bottomTrailing)
+                .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+
+                HStack {
+
+                    Image(systemName: entry.footerImage)
+                        .resizable()
+                        .scaledToFit()
+                        .frame(width: 15, height: 15)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                
+                    Text(entry.footerText)
+                        .font(.caption2)
+                        .padding(.trailing, 13.0)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                }
+                .frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
+            }
+        }
+    }
+}
+
+struct FilesWidget_Previews: PreviewProvider {
+    static var previews: some View {
+        let datas = Array(filesDatasTest[0...4])
+        let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, tile: "Good afternoon, Marino Faggiana", footerImage: "checkmark.icloud", footerText: "Nextcloud files")
+        FilesWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
+    }
+}

+ 95 - 0
Widget/Lockscreen/LockscreenData.swift

@@ -0,0 +1,95 @@
+//
+//  LockscreenData.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 13/10/22.
+//  Copyright © 2022 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 WidgetKit
+import NextcloudKit
+
+struct LockscreenData: TimelineEntry {
+    let date: Date
+    let isPlaceholder: Bool
+    let activity: String
+    let link: URL
+    let quotaRelative: Float
+    let quotaUsed: String
+    let quotaTotal: String
+}
+
+func getLockscreenDataEntry(isPreview: Bool, completion: @escaping (_ entry: LockscreenData) -> Void) {
+
+    if isPreview {
+        return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: ""))
+    }
+
+    guard let account = NCManageDatabase.shared.getActiveAccount() else {
+        return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: ""))
+    }
+
+    var quotaRelative: Float = 0
+    if account.quotaRelative > 0 {
+        quotaRelative = Float(account.quotaRelative) / 100
+    }
+    let quotaUsed: String = CCUtility.transformedSize(account.quotaUsed)
+    var quotaTotal: String = ""
+
+    switch account.quotaTotal {
+    case -1:
+        quotaTotal = ""
+    case -2:
+        quotaTotal = ""
+    case -3:
+        quotaTotal = ""
+    default:
+        quotaTotal = CCUtility.transformedSize(account.quotaTotal)
+    }
+
+    let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
+    if serverVersionMajor >= NCGlobal.shared.nextcloudVersion25 {
+
+        // NETWORKING
+        let password = CCUtility.getPassword(account.account)!
+        NKCommon.shared.setup(
+            account: account.account,
+            user: account.user,
+            userId: account.userId,
+            password: password,
+            urlBase: account.urlBase,
+            userAgent: CCUtility.getUserAgent(),
+            nextcloudVersion: 0,
+            delegate: NCNetworking.shared)
+
+        let options = NKRequestOptions(timeout: 15, queue: NKCommon.shared.backgroundQueue)
+        NextcloudKit.shared.getDashboardWidgetsApplication("activity", options: options) { _, results, _, error in
+            var activity: String = NSLocalizedString("_no_data_available_", comment: "")
+            var link = URL(string: "https://")!
+            if error == .success, let result = results?.first {
+                if let item = result.items?.first {
+                    if let title = item.title {  activity = title }
+                    if let itemLink = item.link, let url = URL(string: itemLink) { link = url }
+                }
+            }
+            completion(LockscreenData(date: Date(), isPlaceholder: false, activity: activity, link: link, quotaRelative: quotaRelative, quotaUsed: quotaUsed, quotaTotal: quotaTotal))
+        }
+    } else {
+        completion(LockscreenData(date: Date(), isPlaceholder: false, activity: NSLocalizedString("_widget_available_nc25_", comment: ""), link: URL(string: "https://")!, quotaRelative: quotaRelative, quotaUsed: quotaUsed, quotaTotal: quotaTotal))
+    }
+}

+ 47 - 0
Widget/Lockscreen/LockscreenWidgetProvider.swift

@@ -0,0 +1,47 @@
+//
+//  LockscreenWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 13/10/22.
+//  Copyright © 2022 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 WidgetKit
+import SwiftUI
+
+struct LockscreenWidgetProvider: TimelineProvider {
+
+    typealias Entry = LockscreenData
+
+    func placeholder(in context: Context) -> Entry {
+        return Entry(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "")
+    }
+
+    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
+        getLockscreenDataEntry(isPreview: false) { entry in
+            completion(entry)
+        }
+    }
+
+    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
+        getLockscreenDataEntry(isPreview: context.isPreview) { entry in
+            let timeLine = Timeline(entries: [entry], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 75 - 0
Widget/Lockscreen/LockscreenWidgetView.swift

@@ -0,0 +1,75 @@
+//
+//  LockscreenWidgetView.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 13/10/22.
+//  Copyright © 2022 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 SwiftUI
+import WidgetKit
+
+@available(iOSApplicationExtension 16.0, *)
+struct LockscreenWidgetView: View {
+
+    let entry: LockscreenData
+    @Environment(\.widgetFamily) private var family
+
+    var body: some View {
+        switch family {
+        case .accessoryCircular:
+            Gauge(
+                value: entry.quotaRelative,
+                label: { Text("  " + entry.quotaTotal + "  ") },
+                currentValueLabel: { Text(entry.quotaUsed) }
+            )
+            .gaugeStyle(.accessoryCircular)
+            .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+        case .accessoryRectangular:
+            VStack(alignment: .leading, spacing: 1) {
+                HStack(spacing: 1) {
+                    Image("activity")
+                        .renderingMode(.template)
+                        .resizable()
+                        .scaledToFill()
+                        .foregroundColor(.gray)
+                        .frame(width: 11, height: 11)
+                    Text(NSLocalizedString("_recent_activity_", comment: ""))
+                        .font(.system(size: 11))
+                        .fontWeight(.heavy)
+                        .foregroundColor(.gray)
+                }
+                Text(entry.activity)
+                    .font(.system(size: 12)).bold()
+            }
+            .widgetURL(entry.link)
+            .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+        default:
+            Text("Not implemented")
+        }
+    }
+}
+
+@available(iOSApplicationExtension 16.0, *)
+struct LockscreenWidgetView_Previews: PreviewProvider {
+    static var previews: some View {
+        let entry = LockscreenData(date: Date(), isPlaceholder: false, activity: "Alba Mayoral changed Marketing / Regional Marketing / Agenda Meetings / Q4 2022 / OCTOBER / 13.11 Afrah Kahlid.md", link: URL(string: "https://")!, quotaRelative: 0.5, quotaUsed: "22 GB", quotaTotal: "50 GB")
+        LockscreenWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .accessoryRectangular)).previewDisplayName("Rectangular")
+        LockscreenWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .accessoryCircular)).previewDisplayName("Circular")
+    }
+}

+ 44 - 0
Widget/Toolbar/ToolbarData.swift

@@ -0,0 +1,44 @@
+//
+//  ToolbarData.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 WidgetKit
+
+struct ToolbarDataEntry: TimelineEntry {
+    let date: Date
+    let isPlaceholder: Bool
+    let footerImage: String
+    let footerText: String
+}
+
+func getToolbarDataEntry(isPreview: Bool, completion: @escaping (_ entry: ToolbarDataEntry) -> Void) {
+
+    if isPreview {
+        return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
+    }
+
+    if NCManageDatabase.shared.getActiveAccount() == nil {
+        return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
+    }
+
+    completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
+}

+ 47 - 0
Widget/Toolbar/ToolbarWidgetProvider.swift

@@ -0,0 +1,47 @@
+//
+//  ToolbarWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 WidgetKit
+import SwiftUI
+
+struct ToolbarWidgetProvider: TimelineProvider {
+
+    typealias Entry = ToolbarDataEntry
+
+    func placeholder(in context: Context) -> Entry {
+        return Entry(date: Date(), isPlaceholder: true, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
+    }
+
+    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
+        getToolbarDataEntry(isPreview: false) { entry in
+            completion(entry)
+        }
+    }
+
+    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
+        getToolbarDataEntry(isPreview: context.isPreview) { entry in
+            let timeLine = Timeline(entries: [entry], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 118 - 0
Widget/Toolbar/ToolbarWidgetView.swift

@@ -0,0 +1,118 @@
+//
+//  ToolbarWidgetView.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 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 SwiftUI
+import WidgetKit
+
+struct ToolbarWidgetView: View {
+
+    var entry: ToolbarDataEntry
+
+    var body: some View {
+
+        GeometryReader { geo in
+
+            ZStack(alignment: .topLeading) {
+
+                Color(.black).opacity(0.9)
+                    .ignoresSafeArea()
+
+                HStack(spacing: 0) {
+
+                    let sizeButton: CGFloat = 65
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionUploadAsset, label: {
+                        Image("addImage")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding()
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionScanDocument, label: {
+                        Image("scan")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding()
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionTextDocument, label: {
+                        Image("note.text")
+                            .resizable()
+                            .renderingMode(.template)
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding()
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+
+                    Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionVoiceMemo, label: {
+                        Image("microphone")
+                            .resizable()
+                            .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
+                            .padding()
+                            .background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                            .clipShape(Circle())
+                            .scaledToFit()
+                            .frame(width: geo.size.width / 4, height: sizeButton)
+                    })
+                }
+                .frame(width: geo.size.width, height: geo.size.height, alignment: .center)
+                .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+
+                HStack {
+
+                    Image(systemName: entry.footerImage)
+                        .resizable()
+                        .scaledToFit()
+                        .frame(width: 15, height: 15)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+
+                    Text(entry.footerText)
+                        .font(.caption2)
+                        .padding(.trailing, 13.0)
+                        .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand))
+                }
+                .frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
+            }
+        }
+    }
+}
+
+struct ToolbarWidget_Previews: PreviewProvider {
+    static var previews: some View {
+        let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
+        ToolbarWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemMedium))
+    }
+}

+ 5 - 0
Widget/Widget-Brinding-header.h

@@ -0,0 +1,5 @@
+//
+//  Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import "CCUtility.h"

+ 93 - 0
Widget/Widget.swift

@@ -0,0 +1,93 @@
+//
+//  NextcloudWidget.swift
+//  NextcloudWidget
+//
+//  Created by Marino Faggiana on 20/08/22.
+//  Copyright © 2022 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 WidgetKit
+import SwiftUI
+
+@main
+struct NextcloudWidgetBundle: WidgetBundle {
+
+    @WidgetBundleBuilder
+    var body: some Widget {
+        DashboardWidget()
+        FilesWidget()
+        ToolbarWidget()
+        LockscreenWidget()
+    }
+}
+
+struct DashboardWidget: Widget {
+    let kind: String = "DashboardWidget"
+
+    var body: some WidgetConfiguration {
+        IntentConfiguration(kind: kind, intent: DashboardIntent.self, provider: DashboardWidgetProvider()) { entry in
+            DashboardWidgetView(entry: entry)
+        }
+        .supportedFamilies([.systemLarge])
+        .configurationDisplayName("Dashboard")
+        .description(NSLocalizedString("_description_dashboardwidget_", comment: ""))
+    }
+}
+
+struct FilesWidget: Widget {
+    let kind: String = "FilesWidget"
+
+    var body: some WidgetConfiguration {
+        StaticConfiguration(kind: kind, provider: FilesWidgetProvider()) { entry in
+            FilesWidgetView(entry: entry)
+        }
+        .supportedFamilies([.systemLarge])
+        .configurationDisplayName("Files")
+        .description(NSLocalizedString("_description_fileswidget_", comment: ""))
+    }
+}
+
+struct ToolbarWidget: Widget {
+    let kind: String = "ToolbarWidget"
+
+    var body: some WidgetConfiguration {
+        StaticConfiguration(kind: kind, provider: ToolbarWidgetProvider()) { entry in
+            ToolbarWidgetView(entry: entry)
+        }
+        .supportedFamilies([.systemMedium])
+        .configurationDisplayName("Toolbar")
+        .description(NSLocalizedString("_description_toolbarwidget_", comment: ""))
+    }
+}
+
+struct LockscreenWidget: Widget {
+    let kind: String = "LockscreenWidget"
+
+    var body: some WidgetConfiguration {
+        if #available(iOSApplicationExtension 16.0, *) {
+            return StaticConfiguration(kind: kind, provider: LockscreenWidgetProvider()) { entry in
+                LockscreenWidgetView(entry: entry)
+            }
+            .supportedFamilies([.accessoryRectangular, .accessoryCircular])
+            .configurationDisplayName(NSLocalizedString("_title_lockscreenwidget_", comment: ""))
+            .description(NSLocalizedString("_description_lockscreenwidget_", comment: ""))
+        } else {
+            return EmptyWidgetConfiguration()
+        }
+    }
+}

+ 42 - 0
WidgetDashboardIntentHandler/IntentHandler.swift

@@ -0,0 +1,42 @@
+//
+//  IntentHandler.swift
+//  WidgetDashboardIntentHandler
+//
+//  Created by Marino Faggiana on 08/10/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+
+import Intents
+import RealmSwift
+
+class IntentHandler: INExtension, DashboardIntentHandling {
+
+    func provideApplicationsOptionsCollection(for intent: DashboardIntent, with completion: @escaping (INObjectCollection<Applications>?, Error?) -> Void) {
+
+        var applications: [Applications] = []
+
+        guard let account = NCManageDatabase.shared.getActiveAccount() else {
+            completion(nil, nil)
+            return
+        }
+
+        let results = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account)
+        for result in results {
+            let application = Applications(identifier: result.id, display: result.title)
+            applications.append(application)
+        }
+
+        completion(INObjectCollection(items: applications), nil)
+    }
+
+    func defaultApplications(for intent: DashboardIntent) -> Applications? {
+
+        guard let account = NCManageDatabase.shared.getActiveAccount() else {
+            return nil
+        }
+        if let result = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account).first {
+            return Applications(identifier: result.id, display: result.title)
+        }
+        return nil
+    }
+}

+ 5 - 0
WidgetDashboardIntentHandler/WidgetDashboardIntentHandler-Brinding-header.h

@@ -0,0 +1,5 @@
+//
+//  Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import "CCUtility.h"

+ 7 - 6
iOSClient/.tx/config

@@ -1,16 +1,17 @@
 [main]
 [main]
 host = https://www.transifex.com
 host = https://www.transifex.com
 
 
-[nextcloud.ios]
+[o:nextcloud:p:nextcloud:r:ios]
 file_filter = Supporting Files/<lang>.lproj/Localizable.strings
 file_filter = Supporting Files/<lang>.lproj/Localizable.strings
 source_file = Supporting Files/en.lproj/Localizable.strings
 source_file = Supporting Files/en.lproj/Localizable.strings
 source_lang = en
 source_lang = en
-type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419,pt_PT:pt-PT,ja_JP:ja-JP
+type        = STRINGS
+lang_map    = hu_HU: hu, es_DO: es-DO, es_419: es-419, cs_CZ: cs-CZ, es_EC: es-EC, es_GT: es-GT, es_PY: es-PY, es_SV: es-SV, pt_BR: pt-BR, fi_FI: fi-FI, nb_NO: nb-NO, es_UY: es-UY, es_MX: es-MX, sk_SK: sk-SK, pt_PT: pt-PT, en_GB: en-GB, ka_GE: ka-GE, es_HN: es-HN, zh_CN: zh-Hans, es_AR: es-AR, es_NI: es-NI, es_PE: es-PE, ja_JP: ja-JP, es_CL: es-CL, es_PR: es-PR, zh_TW: zh-Hant-TW, es_CO: es-CO, es_CR: es-CR, es_PA: es-PA
 
 
-[nextcloud.ios-info]
+[o:nextcloud:p:nextcloud:r:ios-info]
 file_filter = Supporting Files/<lang>.lproj/InfoPlist.strings
 file_filter = Supporting Files/<lang>.lproj/InfoPlist.strings
 source_file = Supporting Files/en.lproj/InfoPlist.strings
 source_file = Supporting Files/en.lproj/InfoPlist.strings
 source_lang = en
 source_lang = en
-type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419,pt_PT:pt-PT,ja_JP:ja-JP
+type        = STRINGS
+lang_map    = es_NI: es-NI, es_PY: es-PY, fi_FI: fi-FI, nb_NO: nb-NO, es_PE: es-PE, es_UY: es-UY, pt_BR: pt-BR, cs_CZ: cs-CZ, en_GB: en-GB, es_CR: es-CR, es_GT: es-GT, es_419: es-419, zh_CN: zh-Hans, es_CO: es-CO, es_DO: es-DO, es_PA: es-PA, es_PR: es-PR, es_SV: es-SV, es_EC: es-EC, es_MX: es-MX, hu_HU: hu, ka_GE: ka-GE, zh_TW: zh-Hant-TW, es_AR: es-AR, sk_SK: sk-SK, es_CL: es-CL, es_HN: es-HN, pt_PT: pt-PT, ja_JP: ja-JP
+

+ 4 - 4
iOSClient/Account Request/NCAccountRequest.swift

@@ -22,7 +22,7 @@
 //
 //
 
 
 import UIKit
 import UIKit
-import NCCommunication
+import NextcloudKit
 
 
 public protocol NCAccountRequestDelegate: AnyObject {
 public protocol NCAccountRequestDelegate: AnyObject {
     func accountRequestAddAccount()
     func accountRequestAddAccount()
@@ -61,13 +61,13 @@ class NCAccountRequest: UIViewController {
 
 
         titleLabel.text = NSLocalizedString("_account_select_", comment: "")
         titleLabel.text = NSLocalizedString("_account_select_", comment: "")
 
 
-        closeButton.setImage(NCUtility.shared.loadImage(named: "xmark", color: NCBrandColor.shared.label), for: .normal)
+        closeButton.setImage(NCUtility.shared.loadImage(named: "xmark", color: .label), for: .normal)
 
 
         tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 1))
         tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 1))
         tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
         tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
 
 
-        view.backgroundColor = NCBrandColor.shared.secondarySystemBackground
-        tableView.backgroundColor = NCBrandColor.shared.secondarySystemBackground
+        view.backgroundColor = .secondarySystemBackground
+        tableView.backgroundColor = .secondarySystemBackground
 
 
         progressView.trackTintColor = .clear
         progressView.trackTintColor = .clear
         progressView.progress = 1
         progressView.progress = 1

+ 36 - 32
iOSClient/Activity/NCActivity.swift

@@ -24,7 +24,7 @@
 
 
 import UIKit
 import UIKit
 import SwiftRichString
 import SwiftRichString
-import NCCommunication
+import NextcloudKit
 
 
 class NCActivity: UIViewController, NCSharePagingContent {
 class NCActivity: UIViewController, NCSharePagingContent {
 
 
@@ -60,13 +60,13 @@ class NCActivity: UIViewController, NCSharePagingContent {
         super.viewDidLoad()
         super.viewDidLoad()
 
 
         self.navigationController?.navigationBar.prefersLargeTitles = true
         self.navigationController?.navigationBar.prefersLargeTitles = true
-        view.backgroundColor = NCBrandColor.shared.systemBackground
+        view.backgroundColor = .systemBackground
         self.title = NSLocalizedString("_activity_", comment: "")
         self.title = NSLocalizedString("_activity_", comment: "")
 
 
         tableView.allowsSelection = false
         tableView.allowsSelection = false
         tableView.separatorColor = UIColor.clear
         tableView.separatorColor = UIColor.clear
         tableView.contentInset = insets
         tableView.contentInset = insets
-        tableView.backgroundColor = NCBrandColor.shared.systemBackground
+        tableView.backgroundColor = .systemBackground
 
 
         if showComments {
         if showComments {
             setupComments()
             setupComments()
@@ -83,12 +83,12 @@ class NCActivity: UIViewController, NCSharePagingContent {
         commentView = Bundle.main.loadNibNamed("NCActivityCommentView", owner: self, options: nil)?.first as? NCActivityCommentView
         commentView = Bundle.main.loadNibNamed("NCActivityCommentView", owner: self, options: nil)?.first as? NCActivityCommentView
         commentView?.setup(urlBase: appDelegate, account: activeAccount) { newComment in
         commentView?.setup(urlBase: appDelegate, account: activeAccount) { newComment in
             guard let newComment = newComment, !newComment.isEmpty, let metadata = self.metadata else { return }
             guard let newComment = newComment, !newComment.isEmpty, let metadata = self.metadata else { return }
-            NCCommunication.shared.putComments(fileId: metadata.fileId, message: newComment) { _, errorCode, errorDescription in
-                if errorCode == 0 {
+            NextcloudKit.shared.putComments(fileId: metadata.fileId, message: newComment) { _, error in
+                if error == .success {
                     self.commentView?.newCommentField.text?.removeAll()
                     self.commentView?.newCommentField.text?.removeAll()
                     self.loadComments()
                     self.loadComments()
                 } else {
                 } else {
-                    NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                    NCContentPresenter.shared.showError(error: error)
                 }
                 }
             }
             }
         }
         }
@@ -96,7 +96,11 @@ class NCActivity: UIViewController, NCSharePagingContent {
 
 
     override func viewWillAppear(_ animated: Bool) {
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
+
         appDelegate.activeViewController = self
         appDelegate.activeViewController = self
+
+        navigationController?.setFileAppreance()
+
         NotificationCenter.default.addObserver(self, selector: #selector(initialize), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterInitialize), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(initialize), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterInitialize), object: nil)
         initialize()
         initialize()
     }
     }
@@ -163,7 +167,7 @@ extension NCActivity: UITableViewDelegate {
 
 
         let label = UILabel()
         let label = UILabel()
         label.font = UIFont.boldSystemFont(ofSize: 13)
         label.font = UIFont.boldSystemFont(ofSize: 13)
-        label.textColor = NCBrandColor.shared.label
+        label.textColor = .label
         label.text = CCUtility.getTitleSectionDate(sectionDates[section])
         label.text = CCUtility.getTitleSectionDate(sectionDates[section])
         label.textAlignment = .center
         label.textAlignment = .center
         label.layer.cornerRadius = 11
         label.layer.cornerRadius = 11
@@ -218,13 +222,13 @@ extension NCActivity: UITableViewDataSource {
         NCOperationQueue.shared.downloadAvatar(user: comment.actorId, dispalyName: comment.actorDisplayName, fileName: fileName, cell: cell, view: tableView, cellImageView: cell.fileAvatarImageView)
         NCOperationQueue.shared.downloadAvatar(user: comment.actorId, dispalyName: comment.actorDisplayName, fileName: fileName, cell: cell, view: tableView, cellImageView: cell.fileAvatarImageView)
         // Username
         // Username
         cell.labelUser.text = comment.actorDisplayName
         cell.labelUser.text = comment.actorDisplayName
-        cell.labelUser.textColor = NCBrandColor.shared.label
+        cell.labelUser.textColor = .label
         // Date
         // Date
         cell.labelDate.text = CCUtility.dateDiff(comment.creationDateTime as Date)
         cell.labelDate.text = CCUtility.dateDiff(comment.creationDateTime as Date)
-        cell.labelDate.textColor = NCBrandColor.shared.systemGray4
+        cell.labelDate.textColor = .systemGray4
         // Message
         // Message
         cell.labelMessage.text = comment.message
         cell.labelMessage.text = comment.message
-        cell.labelMessage.textColor = NCBrandColor.shared.label
+        cell.labelMessage.textColor = .label
         // Button Menu
         // Button Menu
         if comment.actorId == appDelegate.userId {
         if comment.actorId == appDelegate.userId {
             cell.buttonMenu.isHidden = false
             cell.buttonMenu.isHidden = false
@@ -248,7 +252,7 @@ extension NCActivity: UITableViewDataSource {
         cell.avatar.isHidden = true
         cell.avatar.isHidden = true
         cell.subjectTrailingConstraint.constant = 10
         cell.subjectTrailingConstraint.constant = 10
         cell.didSelectItemEnable = self.didSelectItemEnable
         cell.didSelectItemEnable = self.didSelectItemEnable
-        cell.subject.textColor = NCBrandColor.shared.label
+        cell.subject.textColor = .label
         cell.viewController = self
         cell.viewController = self
 
 
         // icon
         // icon
@@ -262,8 +266,8 @@ extension NCActivity: UITableViewDataSource {
                     cell.icon.image = image
                     cell.icon.image = image
                 }
                 }
             } else {
             } else {
-                NCCommunication.shared.downloadContent(serverUrl: activity.icon) { _, data, errorCode, _ in
-                    if errorCode == 0 {
+                NextcloudKit.shared.downloadContent(serverUrl: activity.icon) { _, data, error in
+                    if error == .success {
                         do {
                         do {
                             try data!.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
                             try data!.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
                             self.tableView.reloadData()
                             self.tableView.reloadData()
@@ -356,7 +360,7 @@ extension NCActivity {
         if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
         if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
             bottom = -mainTabBar.getHight()
             bottom = -mainTabBar.getHight()
         }
         }
-        NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom-5, style: .gray)
+        NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom-5, style: .medium)
 
 
         let dispatchGroup = DispatchGroup()
         let dispatchGroup = DispatchGroup()
         loadComments(disptachGroup: dispatchGroup)
         loadComments(disptachGroup: dispatchGroup)
@@ -403,11 +407,11 @@ extension NCActivity {
         guard showComments, let metadata = metadata else { return }
         guard showComments, let metadata = metadata else { return }
         disptachGroup?.enter()
         disptachGroup?.enter()
 
 
-        NCCommunication.shared.getComments(fileId: metadata.fileId) { account, comments, errorCode, errorDescription in
-            if errorCode == 0, let comments = comments {
+        NextcloudKit.shared.getComments(fileId: metadata.fileId) { account, comments, data, error in
+            if error == .success, let comments = comments {
                 NCManageDatabase.shared.addComments(comments, account: metadata.account, objectId: metadata.fileId)
                 NCManageDatabase.shared.addComments(comments, account: metadata.account, objectId: metadata.fileId)
-            } else if errorCode != NCGlobal.shared.errorResourceNotFound {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
+            } else if error.errorCode != NCGlobal.shared.errorResourceNotFound {
+                NCContentPresenter.shared.showError(error: error)
             }
             }
 
 
             if let disptachGroup = disptachGroup {
             if let disptachGroup = disptachGroup {
@@ -427,20 +431,20 @@ extension NCActivity {
 
 
         disptachGroup.enter()
         disptachGroup.enter()
 
 
-        NCCommunication.shared.getActivity(
+        NextcloudKit.shared.getActivity(
             since: 0,
             since: 0,
             limit: 1,
             limit: 1,
             objectId: nil,
             objectId: nil,
             objectType: objectType,
             objectType: objectType,
-            previews: true) { account, _, activityFirstKnown, activityLastGiven, errorCode, _ in
+            previews: true) { account, _, activityFirstKnown, activityLastGiven, data, error in
                 defer { disptachGroup.leave() }
                 defer { disptachGroup.leave() }
 
 
                 let largestActivityId = max(activityFirstKnown, activityLastGiven)
                 let largestActivityId = max(activityFirstKnown, activityLastGiven)
-                guard errorCode == 0,
+                guard error == .success,
                       account == self.appDelegate.account,
                       account == self.appDelegate.account,
                       largestActivityId > resultActivityId
                       largestActivityId > resultActivityId
                 else {
                 else {
-                    self.hasActivityToLoad = errorCode == 304 ? false : self.hasActivityToLoad
+                    self.hasActivityToLoad = error.errorCode == NCGlobal.shared.errorNotModified ? false : self.hasActivityToLoad
                     return
                     return
                 }
                 }
 
 
@@ -454,18 +458,18 @@ extension NCActivity {
         var resultActivityId = 0
         var resultActivityId = 0
         disptachGroup.enter()
         disptachGroup.enter()
 
 
-        NCCommunication.shared.getActivity(
+        NextcloudKit.shared.getActivity(
             since: idActivity,
             since: idActivity,
             limit: min(limit, 200),
             limit: min(limit, 200),
             objectId: metadata?.fileId,
             objectId: metadata?.fileId,
             objectType: objectType,
             objectType: objectType,
-            previews: true) { account, activities, activityFirstKnown, activityLastGiven, errorCode, _ in
+            previews: true) { account, activities, activityFirstKnown, activityLastGiven, data, error in
                 defer { disptachGroup.leave() }
                 defer { disptachGroup.leave() }
-                guard errorCode == 0,
+                guard error == .success,
                       account == self.appDelegate.account,
                       account == self.appDelegate.account,
                       !activities.isEmpty
                       !activities.isEmpty
                 else {
                 else {
-                    self.hasActivityToLoad = errorCode == 304 ? false : self.hasActivityToLoad
+                    self.hasActivityToLoad = error.errorCode == NCGlobal.shared.errorNotModified ? false : self.hasActivityToLoad
                     return
                     return
                 }
                 }
                 NCManageDatabase.shared.addActivity(activities, account: account)
                 NCManageDatabase.shared.addActivity(activities, account: account)
@@ -514,11 +518,11 @@ extension NCActivity: NCShareCommentsCellDelegate {
                     alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in
                     alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in
                         guard let message = alert.textFields?.first?.text, message != "" else { return }
                         guard let message = alert.textFields?.first?.text, message != "" else { return }
 
 
-                        NCCommunication.shared.updateComments(fileId: metadata.fileId, messageId: tableComments.messageId, message: message) { _, errorCode, errorDescription in
-                            if errorCode == 0 {
+                        NextcloudKit.shared.updateComments(fileId: metadata.fileId, messageId: tableComments.messageId, message: message) { _, error in
+                            if error == .success {
                                 self.loadComments()
                                 self.loadComments()
                             } else {
                             } else {
-                                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                                NCContentPresenter.shared.showError(error: error)
                             }
                             }
                         }
                         }
                     }))
                     }))
@@ -535,11 +539,11 @@ extension NCActivity: NCShareCommentsCellDelegate {
                 action: { _ in
                 action: { _ in
                     guard let metadata = self.metadata, let tableComments = tableComments else { return }
                     guard let metadata = self.metadata, let tableComments = tableComments else { return }
 
 
-                    NCCommunication.shared.deleteComments(fileId: metadata.fileId, messageId: tableComments.messageId) { _, errorCode, errorDescription in
-                        if errorCode == 0 {
+                    NextcloudKit.shared.deleteComments(fileId: metadata.fileId, messageId: tableComments.messageId) { _, error in
+                        if error == .success {
                             self.loadComments()
                             self.loadComments()
                         } else {
                         } else {
-                            NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
+                            NCContentPresenter.shared.showError(error: error)
                         }
                         }
                     }
                     }
                 }
                 }

+ 1 - 1
iOSClient/Activity/NCActivityCommentView.swift

@@ -48,7 +48,7 @@ class NCActivityCommentView: UIView, UITextFieldDelegate {
         } else {
         } else {
             labelUser.text = account.displayName
             labelUser.text = account.displayName
         }
         }
-        labelUser.textColor = NCBrandColor.shared.label
+        labelUser.textColor = .label
     }
     }
 
 
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {

+ 33 - 46
iOSClient/Activity/NCActivityTableViewCell.swift

@@ -22,8 +22,9 @@
 //
 //
 
 
 import Foundation
 import Foundation
-import NCCommunication
+import NextcloudKit
 import FloatingPanel
 import FloatingPanel
+import JGProgressHUD
 
 
 class NCActivityCollectionViewCell: UICollectionViewCell {
 class NCActivityCollectionViewCell: UICollectionViewCell {
 
 
@@ -108,7 +109,8 @@ extension NCActivityTableViewCell: UICollectionViewDelegate {
                         viewController.trashPath = result.filePath
                         viewController.trashPath = result.filePath
                         (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
                         (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
                     } else {
                     } else {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCGlobal.shared.errorInternalError)
+                        let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_trash_file_not_found_")
+                        NCContentPresenter.shared.showError(error: error)
                     }
                     }
                 }
                 }
             }
             }
@@ -139,54 +141,39 @@ extension NCActivityTableViewCell: UICollectionViewDelegate {
                 }
                 }
             }
             }
 
 
-            var pathComponents = activityPreview.link.components(separatedBy: "?")
-            pathComponents = pathComponents[1].components(separatedBy: "&")
-            var serverUrlFileName = pathComponents[0].replacingOccurrences(of: "dir=", with: "").removingPercentEncoding!
-            serverUrlFileName = NCUtilityFileSystem.shared.getHomeServer(account: activityPreview.account) + serverUrlFileName + "/" + activitySubjectRich.name
-            let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(activitySubjectRich.id, fileNameView: activitySubjectRich.name)!
-
-            if let backgroundView = appDelegate.window?.rootViewController?.view {
-                NCActivityIndicator.shared.start(backgroundView: backgroundView)
+            let hud = JGProgressHUD()
+            hud.indicatorView = JGProgressHUDRingIndicatorView()
+            if let indicatorView = hud.indicatorView as? JGProgressHUDRingIndicatorView {
+                indicatorView.ringWidth = 1.5
             }
             }
-
-            NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { _ in
-
-            }, taskHandler: { _ in
-
-            }, progressHandler: { _ in
-
-            }) { account, _, _, _, _, _, errorCode, _ in
-
-                if account == self.appDelegate.account && errorCode == 0 {
-
-                    let serverUrl = (serverUrlFileName as NSString).deletingLastPathComponent
-                    let fileName = (serverUrlFileName as NSString).lastPathComponent
-                    let serverUrlFileName = serverUrl + "/" + fileName
-
-                    NCNetworking.shared.readFile(serverUrlFileName: serverUrlFileName) { account, metadata, errorCode, _ in
-
-                        NCActivityIndicator.shared.stop()
-
-                        DispatchQueue.main.async {
-                            if account == self.appDelegate.account, errorCode == 0, let metadata = metadata {
-
-                                // move from id to oc:id + instanceid (ocId)
-                                let atPath = CCUtility.getDirectoryProviderStorage()! + "/" + activitySubjectRich.id
-                                let toPath = CCUtility.getDirectoryProviderStorage()! + "/" + metadata.ocId
-
-                                CCUtility.moveFile(atPath: atPath, toPath: toPath)
-
-                                NCManageDatabase.shared.addMetadata(metadata)
-                                if let viewController = self.viewController {
-                                    NCViewer.shared.view(viewController: viewController, metadata: metadata, metadatas: [metadata], imageIcon: cell?.imageView.image)
-                                }
+            guard let view = appDelegate.window?.rootViewController?.view else { return }
+            hud.show(in: view)
+
+            NextcloudKit.shared.getFileFromFileId(fileId: String(activityPreview.fileId)) { account, file, data, error in
+                if let file = file {
+
+                    let metadata = NCManageDatabase.shared.convertNCFileToMetadata(file, isEncrypted: file.e2eEncrypted, account: account)
+                    NCManageDatabase.shared.addMetadata(metadata)
+
+                    let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
+                    let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+
+                    NextcloudKit.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { _ in
+                    }, taskHandler: { _ in
+                    }, progressHandler: { progress in
+                        hud.progress = Float(progress.fractionCompleted)
+                    }) { account, _, _, _, _, _, error in
+                        hud.dismiss()
+                        if account == self.appDelegate.account && error == .success {
+                            NCManageDatabase.shared.addLocalFile(metadata: metadata)
+                            if let viewController = self.viewController {
+                                NCViewer.shared.view(viewController: viewController, metadata: metadata, metadatas: [metadata], imageIcon: cell?.imageView.image)
                             }
                             }
                         }
                         }
                     }
                     }
-
-                } else {
-
-                    NCActivityIndicator.shared.stop()
+                } else if error != .success {
+                    hud.dismiss()
+                    NCContentPresenter.shared.showError(error: error)
                 }
                 }
             }
             }
         }
         }

+ 193 - 158
iOSClient/AppDelegate.swift

@@ -23,10 +23,11 @@
 
 
 import UIKit
 import UIKit
 import BackgroundTasks
 import BackgroundTasks
-import NCCommunication
+import NextcloudKit
 import TOPasscodeViewController
 import TOPasscodeViewController
 import LocalAuthentication
 import LocalAuthentication
 import Firebase
 import Firebase
+import WidgetKit
 
 
 @UIApplicationMain
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, TOPasscodeViewControllerDelegate, NCAccountRequestDelegate, NCViewCertificateDetailsDelegate, NCUserBaseUrl {
 class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, TOPasscodeViewControllerDelegate, NCAccountRequestDelegate, NCViewCertificateDetailsDelegate, NCUserBaseUrl {
@@ -41,7 +42,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     @objc var password: String = ""
     @objc var password: String = ""
 
 
     var deletePasswordSession: Bool = false
     var deletePasswordSession: Bool = false
-    var activeAppConfigView: NCAppConfigView?
     var activeLogin: NCLogin?
     var activeLogin: NCLogin?
     var activeLoginWeb: NCLoginWeb?
     var activeLoginWeb: NCLoginWeb?
     var activeServerUrl: String = ""
     var activeServerUrl: String = ""
@@ -60,16 +60,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     var shares: [tableShare] = []
     var shares: [tableShare] = []
     var timerErrorNetworking: Timer?
     var timerErrorNetworking: Timer?
 
 
-    var errorITMS90076: Bool = false
-
     private var privacyProtectionWindow: UIWindow?
     private var privacyProtectionWindow: UIWindow?
-    
+
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 
 
         let userAgent = CCUtility.getUserAgent() as String
         let userAgent = CCUtility.getUserAgent() as String
-        let isSimulatorOrTestFlight = NCUtility.shared.isSimulatorOrTestFlight()
         let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
         let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility.shared.getVersionApp())
 
 
+        // Register initialize
+        NotificationCenter.default.addObserver(self, selector: #selector(initialize), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterInitialize), object: nil)
+
         UserDefaults.standard.register(defaults: ["UserAgent": userAgent])
         UserDefaults.standard.register(defaults: ["UserAgent": userAgent])
         if !CCUtility.getDisableCrashservice() && !NCBrandOptions.shared.disable_crash_service {
         if !CCUtility.getDisableCrashservice() && !NCBrandOptions.shared.disable_crash_service {
             FirebaseApp.configure()
             FirebaseApp.configure()
@@ -78,47 +78,38 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         CCUtility.createDirectoryStandard()
         CCUtility.createDirectoryStandard()
         CCUtility.emptyTemporaryDirectory()
         CCUtility.emptyTemporaryDirectory()
 
 
-        NCCommunicationCommon.shared.setup(delegate: NCNetworking.shared)
-        NCCommunicationCommon.shared.setup(userAgent: userAgent)
+        NKCommon.shared.setup(delegate: NCNetworking.shared)
+        NKCommon.shared.setup(userAgent: userAgent)
 
 
         startTimerErrorNetworking()
         startTimerErrorNetworking()
 
 
         // LOG
         // LOG
         var levelLog = 0
         var levelLog = 0
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
         if let pathDirectoryGroup = CCUtility.getDirectoryGroup()?.path {
-            NCCommunicationCommon.shared.pathLog = pathDirectoryGroup
+            NKCommon.shared.pathLog = pathDirectoryGroup
         }
         }
 
 
         if NCBrandOptions.shared.disable_log {
         if NCBrandOptions.shared.disable_log {
 
 
-            NCUtilityFileSystem.shared.deleteFile(filePath: NCCommunicationCommon.shared.filenamePathLog)
-            NCUtilityFileSystem.shared.deleteFile(filePath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/" + NCCommunicationCommon.shared.filenameLog)
+            NCUtilityFileSystem.shared.deleteFile(filePath: NKCommon.shared.filenamePathLog)
+            NCUtilityFileSystem.shared.deleteFile(filePath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/" + NKCommon.shared.filenameLog)
 
 
         } else {
         } else {
 
 
             levelLog = CCUtility.getLogLevel()
             levelLog = CCUtility.getLogLevel()
-            NCCommunicationCommon.shared.levelLog = levelLog
-            NCCommunicationCommon.shared.copyLogToDocumentDirectory = true
-            if isSimulatorOrTestFlight {
-                NCCommunicationCommon.shared.writeLog("Start session with level \(levelLog) " + versionNextcloudiOS + " (Simulator / TestFlight)")
-            } else {
-                NCCommunicationCommon.shared.writeLog("Start session with level \(levelLog) " + versionNextcloudiOS)
-            }
+            NKCommon.shared.levelLog = levelLog
+            NKCommon.shared.copyLogToDocumentDirectory = true
+            NKCommon.shared.writeLog("[INFO] Start session with level \(levelLog) " + versionNextcloudiOS + " in state \(UIApplication.shared.applicationState.rawValue) where (0 active, 1 inactive, 2 background).")
         }
         }
 
 
         // LOG Account
         // LOG Account
         if let account = NCManageDatabase.shared.getActiveAccount() {
         if let account = NCManageDatabase.shared.getActiveAccount() {
-            NCCommunicationCommon.shared.writeLog("Account active \(account.account)")
+            NKCommon.shared.writeLog("Account active \(account.account)")
             if CCUtility.getPassword(account.account).isEmpty {
             if CCUtility.getPassword(account.account).isEmpty {
-                NCCommunicationCommon.shared.writeLog("PASSWORD NOT FOUND for \(account.account)")
+                NKCommon.shared.writeLog("[ERROR] PASSWORD NOT FOUND for \(account.account)")
             }
             }
         }
         }
 
 
-        // ITMS-90076: Potential Loss of Keychain Access
-        if let account = NCManageDatabase.shared.getActiveAccount(), CCUtility.getPassword(account.account).isEmpty, NCUtility.shared.getVersionApp(withBuild: false).starts(with: "4.4") {
-            errorITMS90076 = true
-        }
-
         // Activate user account
         // Activate user account
         if let activeAccount = NCManageDatabase.shared.getActiveAccount() {
         if let activeAccount = NCManageDatabase.shared.getActiveAccount() {
 
 
@@ -147,13 +138,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         // Create user color
         // Create user color
         NCBrandColor.shared.createUserColors()
         NCBrandColor.shared.createUserColors()
 
 
-        // initialize
-        NotificationCenter.default.addObserver(self, selector: #selector(initialize), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterInitialize), object: nil)
-        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterInitialize, userInfo:["atStart":1])
-
-        // Process upload
-        networkingProcessUpload = NCNetworkingProcessUpload()
-
         // Push Notification & display notification
         // Push Notification & display notification
         application.registerForRemoteNotifications()
         application.registerForRemoteNotifications()
         UNUserNotificationCenter.current().delegate = self
         UNUserNotificationCenter.current().delegate = self
@@ -167,15 +151,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         }
         }
 
 
         // Background task: register
         // Background task: register
-        if #available(iOS 13.0, *) {
-            BGTaskScheduler.shared.register(forTaskWithIdentifier: NCGlobal.shared.refreshTask, using: nil) { task in
-                self.handleRefreshTask(task)
-            }
-            BGTaskScheduler.shared.register(forTaskWithIdentifier: NCGlobal.shared.processingTask, using: nil) { task in
-                self.handleProcessingTask(task)
-            }
-        } else {
-            application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
+        BGTaskScheduler.shared.register(forTaskWithIdentifier: NCGlobal.shared.refreshTask, using: nil) { task in
+            self.handleRefreshTask(task)
+        }
+        BGTaskScheduler.shared.register(forTaskWithIdentifier: NCGlobal.shared.processingTask, using: nil) { task in
+            self.handleProcessingTask(task)
         }
         }
 
 
         // Intro
         // Intro
@@ -206,47 +186,43 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     // MARK: - Life Cycle
     // MARK: - Life Cycle
 
 
-    // L' applicazione entrerà in primo piano (attivo sempre)
+    // L' applicazione entrerà in attivo (sempre)
     func applicationDidBecomeActive(_ application: UIApplication) {
     func applicationDidBecomeActive(_ application: UIApplication) {
 
 
+        NKCommon.shared.writeLog("[INFO] Application did become active")
+
         self.deletePasswordSession = false
         self.deletePasswordSession = false
 
 
         if !NCAskAuthorization.shared.isRequesting {
         if !NCAskAuthorization.shared.isRequesting {
-            // Privacy
             hidePrivacyProtectionWindow()
             hidePrivacyProtectionWindow()
         }
         }
 
 
         NCSettingsBundleHelper.setVersionAndBuildNumber()
         NCSettingsBundleHelper.setVersionAndBuildNumber()
 
 
-        if account == "" { return }
-
-        networkingProcessUpload?.verifyUploadZombie()
+        if !account.isEmpty {
+            networkingProcessUpload?.verifyUploadZombie()
+        }
 
 
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterApplicationDidBecomeActive)
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterApplicationDidBecomeActive)
     }
     }
 
 
-    // L' applicazione entrerà in primo piano (attivo solo dopo il background)
+    // L' applicazione entrerà in primo piano (dopo il background)
     func applicationWillEnterForeground(_ application: UIApplication) {
     func applicationWillEnterForeground(_ application: UIApplication) {
+        guard !account.isEmpty, let activeAccount = NCManageDatabase.shared.getActiveAccount() else { return }
 
 
-        if account == "" { return }
-        guard let activeAccount = NCManageDatabase.shared.getActiveAccount() else { return }
+        NKCommon.shared.writeLog("[INFO] Application will enter in foreground")
 
 
         // Account changed ??
         // Account changed ??
         if activeAccount.account != account {
         if activeAccount.account != account {
             settingAccount(activeAccount.account, urlBase: activeAccount.urlBase, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account))
             settingAccount(activeAccount.account, urlBase: activeAccount.urlBase, user: activeAccount.user, userId: activeAccount.userId, password: CCUtility.getPassword(activeAccount.account))
-
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterInitialize)
-        }
-
-        NCCommunicationCommon.shared.writeLog("Application will enter in foreground")
-
-        // START TIMER UPLOAD PROCESS
-        if NCUtility.shared.isSimulator() {
-            networkingProcessUpload?.startTimer()
+        } else {
+            // Initialize Auto upload
+            NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in
+                NKCommon.shared.writeLog("[INFO] Initialize Auto upload with \(items) uploads")
+                // START UPLOAD PROCESS
+                DispatchQueue.main.async { self.networkingProcessUpload = NCNetworkingProcessUpload() }
+            }
         }
         }
-        
-        // Initialize Auto upload
-        NCAutoUpload.shared.initAutoUpload(viewController: nil) { _ in }
 
 
         // Required unsubscribing / subscribing
         // Required unsubscribing / subscribing
         NCPushNotification.shared().pushNotification()
         NCPushNotification.shared().pushNotification()
@@ -264,14 +240,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     // L' applicazione si dimetterà dallo stato di attivo
     // L' applicazione si dimetterà dallo stato di attivo
     func applicationWillResignActive(_ application: UIApplication) {
     func applicationWillResignActive(_ application: UIApplication) {
+        guard !account.isEmpty else { return }
 
 
-        if account == "" { return }
+        NKCommon.shared.writeLog("[INFO] Application will resign active")
 
 
         if CCUtility.getPrivacyScreenEnabled() {
         if CCUtility.getPrivacyScreenEnabled() {
             // Privacy
             // Privacy
             showPrivacyProtectionWindow()
             showPrivacyProtectionWindow()
         }
         }
 
 
+        // Reload Widget
+        WidgetCenter.shared.reloadAllTimelines()
+
         // Clear operation queue
         // Clear operation queue
         NCOperationQueue.shared.cancelAllQueue()
         NCOperationQueue.shared.cancelAllQueue()
         // Clear download
         // Clear download
@@ -288,18 +268,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     // L' applicazione è entrata nello sfondo
     // L' applicazione è entrata nello sfondo
     func applicationDidEnterBackground(_ application: UIApplication) {
     func applicationDidEnterBackground(_ application: UIApplication) {
+        guard !account.isEmpty else { return }
 
 
-        if account == "" { return }
+        NKCommon.shared.writeLog("[INFO] Application did enter in background")
 
 
-        // STOP TIMER UPLOAD PROCESS
-        if NCUtility.shared.isSimulator() {
-            networkingProcessUpload?.stopTimer()
-        }
+        // STOP UPLOAD PROCESS
+        networkingProcessUpload?.stopTimer()
 
 
-        if #available(iOS 13.0, *) {
-            scheduleAppRefresh()
-            scheduleBackgroundProcessing()
-        }
+        scheduleAppRefresh()
+        scheduleAppProcessing()
 
 
         // Passcode
         // Passcode
         presentPasscode { }
         presentPasscode { }
@@ -311,7 +288,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     func applicationWillTerminate(_ application: UIApplication) {
     func applicationWillTerminate(_ application: UIApplication) {
 
 
         NCNetworking.shared.cancelAllDownloadTransfer()
         NCNetworking.shared.cancelAllDownloadTransfer()
-        NCCommunicationCommon.shared.writeLog("bye bye")
+
+        let content = UNMutableNotificationContent()
+        content.title = NCBrandOptions.shared.brand
+        content.body = NSLocalizedString("_keep_running_", comment: "")
+        let req = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
+        let notificationCenter = UNUserNotificationCenter.current()
+        notificationCenter.add(req)
+
+        NKCommon.shared.writeLog("bye bye")
     }
     }
 
 
     // MARK: -
     // MARK: -
@@ -319,13 +304,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     @objc private func initialize() {
     @objc private func initialize() {
         guard !account.isEmpty else { return }
         guard !account.isEmpty else { return }
 
 
-        NCCommunicationCommon.shared.writeLog("initialize Main")
+        NKCommon.shared.writeLog("[INFO] initialize Main")
 
 
         // Registeration push notification
         // Registeration push notification
         NCPushNotification.shared().pushNotification()
         NCPushNotification.shared().pushNotification()
 
 
         // Start Auto Upload
         // Start Auto Upload
-        NCAutoUpload.shared.initAutoUpload(viewController: nil) { _ in }
+        NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in
+            NKCommon.shared.writeLog("[INFO] Initialize Auto upload with \(items) uploads")
+            DispatchQueue.main.async { self.networkingProcessUpload = NCNetworkingProcessUpload() }
+        }
 
 
         // Start services
         // Start services
         NCService.shared.startRequestServicesServer()
         NCService.shared.startRequestServicesServer()
@@ -333,6 +321,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         // close detail
         // close detail
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMenuDetailClose)
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMenuDetailClose)
 
 
+        // Reload Widget
+        WidgetCenter.shared.reloadAllTimelines()
+
         // Registeration domain File Provider
         // Registeration domain File Provider
         // FileProviderDomain *fileProviderDomain = [FileProviderDomain new];
         // FileProviderDomain *fileProviderDomain = [FileProviderDomain new];
         // [fileProviderDomain removeAllDomains];
         // [fileProviderDomain removeAllDomains];
@@ -341,100 +332,80 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     // MARK: - Background Task
     // MARK: - Background Task
 
 
-    @available(iOS 13.0, *)
+    /*
+    @discussion Schedule a refresh task request to ask that the system launch your app briefly so that you can download data and keep your app's contents up-to-date. The system will fulfill this request intelligently based on system conditions and app usage.
+     < MAX 30 seconds >
+     */
     func scheduleAppRefresh() {
     func scheduleAppRefresh() {
 
 
         let request = BGAppRefreshTaskRequest(identifier: NCGlobal.shared.refreshTask)
         let request = BGAppRefreshTaskRequest(identifier: NCGlobal.shared.refreshTask)
-        request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60) // Refresh after 5 minutes.
+        request.earliestBeginDate = Date(timeIntervalSinceNow: 60) // Refresh after 60 seconds.
         do {
         do {
             try BGTaskScheduler.shared.submit(request)
             try BGTaskScheduler.shared.submit(request)
-            NCCommunicationCommon.shared.writeLog("Refresh task success submit request \(request)")
+            NKCommon.shared.writeLog("[SUCCESS] Refresh task success submit request 60 seconds \(request)")
         } catch {
         } catch {
-            NCCommunicationCommon.shared.writeLog("Refresh task failed to submit request: \(error)")
+            NKCommon.shared.writeLog("[ERROR] Refresh task failed to submit request: \(error)")
         }
         }
     }
     }
 
 
-    @available(iOS 13.0, *)
-    func scheduleBackgroundProcessing() {
+    /*
+     @discussion Schedule a processing task request to ask that the system launch your app when conditions are favorable for battery life to handle deferrable, longer-running processing, such as syncing, database maintenance, or similar tasks. The system will attempt to fulfill this request to the best of its ability within the next two days as long as the user has used your app within the past week.
+     < MAX over 1 minute >
+     */
+    func scheduleAppProcessing() {
 
 
         let request = BGProcessingTaskRequest(identifier: NCGlobal.shared.processingTask)
         let request = BGProcessingTaskRequest(identifier: NCGlobal.shared.processingTask)
         request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60) // Refresh after 5 minutes.
         request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60) // Refresh after 5 minutes.
-        request.requiresNetworkConnectivity = true
+        request.requiresNetworkConnectivity = false
         request.requiresExternalPower = false
         request.requiresExternalPower = false
         do {
         do {
             try BGTaskScheduler.shared.submit(request)
             try BGTaskScheduler.shared.submit(request)
-            NCCommunicationCommon.shared.writeLog("Background Processing task success submit request \(request)")
+            NKCommon.shared.writeLog("[SUCCESS] Background Processing task success submit request 5 minutes \(request)")
         } catch {
         } catch {
-            NCCommunicationCommon.shared.writeLog("Background Processing task failed to submit request: \(error)")
+            NKCommon.shared.writeLog("[ERROR] Background Processing task failed to submit request: \(error)")
         }
         }
     }
     }
 
 
-    @available(iOS 13.0, *)
     func handleRefreshTask(_ task: BGTask) {
     func handleRefreshTask(_ task: BGTask) {
-
-        if account == "" {
+        scheduleAppRefresh()
+        
+        guard !account.isEmpty else {
             task.setTaskCompleted(success: true)
             task.setTaskCompleted(success: true)
             return
             return
         }
         }
 
 
-        NCCommunicationCommon.shared.writeLog("Start handler refresh task [Auto upload]")
-
-        NCAutoUpload.shared.initAutoUpload(viewController: nil) { _ in
-            DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
-                NCCommunicationCommon.shared.writeLog("Completition handler refresh task with [Auto upload]")
-                task.setTaskCompleted(success: true)
-            }
+        NKCommon.shared.setup(delegate: NCNetworking.shared)
+        NKCommon.shared.writeLog("[INFO] Start handler refresh task [Auto upload]")
+        
+        NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in
+            NKCommon.shared.writeLog("[INFO] Completition handler refresh task [Auto upload] with \(items) uploads")
+            task.setTaskCompleted(success: true)
         }
         }
     }
     }
 
 
-    @available(iOS 13.0, *)
     func handleProcessingTask(_ task: BGTask) {
     func handleProcessingTask(_ task: BGTask) {
-
-        if account == "" {
+        scheduleAppProcessing()
+        
+        guard !account.isEmpty else {
             task.setTaskCompleted(success: true)
             task.setTaskCompleted(success: true)
             return
             return
         }
         }
 
 
-        NCCommunicationCommon.shared.writeLog("Start handler processing task [Synchronize Favorite & Offline]")
-
-        NCNetworking.shared.listingFavoritescompletion(selector: NCGlobal.shared.selectorReadFile) { _, _, errorCode, _ in
-            NCCommunicationCommon.shared.writeLog("Completition listing favorite with error: \(errorCode)")
-        }
+        NKCommon.shared.setup(delegate: NCNetworking.shared)
+        NKCommon.shared.writeLog("[INFO] Start handler processing task [Reload widget]")
 
 
-        NCService.shared.synchronizeOffline(account: account)
+        WidgetCenter.shared.reloadAllTimelines()
 
 
-        DispatchQueue.main.asyncAfter(deadline: .now() + 25) {
-            NCCommunicationCommon.shared.writeLog("Completition handler processing task [Synchronize Favorite & Offline]")
-            task.setTaskCompleted(success: true)
-        }
-    }
-
-    // MARK: - Fetch
-
-    func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
-
-        if account == "" {
-            completionHandler(UIBackgroundFetchResult.noData)
-            return
-        }
-
-        NCCommunicationCommon.shared.writeLog("Start perform Fetch [Auto upload]")
-
-        NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in
-            NCCommunicationCommon.shared.writeLog("Completition perform Fetch with \(items) uploads [Auto upload]")
-            if items == 0 {
-                completionHandler(UIBackgroundFetchResult.noData)
-            } else {
-                completionHandler(UIBackgroundFetchResult.newData)
-            }
-        }
+        task.setTaskCompleted(success: true)
     }
     }
 
 
     // MARK: - Background Networking Session
     // MARK: - Background Networking Session
 
 
     func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
     func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
 
 
-        NCCommunicationCommon.shared.writeLog("Start handle Events For Background URLSession: \(identifier)")
+        NKCommon.shared.writeLog("[INFO] Start handle Events For Background URLSession: \(identifier)")
+        // Reload Widget
+        WidgetCenter.shared.reloadAllTimelines()
         backgroundSessionCompletionHandler = completionHandler
         backgroundSessionCompletionHandler = completionHandler
     }
     }
 
 
@@ -449,8 +420,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     }
     }
 
 
     func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
     func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
-        NCNetworking.shared.checkPushNotificationServerProxyCertificateUntrusted(viewController: self.window?.rootViewController) { errorCode in
-            if errorCode == 0 {
+        NCNetworking.shared.checkPushNotificationServerProxyCertificateUntrusted(viewController: self.window?.rootViewController) { error in
+            if error == .success {
                 NCPushNotification.shared().registerForRemoteNotifications(withDeviceToken: deviceToken)
                 NCPushNotification.shared().registerForRemoteNotifications(withDeviceToken: deviceToken)
             }
             }
         }
         }
@@ -466,18 +437,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     @objc func openLogin(viewController: UIViewController?, selector: Int, openLoginWeb: Bool) {
     @objc func openLogin(viewController: UIViewController?, selector: Int, openLoginWeb: Bool) {
 
 
-        // use appConfig [MDM]
-        if NCBrandOptions.shared.use_configuration {
-
-            if activeAppConfigView?.view.window == nil {
-                activeAppConfigView = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCAppConfigView") as? NCAppConfigView
-                showLoginViewController(activeAppConfigView, contextViewController: viewController)
-            }
-            return
-        }
-
-        // only for personalized LoginWeb [customer]
-        if NCBrandOptions.shared.use_login_web_personalized {
+        // [WEBPersonalized] [AppConfig]
+        if NCBrandOptions.shared.use_login_web_personalized || NCBrandOptions.shared.use_AppConfig {
 
 
             if activeLoginWeb?.view.window == nil {
             if activeLoginWeb?.view.window == nil {
                 activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb
                 activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb
@@ -576,19 +537,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
         let certificateHostSavedPath = CCUtility.getDirectoryCerificates()! + "/" + host + ".der"
         let certificateHostSavedPath = CCUtility.getDirectoryCerificates()! + "/" + host + ".der"
         var title = NSLocalizedString("_ssl_certificate_changed_", comment: "")
         var title = NSLocalizedString("_ssl_certificate_changed_", comment: "")
-        
+
         if !FileManager.default.fileExists(atPath: certificateHostSavedPath) {
         if !FileManager.default.fileExists(atPath: certificateHostSavedPath) {
             title = NSLocalizedString("_connect_server_anyway_", comment: "")
             title = NSLocalizedString("_connect_server_anyway_", comment: "")
         }
         }
-        
+
         let alertController = UIAlertController(title: title, message: NSLocalizedString("_server_is_trusted_", comment: ""), preferredStyle: .alert)
         let alertController = UIAlertController(title: title, message: NSLocalizedString("_server_is_trusted_", comment: ""), preferredStyle: .alert)
-        
+
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", comment: ""), style: .default, handler: { action in
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", comment: ""), style: .default, handler: { action in
             NCNetworking.shared.writeCertificate(host: host)
             NCNetworking.shared.writeCertificate(host: host)
         }))
         }))
-        
+
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_no_", comment: ""), style: .default, handler: { action in }))
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_no_", comment: ""), style: .default, handler: { action in }))
-        
+
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_certificate_details_", comment: ""), style: .default, handler: { action in
         alertController.addAction(UIAlertAction(title: NSLocalizedString("_certificate_details_", comment: ""), style: .default, handler: { action in
             if let navigationController = UIStoryboard(name: "NCViewCertificateDetails", bundle: nil).instantiateInitialViewController() as? UINavigationController {
             if let navigationController = UIStoryboard(name: "NCViewCertificateDetails", bundle: nil).instantiateInitialViewController() as? UINavigationController {
                 let viewController = navigationController.topViewController as! NCViewCertificateDetails
                 let viewController = navigationController.topViewController as! NCViewCertificateDetails
@@ -597,7 +558,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                 self.window?.rootViewController?.present(navigationController, animated: true)
                 self.window?.rootViewController?.present(navigationController, animated: true)
             }
             }
         }))
         }))
-        
+
         window?.rootViewController?.present(alertController, animated: true)
         window?.rootViewController?.present(alertController, animated: true)
     }
     }
 
 
@@ -609,6 +570,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     @objc func settingAccount(_ account: String, urlBase: String, user: String, userId: String, password: String) {
     @objc func settingAccount(_ account: String, urlBase: String, user: String, userId: String, password: String) {
 
 
+        let accountBackup = self.account
+        let userIdBackup = self.userId
+
         self.account = account
         self.account = account
         self.urlBase = urlBase
         self.urlBase = urlBase
         self.user = user
         self.user = user
@@ -617,12 +581,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
         _ = NCFunctionCenter.shared
         _ = NCFunctionCenter.shared
 
 
-        NCCommunicationCommon.shared.setup(account: account, user: user, userId: userId, password: password, urlBase: urlBase)
+        NKCommon.shared.setup(account: account, user: user, userId: userId, password: password, urlBase: urlBase)
         let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
         let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: account, elements: NCElementsJSON.shared.capabilitiesVersionMajor)
         if serverVersionMajor > 0 {
         if serverVersionMajor > 0 {
-            NCCommunicationCommon.shared.setup(nextcloudVersion: serverVersionMajor)
+            NKCommon.shared.setup(nextcloudVersion: serverVersionMajor)
         }
         }
         NCKTVHTTPCache.shared.restartProxy(user: user, password: password)
         NCKTVHTTPCache.shared.restartProxy(user: user, password: password)
+
+        DispatchQueue.main.async {
+            if UIApplication.shared.applicationState != .background && (accountBackup != account || userIdBackup != userId) {
+                NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterInitialize, second: 0.2)
+            }
+        }
     }
     }
 
 
     @objc func deleteAccount(_ account: String, wipe: Bool) {
     @objc func deleteAccount(_ account: String, wipe: Bool) {
@@ -663,8 +633,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
             NCNetworking.shared.cancelAllTask()
             NCNetworking.shared.cancelAllTask()
 
 
             settingAccount(tableAccount.account, urlBase: tableAccount.urlBase, user: tableAccount.user, userId: tableAccount.userId, password: CCUtility.getPassword(tableAccount.account))
             settingAccount(tableAccount.account, urlBase: tableAccount.urlBase, user: tableAccount.user, userId: tableAccount.userId, password: CCUtility.getPassword(tableAccount.account))
-
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterInitialize)
         }
         }
     }
     }
 
 
@@ -699,7 +667,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                 let popup = NCPopupViewController(contentController: vcAccountRequest, popupWidth: 300, popupHeight: height+20)
                 let popup = NCPopupViewController(contentController: vcAccountRequest, popupWidth: 300, popupHeight: height+20)
                 popup.backgroundAlpha = 0.8
                 popup.backgroundAlpha = 0.8
 
 
-                UIApplication.shared.keyWindow?.rootViewController?.present(popup, animated: true)
+                window?.rootViewController?.present(popup, animated: true)
                 
                 
                 vcAccountRequest.startTimer()
                 vcAccountRequest.startTimer()
             }
             }
@@ -814,8 +782,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     // MARK: - Open URL
     // MARK: - Open URL
 
 
     func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
     func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
-
-        if account == "" { return false }
+        guard !account.isEmpty else { return false }
 
 
         let scheme = url.scheme
         let scheme = url.scheme
         let action = url.host
         let action = url.host
@@ -823,7 +790,73 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         var serverUrl: String = ""
         var serverUrl: String = ""
         var matchedAccount: tableAccount?
         var matchedAccount: tableAccount?
 
 
-        if scheme == "nextcloud" && action == "open-file" {
+        /*
+         Example:
+         nextcloud://open-action?action=create-voice-memo
+         */
+
+        if scheme == "nextcloud" && action == "open-action" {
+
+            if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
+                let queryItems = urlComponents.queryItems
+                guard let actionScheme = CCUtility.value(forKey: "action", fromQueryItems: queryItems), let rootViewController = window?.rootViewController else { return false }
+                
+                switch actionScheme {
+                case NCGlobal.shared.actionUploadAsset:
+
+                    NCAskAuthorization.shared.askAuthorizationPhotoLibrary(viewController: rootViewController) { hasPermission in
+                        if hasPermission {
+                            NCPhotosPickerViewController.init(viewController: rootViewController, maxSelectedAssets: 0, singleSelectedMode: false)
+                        }
+                    }
+                    
+                case NCGlobal.shared.actionScanDocument:
+                    
+                    NCCreateScanDocument.shared.openScannerDocument(viewController: rootViewController)
+                    
+                case NCGlobal.shared.actionTextDocument:
+                    
+                    guard let navigationController = UIStoryboard(name: "NCCreateFormUploadDocuments", bundle: nil).instantiateInitialViewController(), let directEditingCreators = NCManageDatabase.shared.getDirectEditingCreators(account: account), let directEditingCreator = directEditingCreators.first(where: { $0.editor == NCGlobal.shared.editorText}) else { return false }
+                    
+                    navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
+
+                    let viewController = (navigationController as! UINavigationController).topViewController as! NCCreateFormUploadDocuments
+                    viewController.editorId = NCGlobal.shared.editorText
+                    viewController.creatorId = directEditingCreator.identifier
+                    viewController.typeTemplate = NCGlobal.shared.templateDocument
+                    viewController.serverUrl = activeServerUrl
+                    viewController.titleForm = NSLocalizedString("_create_nextcloudtext_document_", comment: "")
+
+                    rootViewController.present(navigationController, animated: true, completion: nil)
+                    
+                case NCGlobal.shared.actionVoiceMemo:
+                    
+                    NCAskAuthorization.shared.askAuthorizationAudioRecord(viewController: rootViewController) { hasPermission in
+                        if hasPermission {
+                            let fileName = CCUtility.createFileNameDate(NSLocalizedString("_voice_memo_filename_", comment: ""), extension: "m4a")!
+                            let viewController = UIStoryboard(name: "NCAudioRecorderViewController", bundle: nil).instantiateInitialViewController() as! NCAudioRecorderViewController
+
+                            viewController.delegate = self
+                            viewController.createRecorder(fileName: fileName)
+                            viewController.modalTransitionStyle = .crossDissolve
+                            viewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
+
+                            rootViewController.present(viewController, animated: true, completion: nil)
+                        }
+                    }
+
+                default:
+                    print("No action")
+                }
+            }
+        }
+
+        /*
+         Example:
+         nextcloud://open-file?path=Talk/IMG_0000123.jpg&user=marinofaggiana&link=https://cloud.nextcloud.com/f/123
+         */
+
+        else if scheme == "nextcloud" && action == "open-file" {
 
 
             if !isSearchingMode, let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
             if !isSearchingMode, let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
 
 
@@ -862,7 +895,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                         }
                         }
 
 
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
-                            NCFunctionCenter.shared.openFileViewInFolder(serverUrl: serverUrl, fileNameBlink: fileName)
+                            NCFunctionCenter.shared.openFileViewInFolder(serverUrl: serverUrl, fileNameBlink: nil, fileNameOpen: fileName)
                         }
                         }
 
 
                     } else {
                     } else {
@@ -880,6 +913,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                     }
                     }
                 }
                 }
             }
             }
+        } else {
+            app.open(url)
         }
         }
 
 
         return true
         return true
@@ -908,6 +943,6 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate {
 extension AppDelegate: NCCreateFormUploadConflictDelegate {
 extension AppDelegate: NCCreateFormUploadConflictDelegate {
     func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) {
     func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) {
         guard let metadatas = metadatas, !metadatas.isEmpty else { return }
         guard let metadatas = metadatas, !metadatas.isEmpty else { return }
-        networkingProcessUpload?.createProcessUploads(metadatas: metadatas)
+        networkingProcessUpload?.createProcessUploads(metadatas: metadatas, completion: { _ in })
     }
     }
 }
 }

+ 9 - 21
iOSClient/Brand/Intro/NCIntroViewController.swift

@@ -60,20 +60,12 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
             textColorOpponent = .black
             textColorOpponent = .black
         }
         }
 
 
-        if #available(iOS 13.0, *) {
-            let navBarAppearance = UINavigationBarAppearance()
-            navBarAppearance.configureWithTransparentBackground()
-            navBarAppearance.shadowColor = .clear
-            navBarAppearance.shadowImage = UIImage()
-            self.navigationController?.navigationBar.standardAppearance = navBarAppearance
-            self.navigationController?.view.backgroundColor = NCBrandColor.shared.customer
-        } else {
-            self.navigationController?.navigationBar.isTranslucent = true
-            self.navigationController?.navigationBar.shadowImage = UIImage()
-            self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
-            self.navigationController?.navigationBar.backgroundColor = .clear
-            self.navigationController?.navigationBar.barTintColor = NCBrandColor.shared.customer
-        }
+        let navBarAppearance = UINavigationBarAppearance()
+        navBarAppearance.configureWithTransparentBackground()
+        navBarAppearance.shadowColor = .clear
+        navBarAppearance.shadowImage = UIImage()
+        self.navigationController?.navigationBar.standardAppearance = navBarAppearance
+        self.navigationController?.view.backgroundColor = NCBrandColor.shared.customer
         self.navigationController?.navigationBar.tintColor = textColor
         self.navigationController?.navigationBar.tintColor = textColor
 
 
         pageControl.currentPageIndicatorTintColor = textColor
         pageControl.currentPageIndicatorTintColor = textColor
@@ -108,14 +100,10 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
     }
     }
 
 
     override var preferredStatusBarStyle: UIStatusBarStyle {
     override var preferredStatusBarStyle: UIStatusBarStyle {
-        if #available(iOS 13.0, *) {
-            if traitCollection.userInterfaceStyle == .light {
-                return .lightContent
-            } else {
-                return .darkContent
-            }
-        } else {
+        if traitCollection.userInterfaceStyle == .light {
             return .lightContent
             return .lightContent
+        } else {
+            return .darkContent
         }
         }
     }
     }
 
 

+ 42 - 238
iOSClient/Brand/NCBrand.swift

@@ -23,20 +23,6 @@
 
 
 import UIKit
 import UIKit
 
 
-// MARK: - Configuration
-
-@objc class NCBrandConfiguration: NSObject {
-    @objc static let shared: NCBrandConfiguration = {
-        let instance = NCBrandConfiguration()
-        return instance
-    }()
-
-    @objc public let configuration_bundleId: String = "it.twsweb.Nextcloud"
-    @objc public let configuration_serverUrl: String = "serverUrl"
-    @objc public let configuration_username: String = "username"
-    @objc public let configuration_password: String = "password"
-}
-
 // MARK: - Options
 // MARK: - Options
 
 
 @objc class NCBrandOptions: NSObject {
 @objc class NCBrandOptions: NSObject {
@@ -46,20 +32,19 @@ import UIKit
     }()
     }()
 
 
     @objc public var brand: String = "Nextcloud"
     @objc public var brand: String = "Nextcloud"
-    // @objc public var mailMe:                            String = "ios@nextcloud.com"                              // Deprecated
     @objc public var textCopyrightNextcloudiOS: String = "Nextcloud Liquid for iOS %@ © 2022"
     @objc public var textCopyrightNextcloudiOS: String = "Nextcloud Liquid for iOS %@ © 2022"
     @objc public var textCopyrightNextcloudServer: String = "Nextcloud Server %@"
     @objc public var textCopyrightNextcloudServer: String = "Nextcloud Server %@"
     @objc public var loginBaseUrl: String = "https://cloud.nextcloud.com"
     @objc public var loginBaseUrl: String = "https://cloud.nextcloud.com"
     @objc public var pushNotificationServerProxy: String = "https://push-notifications.nextcloud.com"
     @objc public var pushNotificationServerProxy: String = "https://push-notifications.nextcloud.com"
     @objc public var linkLoginHost: String = "https://nextcloud.com/install"
     @objc public var linkLoginHost: String = "https://nextcloud.com/install"
     @objc public var linkloginPreferredProviders: String = "https://nextcloud.com/signup-ios"
     @objc public var linkloginPreferredProviders: String = "https://nextcloud.com/signup-ios"
-    @objc public var webLoginAutenticationProtocol: String = "nc://"                                            // example "abc://"
+    @objc public var webLoginAutenticationProtocol: String = "nc://"                                                // example "abc://"
     @objc public var privacy: String = "https://nextcloud.com/privacy"
     @objc public var privacy: String = "https://nextcloud.com/privacy"
     @objc public var sourceCode: String = "https://github.com/nextcloud/ios"
     @objc public var sourceCode: String = "https://github.com/nextcloud/ios"
 
 
     // Personalized
     // Personalized
-    @objc public var webCloseViewProtocolPersonalized: String = ""                                                 // example "abc://change/plan"      Don't touch me !!
-    @objc public var folderBrandAutoUpload: String = ""                                                 // example "_auto_upload_folder_"   Don't touch me !!
+    @objc public var webCloseViewProtocolPersonalized: String = ""                                                  // example "abc://change/plan"      Don't touch me !!
+    @objc public var folderBrandAutoUpload: String = ""                                                             // example "_auto_upload_folder_"   Don't touch me !!
 
 
     // Auto Upload default folder
     // Auto Upload default folder
     @objc public var folderDefaultAutoUpload: String = "Photos"
     @objc public var folderDefaultAutoUpload: String = "Photos"
@@ -68,16 +53,17 @@ import UIKit
     @objc public var capabilitiesGroups: String = "group.it.twsweb.Crypto-Cloud"
     @objc public var capabilitiesGroups: String = "group.it.twsweb.Crypto-Cloud"
 
 
     // User Agent
     // User Agent
-    @objc public var userAgent: String = "Nextcloud-iOS"                                    // Don't touch me !!
+    @objc public var userAgent: String = "Nextcloud-iOS"                                                            // Don't touch me !!
 
 
-    // Options
+    // BRAND ONLY
     @objc public var use_login_web_personalized:        Bool = false                                                // Don't touch me !!
     @objc public var use_login_web_personalized:        Bool = false                                                // Don't touch me !!
+    @objc public var use_AppConfig:                     Bool = false                                                // Don't touch me !!
+    
+    // Options
     @objc public var use_default_auto_upload:           Bool = false
     @objc public var use_default_auto_upload:           Bool = false
     @objc public var use_themingColor:                  Bool = true
     @objc public var use_themingColor:                  Bool = true
-    //@objc public var use_themingBackground:             Bool = true                                               // Deprecated
     @objc public var use_themingLogo:                   Bool = false
     @objc public var use_themingLogo:                   Bool = false
     @objc public var use_storeLocalAutoUploadAll:       Bool = false
     @objc public var use_storeLocalAutoUploadAll:       Bool = false
-    @objc public var use_configuration:                 Bool = false                                                // Don't touch me !!
     @objc public var use_loginflowv2:                   Bool = false                                                // Don't touch me !!
     @objc public var use_loginflowv2:                   Bool = false                                                // Don't touch me !!
 
 
     @objc public var disable_intro:                     Bool = false
     @objc public var disable_intro:                     Bool = false
@@ -87,7 +73,6 @@ import UIKit
     @objc public var disable_more_external_site:        Bool = false
     @objc public var disable_more_external_site:        Bool = false
     @objc public var disable_openin_file:               Bool = false                                                // Don't touch me !!
     @objc public var disable_openin_file:               Bool = false                                                // Don't touch me !!
     @objc public var disable_crash_service:             Bool = false
     @objc public var disable_crash_service:             Bool = false
-    @objc public var disable_request_account:           Bool = false
     @objc public var disable_log:                       Bool = false
     @objc public var disable_log:                       Bool = false
 
 
     override init() {
     override init() {
@@ -95,6 +80,35 @@ import UIKit
         if folderBrandAutoUpload != "" {
         if folderBrandAutoUpload != "" {
             folderDefaultAutoUpload = folderBrandAutoUpload
             folderDefaultAutoUpload = folderBrandAutoUpload
         }
         }
+        
+        // wrapper AppConfig
+        if let configurationManaged = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed"), use_AppConfig {
+            
+            if let str = configurationManaged[NCGlobal.shared.configuration_brand] as? String {
+                brand = str
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_intro] as? String {
+                disable_intro = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_multiaccount] as? String {
+                disable_multiaccount = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_crash_service] as? String {
+                disable_crash_service = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_log] as? String {
+                disable_log = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_manage_account] as? String {
+                disable_manage_account = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_more_external_site] as? String {
+                disable_more_external_site = (str as NSString).boolValue
+            }
+            if let str = configurationManaged[NCGlobal.shared.configuration_disable_openin_file] as? String {
+                disable_openin_file = (str as NSString).boolValue
+            }
+        }
     }
     }
 }
 }
 
 
@@ -146,11 +160,11 @@ class NCBrandColor: NSObject {
     }
     }
 
 
     // Color
     // Color
-    @objc public let customer: UIColor = UIColor(red: 0.0/255.0, green: 130.0/255.0, blue: 201.0/255.0, alpha: 1.0)    // BLU NC : #0082c9
+    @objc public let customer: UIColor = UIColor(red: 0.0/255.0, green: 130.0/255.0, blue: 201.0/255.0, alpha: 1.0)     // BLU NC : #0082c9
     @objc public var customerText: UIColor = .white
     @objc public var customerText: UIColor = .white
 
 
-    @objc public var brand: UIColor                                                                                 // don't touch me
-    @objc public var brandElement: UIColor                                                                                 // don't touch me
+    @objc public var brand: UIColor                                                                                     // don't touch me
+    @objc public var brandElement: UIColor                                                                              // don't touch me
     @objc public var brandText: UIColor                                                                                 // don't touch me
     @objc public var brandText: UIColor                                                                                 // don't touch me
 
 
     @objc public let nextcloud: UIColor = UIColor(red: 0.0/255.0, green: 130.0/255.0, blue: 201.0/255.0, alpha: 1.0)
     @objc public let nextcloud: UIColor = UIColor(red: 0.0/255.0, green: 130.0/255.0, blue: 201.0/255.0, alpha: 1.0)
@@ -163,225 +177,15 @@ class NCBrandColor: NSObject {
     public var themingColorElement: String = ""
     public var themingColorElement: String = ""
     public var themingColorText: String = ""
     public var themingColorText: String = ""
 
 
-    @objc public var annotationColor: UIColor {
-        get {
-            return .systemBlue
-        }
-    }
-
-    @objc public var systemBlue: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemBlue
-            } else {
-                return UIColor(red: 0.0, green: 122.0 / 255.0, blue: 1.0, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemIndigo: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemIndigo
-            } else {
-                return UIColor(red: 88.0 / 255.0, green: 86.0 / 255.0, blue: 214.0 / 255.0, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemPink: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemPink
-            } else {
-                return UIColor(red: 1.0, green: 45.0 / 255.0, blue: 85.0 / 255.0, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemTeal: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemTeal
-            } else {
-                return UIColor(red: 90.0 / 255.0, green: 200.0 / 255.0, blue: 250.0 / 255.0, alpha: 1.0)
-            }
-        }
-    }
-
     @objc public var systemMint: UIColor {
     @objc public var systemMint: UIColor {
         get {
         get {
             return UIColor(red: 0.0 / 255.0, green: 199.0 / 255.0, blue: 190.0 / 255.0, alpha: 1.0)
             return UIColor(red: 0.0 / 255.0, green: 199.0 / 255.0, blue: 190.0 / 255.0, alpha: 1.0)
         }
         }
     }
     }
 
 
-    @objc public var systemBackground: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemBackground
-            } else {
-                return .white
-            }
-        }
-    }
-
-    @objc public var secondarySystemBackground: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .secondarySystemBackground
-            } else {
-                return UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var tertiarySystemBackground: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .tertiarySystemBackground
-            } else {
-                return UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGroupedBackground: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGroupedBackground
-            } else {
-                return UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var secondarySystemGroupedBackground: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .secondarySystemGroupedBackground
-            } else {
-                return .white
-            }
-        }
-    }
-
-    @objc public var label: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .label
-            } else {
-                return .black
-            }
-        }
-    }
-
-    @objc public var secondaryLabel: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .secondaryLabel
-            } else {
-                return UIColor(red: 0.24, green: 0.24, blue: 0.26, alpha: 0.6)
-            }
-        }
-    }
-
-    @objc public var separator: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .separator
-            } else {
-                return UIColor(red: 0.89, green: 0.89, blue: 0.89, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var opaqueSeparator: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .opaqueSeparator
-            } else {
-                return UIColor(red: 0.78, green: 0.78, blue: 0.78, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray
-            } else {
-                return UIColor(red: 0.56, green: 0.56, blue: 0.58, alpha: 1.0)
-            }
-        }
-    }
-
     @objc public var systemGray1: UIColor {
     @objc public var systemGray1: UIColor {
         get {
         get {
-            if #available(iOS 13, *) {
-                return UIColor(red: 0.60, green: 0.60, blue: 0.60, alpha: 1.0)
-            } else {
-                return UIColor(red: 0.60, green: 0.60, blue: 0.60, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray2: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray2
-            } else {
-                return UIColor(red: 0.68, green: 0.68, blue: 0.7, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray3: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray3
-            } else {
-                return UIColor(red: 0.78, green: 0.78, blue: 0.8, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray4: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray4
-            } else {
-                return UIColor(red: 0.82, green: 0.82, blue: 0.84, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray5: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray5
-            } else {
-                return UIColor(red: 0.9, green: 0.9, blue: 0.92, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemGray6: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemGray6
-            } else {
-                return UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0)
-            }
-        }
-    }
-
-    @objc public var systemFill: UIColor {
-        get {
-            if #available(iOS 13, *) {
-                return .systemFill
-            } else {
-                return UIColor(red: 120/255, green: 120/255, blue: 120/255, alpha: 1.0)
-            }
+            return UIColor(red: 0.60, green: 0.60, blue: 0.60, alpha: 1.0)
         }
         }
     }
     }
 
 
@@ -407,7 +211,7 @@ class NCBrandColor: NSObject {
 
 
         cacheImages.favorite = NCUtility.shared.loadImage(named: "star.fill", color: yellowFavorite)
         cacheImages.favorite = NCUtility.shared.loadImage(named: "star.fill", color: yellowFavorite)
         cacheImages.comment = UIImage(named: "comment")!.image(color: gray, size: 50)
         cacheImages.comment = UIImage(named: "comment")!.image(color: gray, size: 50)
-        cacheImages.livePhoto = NCUtility.shared.loadImage(named: "livephoto", color: label)
+        cacheImages.livePhoto = NCUtility.shared.loadImage(named: "livephoto", color: .label)
         cacheImages.offlineFlag = UIImage(named: "offlineFlag")!
         cacheImages.offlineFlag = UIImage(named: "offlineFlag")!
         cacheImages.local = UIImage(named: "local")!
         cacheImages.local = UIImage(named: "local")!
 
 

+ 8 - 10
iOSClient/Brand/NCBridgeSwift.h

@@ -21,28 +21,26 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 //
 
 
-//
-// App bridge swift
-//
-// change 
-// from   : Nextcloud-Swift.h
-// to     : brand-Swift.h
-//
 #if !defined(EXTENSION)
 #if !defined(EXTENSION)
 #import "Nextcloud-Swift.h"
 #import "Nextcloud-Swift.h"
 #endif
 #endif
 
 
-// Nextcloud Share
 #if defined(EXTENSION_SHARE)
 #if defined(EXTENSION_SHARE)
 #import "Share-Swift.h"
 #import "Share-Swift.h"
 #endif
 #endif
 
 
-// Nextcloud File Provider Extension
 #if defined(EXTENSION_FILE_PROVIDER_EXTENSION)
 #if defined(EXTENSION_FILE_PROVIDER_EXTENSION)
 #import "File_Provider_Extension-Swift.h"
 #import "File_Provider_Extension-Swift.h"
 #endif
 #endif
 
 
-// Nextcloud Notification Service Extension
 #if defined(EXTENSION_NOTIFICATION_SERVICE)
 #if defined(EXTENSION_NOTIFICATION_SERVICE)
 #import "Notification_Service_Extension-Swift.h"
 #import "Notification_Service_Extension-Swift.h"
 #endif
 #endif
+
+#if defined(EXTENSION_WIDGET)
+#import "Widget-Swift.h"
+#endif
+
+#if defined(EXTENSION_WIDGETDASHBOARDINTENTHANDLER)
+#import "WidgetDashboardIntentHandler-Swift.h"
+#endif

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно