diff options
author | Marino Faggiana <ios@nextcloud.com> | 2022-11-03 11:44:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-03 11:44:24 +0300 |
commit | 141fbcf2a296311ea75a3197bab5a96b2bc72d10 (patch) | |
tree | 753b0499ba8fb2abff92890f57892203a3356d80 | |
parent | 01a3750f5c20aa45e158d3f267aed77216c4885f (diff) | |
parent | 0383207caf42505bc5ed23cf4dc06dffc3753660 (diff) |
Merge pull request #2235 from nextcloud/develop4.5.4
Version 4.5.4
275 files changed, 2838 insertions, 1528 deletions
diff --git a/File Provider Extension/FileProviderData.swift b/File Provider Extension/FileProviderData.swift index a24fc3b49..9d418f7fd 100644 --- a/File Provider Extension/FileProviderData.swift +++ b/File Provider Extension/FileProviderData.swift @@ -94,7 +94,7 @@ class fileProviderData: NSObject { user = activeAccount.user userId = activeAccount.userId accountUrlBase = activeAccount.urlBase - homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) + homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) 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 @@ -118,7 +118,7 @@ class fileProviderData: NSObject { user = activeAccount.user userId = activeAccount.userId accountUrlBase = activeAccount.urlBase - homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) + homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) 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 diff --git a/File Provider Extension/FileProviderExtension+Actions.swift b/File Provider Extension/FileProviderExtension+Actions.swift index b7c01570f..ac64cb8b3 100644 --- a/File Provider Extension/FileProviderExtension+Actions.swift +++ b/File Provider Extension/FileProviderExtension+Actions.swift @@ -245,7 +245,7 @@ extension FileProviderExtension { } 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, userId: metadata.userId, account: metadata.account)! NextcloudKit.shared.setFavorite(fileName: fileNamePath, favorite: favorite) { _, error in diff --git a/File Provider Extension/FileProviderExtension+Thumbnail.swift b/File Provider Extension/FileProviderExtension+Thumbnail.swift index 87fd9875e..46d601356 100644 --- a/File Provider Extension/FileProviderExtension+Thumbnail.swift +++ b/File Provider Extension/FileProviderExtension+Thumbnail.swift @@ -42,7 +42,7 @@ extension FileProviderExtension { if metadata.hasPreview { - 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, userId: metadata.userId, account: metadata.account)! let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)! if let urlBase = metadata.urlBase.urlEncoded, diff --git a/File Provider Extension/FileProviderUtility.swift b/File Provider Extension/FileProviderUtility.swift index bfa113b26..6ba2c717c 100644 --- a/File Provider Extension/FileProviderUtility.swift +++ b/File Provider Extension/FileProviderUtility.swift @@ -61,7 +61,7 @@ class fileProviderUtility: NSObject { func getParentItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier? { - let homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: metadata.account) + let homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: metadata.urlBase, userId: metadata.userId) if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) { if directory.serverUrl == homeServerUrl { return NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue) diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 596c63aaa..e617f1c78 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -241,6 +241,9 @@ F75B0ABD244C4DBB00E58DCA /* NCFunctionCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75B0ABC244C4DBB00E58DCA /* NCFunctionCenter.swift */; }; F75C0C4823D1FAE300163CC8 /* NCRichWorkspaceCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75C0C4723D1FAE300163CC8 /* NCRichWorkspaceCommon.swift */; }; F75D19E325EFE09000D74598 /* NCTrash+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75D19E225EFE09000D74598 /* NCTrash+Menu.swift */; }; + F75DD765290ABB25002EB562 /* Intent.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F75DD769290ABB25002EB562 /* Intent.intentdefinition */; }; + F75DD766290ABB25002EB562 /* Intent.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F75DD769290ABB25002EB562 /* Intent.intentdefinition */; }; + F75DD767290ABB25002EB562 /* Intent.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F75DD769290ABB25002EB562 /* Intent.intentdefinition */; }; F75E57BD25BF0EC1002B72C2 /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = F75E57BC25BF0EC1002B72C2 /* SVGKit */; }; F75E57BF25BF0EC8002B72C2 /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = F75E57BE25BF0EC8002B72C2 /* SVGKit */; }; F75E57C125BF0ECD002B72C2 /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = F75E57C025BF0ECD002B72C2 /* SVGKit */; }; @@ -358,6 +361,10 @@ F78ACD52219046DC0088454D /* NCSectionHeaderFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78ACD51219046DC0088454D /* NCSectionHeaderFooter.swift */; }; F78ACD54219047D40088454D /* NCSectionFooter.xib in Resources */ = {isa = PBXBuildFile; fileRef = F78ACD53219047D40088454D /* NCSectionFooter.xib */; }; F78ACD58219048040088454D /* NCSectionHeaderMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F78ACD57219048040088454D /* NCSectionHeaderMenu.xib */; }; + F78D0C7F2912722100D706AB /* JGProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = F78D0C7E2912722100D706AB /* JGProgressHUD */; }; + F78D0C812912723900D706AB /* JGProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = F78D0C802912723900D706AB /* JGProgressHUD */; }; + F78D0C832912724F00D706AB /* JGProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = F78D0C822912724F00D706AB /* JGProgressHUD */; }; + F78D0C852912725600D706AB /* JGProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = F78D0C842912725600D706AB /* JGProgressHUD */; }; F78F74342163757000C2ADAD /* NCTrash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F78F74332163757000C2ADAD /* NCTrash.storyboard */; }; F78F74362163781100C2ADAD /* NCTrash.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78F74352163781100C2ADAD /* NCTrash.swift */; }; F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */; }; @@ -439,7 +446,6 @@ F7C9739228F17131002C43E2 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C9739128F17131002C43E2 /* Intents.framework */; }; F7C9739528F17131002C43E2 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C9739428F17131002C43E2 /* IntentHandler.swift */; }; F7C9739928F17131002C43E2 /* WidgetDashboardIntentHandler.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F7C9739028F17131002C43E2 /* WidgetDashboardIntentHandler.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - F7C9739D28F1733B002C43E2 /* Dashboard.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F7FABE3928D1DAD00000A325 /* Dashboard.intentdefinition */; }; F7CA212D25F1333300826ABB /* NCAccountRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CA212B25F1333200826ABB /* NCAccountRequest.swift */; }; F7CA212E25F1333300826ABB /* NCAccountRequest.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7CA212C25F1333200826ABB /* NCAccountRequest.storyboard */; }; F7CB689A2541676B0050EC94 /* NCMore.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7CB68992541676B0050EC94 /* NCMore.storyboard */; }; @@ -499,8 +505,6 @@ F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; }; F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; }; F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */; }; - F7FABE3628D1DAD00000A325 /* Dashboard.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F7FABE3928D1DAD00000A325 /* Dashboard.intentdefinition */; }; - F7FABE3728D1DAD00000A325 /* Dashboard.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = F7FABE3928D1DAD00000A325 /* Dashboard.intentdefinition */; settings = {ATTRIBUTES = (codegen, ); }; }; F7FAFD3A28BFA948000777FE /* NCNotification+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7FAFD3928BFA947000777FE /* NCNotification+Menu.swift */; }; F7FF2CB12842159500EBB7A1 /* NCSectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7FF2CB02842159500EBB7A1 /* NCSectionHeader.xib */; }; /* End PBXBuildFile section */ @@ -712,7 +716,6 @@ F710D1F42405770F00A6033D /* NCViewerPDF.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerPDF.swift; sourceTree = "<group>"; }; F710D2012405826100A6033D /* NCViewer+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCViewer+Menu.swift"; sourceTree = "<group>"; }; F710E80F1EF95C9C00DC2427 /* ImagesIntro.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ImagesIntro.xcassets; sourceTree = "<group>"; }; - F711D63328F47A66003F43C8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Dashboard.strings; sourceTree = "<group>"; }; F7134184259747BA00768D21 /* NCPushNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NCPushNotification.h; sourceTree = "<group>"; }; F7134185259747BA00768D21 /* NCPushNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NCPushNotification.m; sourceTree = "<group>"; }; F713FEFE2472764000214AF6 /* UIImage+animatedGIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+animatedGIF.h"; sourceTree = "<group>"; }; @@ -828,6 +831,7 @@ F75B923D1ECAE55E00199C96 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; }; F75C0C4723D1FAE300163CC8 /* NCRichWorkspaceCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCRichWorkspaceCommon.swift; sourceTree = "<group>"; }; F75D19E225EFE09000D74598 /* NCTrash+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCTrash+Menu.swift"; sourceTree = "<group>"; }; + F75DD768290ABB25002EB562 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intent.intentdefinition; sourceTree = "<group>"; }; F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; }; F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; }; F760329D252F0F8E0015A421 /* NCTransferCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NCTransferCell.swift; path = iOSClient/Transfers/NCTransferCell.swift; sourceTree = SOURCE_ROOT; }; @@ -1010,6 +1014,50 @@ F7BB04851FD58ACB00BBFD2A /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/Localizable.strings"; sourceTree = "<group>"; }; F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewCertificateDetails.storyboard; sourceTree = "<group>"; }; F7BC287F26663F85004D46C5 /* NCViewCertificateDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewCertificateDetails.swift; sourceTree = "<group>"; }; + F7BE7C25290AC8C9002ABB61 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C27290ADEFD002ABB61 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C29290ADEFD002ABB61 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C2B290ADEFE002ABB61 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C2D290ADEFF002ABB61 /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C2F290ADF00002ABB61 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C31290ADF00002ABB61 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C33290ADF01002ABB61 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C35290ADF03002ABB61 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C37290ADF03002ABB61 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C39290ADF04002ABB61 /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-UY"; path = "es-UY.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C3B290ADF04002ABB61 /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PR"; path = "es-PR.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C3D290ADF05002ABB61 /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PE"; path = "es-PE.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C3F290ADF06002ABB61 /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PY"; path = "es-PY.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C41290ADF06002ABB61 /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PA"; path = "es-PA.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C43290ADF06002ABB61 /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-NI"; path = "es-NI.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C45290ADF07002ABB61 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C47290ADF07002ABB61 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C49290ADF08002ABB61 /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-HN"; path = "es-HN.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C4B290ADF09002ABB61 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C4D290ADF0A002ABB61 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C4F290ADF0A002ABB61 /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sk-SK"; path = "sk-SK.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C51290ADF0B002ABB61 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C53290ADF0B002ABB61 /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CL"; path = "es-CL.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C55290ADF0C002ABB61 /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CO"; path = "es-CO.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C57290ADF0C002ABB61 /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CR"; path = "es-CR.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C59290ADF0D002ABB61 /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-DO"; path = "es-DO.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C5B290ADF0D002ABB61 /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-EC"; path = "es-EC.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C5D290ADF0E002ABB61 /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-SV"; path = "es-SV.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C5F290ADF0E002ABB61 /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-GT"; path = "es-GT.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C61290ADF10002ABB61 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C63290ADF10002ABB61 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C65290ADF10002ABB61 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C67290ADF11002ABB61 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C69290ADF11002ABB61 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C6B290ADF12002ABB61 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C6D290ADF12002ABB61 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C6F290ADF13002ABB61 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C71290ADF13002ABB61 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C73290ADF14002ABB61 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C75290ADF14002ABB61 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nb-NO"; path = "nb-NO.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C77290ADF15002ABB61 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Intent.strings; sourceTree = "<group>"; }; + F7BE7C79290ADF16002ABB61 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Intent.strings"; sourceTree = "<group>"; }; + F7BE7C7B290ADF16002ABB61 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Intent.strings"; sourceTree = "<group>"; }; F7C1EEA425053A9C00866ACC /* NCDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCDataSource.swift; sourceTree = "<group>"; }; F7C40BE221998C050004137E /* PDFGenerator.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PDFGenerator.framework; path = Carthage/Build/iOS/PDFGenerator.framework; sourceTree = "<group>"; }; F7C40BE421998D5A0004137E /* MGSwipeTableCell.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MGSwipeTableCell.framework; path = Carthage/Build/iOS/MGSwipeTableCell.framework; sourceTree = "<group>"; }; @@ -1036,49 +1084,6 @@ F7CB689F254169530050EC94 /* NCSettings.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCSettings.storyboard; sourceTree = "<group>"; }; F7CBC31B24F78E79004D3812 /* NCSortMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSortMenu.swift; sourceTree = "<group>"; }; F7CC04E61F5AD50D00378CEF /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; }; - F7CD836428F6B4DA00E93B11 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD836628F6B4DA00E93B11 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD836828F6B4DB00E93B11 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD836A28F6B4DC00E93B11 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD836C28F6B4DC00E93B11 /* cs-CZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "cs-CZ"; path = "cs-CZ.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD836E28F6B4DD00E93B11 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837028F6B4E100E93B11 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837228F6B4E300E93B11 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD837428F6B4E700E93B11 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837628F6B4E800E93B11 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837828F6B4EA00E93B11 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD837A28F6B4EC00E93B11 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837C28F6B4ED00E93B11 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD837E28F6B4EE00E93B11 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD838028F6B4EF00E93B11 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD838228F6B4F000E93B11 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD838428F6B4F200E93B11 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD838628F6B4F300E93B11 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "nb-NO"; path = "nb-NO.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD838828F6B4F400E93B11 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD838A28F6B4F800E93B11 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD838C28F6B4F900E93B11 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD838E28F6B4F900E93B11 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD839028F6B4FA00E93B11 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD839228F6B4FB00E93B11 /* sk-SK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sk-SK"; path = "sk-SK.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD839428F6B4FC00E93B11 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD839628F6B4FC00E93B11 /* es-CL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CL"; path = "es-CL.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD839828F6B4FD00E93B11 /* es-CO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CO"; path = "es-CO.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD839A28F6B4FE00E93B11 /* es-CR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-CR"; path = "es-CR.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD839C28F6B4FF00E93B11 /* es-DO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-DO"; path = "es-DO.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD839E28F6B4FF00E93B11 /* es-EC */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-EC"; path = "es-EC.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83A028F6B50000E93B11 /* es-SV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-SV"; path = "es-SV.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83A228F6B50100E93B11 /* es-GT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-GT"; path = "es-GT.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83A428F6B50100E93B11 /* es-HN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-HN"; path = "es-HN.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83A628F6B50200E93B11 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83A828F6B50300E93B11 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83AA28F6B50400E93B11 /* es-NI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-NI"; path = "es-NI.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83AC28F6B50400E93B11 /* es-PA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PA"; path = "es-PA.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83AE28F6B50500E93B11 /* es-PY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PY"; path = "es-PY.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83B028F6B50600E93B11 /* es-PE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PE"; path = "es-PE.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83B228F6B50700E93B11 /* es-PR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-PR"; path = "es-PR.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83B428F6B50700E93B11 /* es-UY */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-UY"; path = "es-UY.lproj/Dashboard.strings"; sourceTree = "<group>"; }; - F7CD83B628F6B50800E93B11 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Dashboard.strings; sourceTree = "<group>"; }; - F7CD83B828F6B50800E93B11 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Dashboard.strings; sourceTree = "<group>"; }; F7CE8AFA1DC1F8D8009CAE48 /* Nextcloud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nextcloud.app; sourceTree = BUILT_PRODUCTS_DIR; }; F7CE8AFB1DC1F8D8009CAE48 /* Share.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Share.appex; sourceTree = BUILT_PRODUCTS_DIR; }; F7D0F33D264144FC0097D4A3 /* Background.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Background.xcassets; sourceTree = "<group>"; }; @@ -1124,7 +1129,6 @@ F7F67BB81A24D27800EE80DA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndMetadata.swift; sourceTree = "<group>"; }; F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewer.swift; sourceTree = "<group>"; }; - F7FABE3828D1DAD00000A325 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Dashboard.intentdefinition; sourceTree = "<group>"; }; F7FAFD3928BFA947000777FE /* NCNotification+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCNotification+Menu.swift"; sourceTree = "<group>"; }; F7FC7D551DC1F93800BB2C6A /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; F7FF2CB02842159500EBB7A1 /* NCSectionHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCSectionHeader.xib; sourceTree = "<group>"; }; @@ -1139,6 +1143,7 @@ F710FC88277B7D3F00AA9FBF /* RealmSwift in Frameworks */, F710FC86277B7D3F00AA9FBF /* Realm in Frameworks */, F7EBCDD3277B821700A4EF67 /* UICKeyChainStore in Frameworks */, + F78D0C852912725600D706AB /* JGProgressHUD in Frameworks */, F75E57C325BF0ED2002B72C2 /* SVGKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1177,6 +1182,7 @@ F7346E2728B0FFF2006CE2D2 /* Realm in Frameworks */, F7346E2928B0FFF2006CE2D2 /* RealmSwift in Frameworks */, F783030D28B4C59A00B84583 /* SwiftEntryKit in Frameworks */, + F78D0C832912724F00D706AB /* JGProgressHUD in Frameworks */, F7346E1228B0EF5B006CE2D2 /* WidgetKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1186,6 +1192,7 @@ buildActionMask = 2147483647; files = ( F7EBCDD1277B820D00A4EF67 /* UICKeyChainStore in Frameworks */, + F78D0C7F2912722100D706AB /* JGProgressHUD in Frameworks */, F75E57C125BF0ECD002B72C2 /* SVGKit in Frameworks */, F73ADD2426554FE20069EA0D /* SwiftEntryKit in Frameworks */, F710FC82277B7D3500AA9FBF /* Realm in Frameworks */, @@ -1232,6 +1239,7 @@ F7A8D72828F17728008BBE1C /* RealmSwift in Frameworks */, F7A8D72E28F17764008BBE1C /* UICKeyChainStore in Frameworks */, F7A8D72C28F17742008BBE1C /* SwiftEntryKit in Frameworks */, + F78D0C812912723900D706AB /* JGProgressHUD in Frameworks */, F7A8D72628F17728008BBE1C /* Realm in Frameworks */, F7A8D72428F1771B008BBE1C /* NextcloudKit in Frameworks */, F7C9739228F17131002C43E2 /* Intents.framework in Frameworks */, @@ -1358,14 +1366,6 @@ path = "Rename file"; sourceTree = "<group>"; }; - F70EA92828D4B97C00920635 /* Intent */ = { - isa = PBXGroup; - children = ( - F7FABE3928D1DAD00000A325 /* Dashboard.intentdefinition */, - ); - path = Intent; - sourceTree = "<group>"; - }; F710E80C1EF95C9C00DC2427 /* Intro */ = { isa = PBXGroup; children = ( @@ -1466,7 +1466,6 @@ F72EA95528B7BAD100C88F0C /* Dashboard */ = { isa = PBXGroup; children = ( - F70EA92828D4B97C00920635 /* Intent */, F7E0710028B13BB00001B882 /* DashboardData.swift */, F72EA95128B7BA2A00C88F0C /* DashboardWidgetProvider.swift */, F72A17D728B221E300F3F159 /* DashboardWidgetView.swift */, @@ -1492,6 +1491,7 @@ F72EA95628B7BAE700C88F0C /* Files */, F76DEE9A28F808BC0041B1C9 /* Lockscreen */, F77ED59628C9CEEE00E24ED0 /* Toolbar */, + F75DD764290AB369002EB562 /* Intent */, F7346E2028B0FA3A006CE2D2 /* Widget-Brinding-header.h */, F7346E1528B0EF5C006CE2D2 /* Widget.swift */, ); @@ -1551,6 +1551,14 @@ path = ScanDocument; sourceTree = "<group>"; }; + F75DD764290AB369002EB562 /* Intent */ = { + isa = PBXGroup; + children = ( + F75DD769290ABB25002EB562 /* Intent.intentdefinition */, + ); + path = Intent; + sourceTree = "<group>"; + }; F7603298252F0E550015A421 /* Collection Common */ = { isa = PBXGroup; children = ( @@ -2245,6 +2253,7 @@ F710FC87277B7D3F00AA9FBF /* RealmSwift */, F7EBCDD2277B821700A4EF67 /* UICKeyChainStore */, F72AD71028C24BBB006CB92D /* NextcloudKit */, + F78D0C842912725600D706AB /* JGProgressHUD */, ); productName = "Notification Service Extension"; productReference = 2C33C47F23E2C475005F963B /* Notification Service Extension.appex */; @@ -2315,6 +2324,7 @@ F783030428B4C50600B84583 /* SVGKit */, F783030C28B4C59A00B84583 /* SwiftEntryKit */, F783034328B5142B00B84583 /* NextcloudKit */, + F78D0C822912724F00D706AB /* JGProgressHUD */, ); productName = DashboardWidgetExtension; productReference = F7346E1028B0EF5B006CE2D2 /* Widget.appex */; @@ -2340,6 +2350,7 @@ F710FC83277B7D3500AA9FBF /* RealmSwift */, F7EBCDD0277B820D00A4EF67 /* UICKeyChainStore */, F72AD71228C24BCC006CB92D /* NextcloudKit */, + F78D0C7E2912722100D706AB /* JGProgressHUD */, ); productName = "File Provider Extension"; productReference = F771E3D020E2392D00AFB62D /* File Provider Extension.appex */; @@ -2411,6 +2422,7 @@ F7A8D72928F17733008BBE1C /* SVGKit */, F7A8D72B28F17742008BBE1C /* SwiftEntryKit */, F7A8D72D28F17764008BBE1C /* UICKeyChainStore */, + F78D0C802912723900D706AB /* JGProgressHUD */, ); productName = WidgetDashboardIntentHandler; productReference = F7C9739028F17131002C43E2 /* WidgetDashboardIntentHandler.appex */; @@ -2845,7 +2857,6 @@ F72EA95A28B7BD0D00C88F0C /* FilesWidgetView.swift in Sources */, F78302FE28B4C44700B84583 /* NCBrand.swift in Sources */, F793E5A028B7651B005E4B02 /* NCViewCertificateDetails.swift in Sources */, - F7FABE3728D1DAD00000A325 /* Dashboard.intentdefinition in Sources */, F793E59F28B764F6005E4B02 /* NCContentPresenter.swift in Sources */, F76DEE9828F808AF0041B1C9 /* LockscreenWidgetProvider.swift in Sources */, F78302FA28B4C3EA00B84583 /* NCManageDatabase+Metadata.swift in Sources */, @@ -2864,6 +2875,7 @@ F72EA95828B7BC4F00C88F0C /* FilesData.swift in Sources */, F793E59E28B763C2005E4B02 /* NCAskAuthorization.swift in Sources */, F78302FF28B4C45000B84583 /* NCUtilityFileSystem.swift in Sources */, + F75DD766290ABB25002EB562 /* Intent.intentdefinition in Sources */, F78302F628B4C3C500B84583 /* NCDatabase.swift in Sources */, F7D68FCD28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift in Sources */, F783030128B4C49700B84583 /* UIImage+Extensions.swift in Sources */, @@ -2993,6 +3005,7 @@ F7239871253D86B600257F49 /* NCEmptyDataSet.swift in Sources */, AFCE353327E4ED1900FEA6C2 /* UIToolbar+Extension.swift in Sources */, 8491B1CD273BBA82001C8C5B /* UIViewController+Menu.swift in Sources */, + F75DD765290ABB25002EB562 /* Intent.intentdefinition in Sources */, F702F2F725EE5CED008F8E80 /* NCLogin.swift in Sources */, F7E98C1627E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */, F7F4F11227ECDC52008676F9 /* UIFont+Extension.swift in Sources */, @@ -3069,7 +3082,6 @@ F7F4F11027ECDC4A008676F9 /* UIDevice+Extensions.swift in Sources */, F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */, F70D8D8124A4A9BF000A5756 /* NCNetworkingProcessUpload.swift in Sources */, - F7FABE3628D1DAD00000A325 /* Dashboard.intentdefinition in Sources */, F7D96FCC246ED7E200536D73 /* NCNetworkingCheckRemoteUser.swift in Sources */, F7E4D9C422ED929B003675FD /* NCShareCommentsCell.swift in Sources */, F717402E24F699A5000C87D5 /* NCFavorite.swift in Sources */, @@ -3090,6 +3102,7 @@ F7C9739528F17131002C43E2 /* IntentHandler.swift in Sources */, F7A8D73D28F181D3008BBE1C /* NCUtilityFileSystem.swift in Sources */, F7A8D74528F1828E008BBE1C /* CCUtility.m in Sources */, + F75DD767290ABB25002EB562 /* Intent.intentdefinition in Sources */, F7A8D73F28F181EF008BBE1C /* NCGlobal.swift in Sources */, F7A8D74328F1826F008BBE1C /* String+Extensions.swift in Sources */, F7A8D73728F17E1E008BBE1C /* NCManageDatabase+Account.swift in Sources */, @@ -3097,7 +3110,6 @@ F7A8D73C28F181BC008BBE1C /* NCBrand.swift in Sources */, F7A8D74228F18261008BBE1C /* NCUtility.swift in Sources */, F7A8D73A28F17E28008BBE1C /* NCManageDatabase+Video.swift in Sources */, - F7C9739D28F1733B002C43E2 /* Dashboard.intentdefinition in Sources */, F7A8D73828F17E21008BBE1C /* NCManageDatabase+DashboardWidget.swift in Sources */, F7A8D73928F17E25008BBE1C /* NCManageDatabase+Metadata.swift in Sources */, F7A8D74128F18254008BBE1C /* UIColor+Extensions.swift in Sources */, @@ -3196,6 +3208,58 @@ path = "Supporting Files"; sourceTree = "<group>"; }; + F75DD769290ABB25002EB562 /* Intent.intentdefinition */ = { + isa = PBXVariantGroup; + children = ( + F75DD768290ABB25002EB562 /* Base */, + F7BE7C25290AC8C9002ABB61 /* en */, + F7BE7C27290ADEFD002ABB61 /* eu */, + F7BE7C29290ADEFD002ABB61 /* ca */, + F7BE7C2B290ADEFE002ABB61 /* zh-Hans */, + F7BE7C2D290ADEFF002ABB61 /* cs-CZ */, + F7BE7C2F290ADF00002ABB61 /* zh-Hant-TW */, + F7BE7C31290ADF00002ABB61 /* nl */, + F7BE7C33290ADF01002ABB61 /* da */, + F7BE7C35290ADF03002ABB61 /* tr */, + F7BE7C37290ADF03002ABB61 /* sv */, + F7BE7C39290ADF04002ABB61 /* es-UY */, + F7BE7C3B290ADF04002ABB61 /* es-PR */, + F7BE7C3D290ADF05002ABB61 /* es-PE */, + F7BE7C3F290ADF06002ABB61 /* es-PY */, + F7BE7C41290ADF06002ABB61 /* es-PA */, + F7BE7C43290ADF06002ABB61 /* es-NI */, + F7BE7C45290ADF07002ABB61 /* es-MX */, + F7BE7C47290ADF07002ABB61 /* es-419 */, + F7BE7C49290ADF08002ABB61 /* es-HN */, + F7BE7C4B290ADF09002ABB61 /* ru */, + F7BE7C4D290ADF0A002ABB61 /* sr */, + F7BE7C4F290ADF0A002ABB61 /* sk-SK */, + F7BE7C51290ADF0B002ABB61 /* es */, + F7BE7C53290ADF0B002ABB61 /* es-CL */, + F7BE7C55290ADF0C002ABB61 /* es-CO */, + F7BE7C57290ADF0C002ABB61 /* es-CR */, + F7BE7C59290ADF0D002ABB61 /* es-DO */, + F7BE7C5B290ADF0D002ABB61 /* es-EC */, + F7BE7C5D290ADF0E002ABB61 /* es-SV */, + F7BE7C5F290ADF0E002ABB61 /* es-GT */, + F7BE7C61290ADF10002ABB61 /* en-GB */, + F7BE7C63290ADF10002ABB61 /* fr */, + F7BE7C65290ADF10002ABB61 /* gl */, + F7BE7C67290ADF11002ABB61 /* ka-GE */, + F7BE7C69290ADF11002ABB61 /* de */, + F7BE7C6B290ADF12002ABB61 /* hu */, + F7BE7C6D290ADF12002ABB61 /* is */, + F7BE7C6F290ADF13002ABB61 /* it */, + F7BE7C71290ADF13002ABB61 /* ja-JP */, + F7BE7C73290ADF14002ABB61 /* ko */, + F7BE7C75290ADF14002ABB61 /* nb-NO */, + F7BE7C77290ADF15002ABB61 /* pl */, + F7BE7C79290ADF16002ABB61 /* pt-BR */, + F7BE7C7B290ADF16002ABB61 /* pt-PT */, + ); + name = Intent.intentdefinition; + sourceTree = "<group>"; + }; F7E70DE91A24DE4100E1B66A /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -3248,58 +3312,6 @@ path = "Supporting Files"; sourceTree = "<group>"; }; - F7FABE3928D1DAD00000A325 /* Dashboard.intentdefinition */ = { - isa = PBXVariantGroup; - children = ( - F7FABE3828D1DAD00000A325 /* Base */, - F711D63328F47A66003F43C8 /* en */, - F7CD836428F6B4DA00E93B11 /* eu */, - F7CD836628F6B4DA00E93B11 /* ca */, - F7CD836828F6B4DB00E93B11 /* zh-Hans */, - F7CD836A28F6B4DC00E93B11 /* zh-Hant-TW */, - F7CD836C28F6B4DC00E93B11 /* cs-CZ */, - F7CD836E28F6B4DD00E93B11 /* da */, - F7CD837028F6B4E100E93B11 /* nl */, - F7CD837228F6B4E300E93B11 /* en-GB */, - F7CD837428F6B4E700E93B11 /* fr */, - F7CD837628F6B4E800E93B11 /* gl */, - F7CD837828F6B4EA00E93B11 /* ka-GE */, - F7CD837A28F6B4EC00E93B11 /* de */, - F7CD837C28F6B4ED00E93B11 /* hu */, - F7CD837E28F6B4EE00E93B11 /* is */, - F7CD838028F6B4EF00E93B11 /* it */, - F7CD838228F6B4F000E93B11 /* ja-JP */, - F7CD838428F6B4F200E93B11 /* ko */, - F7CD838628F6B4F300E93B11 /* nb-NO */, - F7CD838828F6B4F400E93B11 /* pl */, - F7CD838A28F6B4F800E93B11 /* pt-BR */, - F7CD838C28F6B4F900E93B11 /* pt-PT */, - F7CD838E28F6B4F900E93B11 /* ru */, - F7CD839028F6B4FA00E93B11 /* sr */, - F7CD839228F6B4FB00E93B11 /* sk-SK */, - F7CD839428F6B4FC00E93B11 /* es */, - F7CD839628F6B4FC00E93B11 /* es-CL */, - F7CD839828F6B4FD00E93B11 /* es-CO */, - F7CD839A28F6B4FE00E93B11 /* es-CR */, - F7CD839C28F6B4FF00E93B11 /* es-DO */, - F7CD839E28F6B4FF00E93B11 /* es-EC */, - F7CD83A028F6B50000E93B11 /* es-SV */, - F7CD83A228F6B50100E93B11 /* es-GT */, - F7CD83A428F6B50100E93B11 /* es-HN */, - F7CD83A628F6B50200E93B11 /* es-419 */, - F7CD83A828F6B50300E93B11 /* es-MX */, - F7CD83AA28F6B50400E93B11 /* es-NI */, - F7CD83AC28F6B50400E93B11 /* es-PA */, - F7CD83AE28F6B50500E93B11 /* es-PY */, - F7CD83B028F6B50600E93B11 /* es-PE */, - F7CD83B228F6B50700E93B11 /* es-PR */, - F7CD83B428F6B50700E93B11 /* es-UY */, - F7CD83B628F6B50800E93B11 /* sv */, - F7CD83B828F6B50800E93B11 /* tr */, - ); - name = Dashboard.intentdefinition; - sourceTree = "<group>"; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -3607,7 +3619,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_TEAM = NKUJUXUJ3B; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -3631,7 +3643,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.5.3; + MARKETING_VERSION = 4.5.4; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; SDKROOT = iphoneos; @@ -3670,7 +3682,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_TEAM = NKUJUXUJ3B; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -3692,7 +3704,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 4.5.3; + MARKETING_VERSION = 4.5.4; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; SDKROOT = iphoneos; @@ -3900,7 +3912,7 @@ repositoryURL = "https://github.com/nextcloud/NextcloudKit"; requirement = { kind = exactVersion; - version = 1.1.0; + version = 1.2.0; }; }; F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = { @@ -4125,6 +4137,26 @@ package = F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */; productName = MarkdownKit; }; + F78D0C7E2912722100D706AB /* JGProgressHUD */ = { + isa = XCSwiftPackageProductDependency; + package = F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */; + productName = JGProgressHUD; + }; + F78D0C802912723900D706AB /* JGProgressHUD */ = { + isa = XCSwiftPackageProductDependency; + package = F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */; + productName = JGProgressHUD; + }; + F78D0C822912724F00D706AB /* JGProgressHUD */ = { + isa = XCSwiftPackageProductDependency; + package = F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */; + productName = JGProgressHUD; + }; + F78D0C842912725600D706AB /* JGProgressHUD */ = { + isa = XCSwiftPackageProductDependency; + package = F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */; + productName = JGProgressHUD; + }; F7A8D72328F1771B008BBE1C /* NextcloudKit */ = { isa = XCSwiftPackageProductDependency; package = F783034028B511D200B84583 /* XCRemoteSwiftPackageReference "NextcloudKit" */; diff --git a/Share/NCShareExtension+NCDelegate.swift b/Share/NCShareExtension+NCDelegate.swift index 3fd9af725..5b4f0d518 100644 --- a/Share/NCShareExtension+NCDelegate.swift +++ b/Share/NCShareExtension+NCDelegate.swift @@ -93,9 +93,9 @@ extension NCShareExtension: NCEmptyDataSetDelegate, NCAccountRequestDelegate { // get auto upload folder autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName() - autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, account: activeAccount.account) + autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, userId: activeAccount.userId, account: activeAccount.account) - serverUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) + serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) layoutForView = NCUtility.shared.getLayoutForView(key: keyLayout, serverUrl: serverUrl) diff --git a/Share/NCShareExtension.swift b/Share/NCShareExtension.swift index 4fb28f661..f83b3a911 100644 --- a/Share/NCShareExtension.swift +++ b/Share/NCShareExtension.swift @@ -218,7 +218,7 @@ class NCShareExtension: UIViewController { self.reloadDatasource(withLoadFolder: true) var navigationTitle = (self.serverUrl as NSString).lastPathComponent - if NCUtilityFileSystem.shared.getHomeServer(account: self.activeAccount.account) == self.serverUrl { + if NCUtilityFileSystem.shared.getHomeServer(urlBase: self.activeAccount.urlBase, userId: self.activeAccount.userId) == self.serverUrl { navigationTitle = NCBrandOptions.shared.brand } self.setNavigationBar(navigationTitle: navigationTitle) @@ -229,7 +229,7 @@ class NCShareExtension: UIViewController { let profileButton = UIButton(type: .custom) profileButton.setImage(image, for: .normal) - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) { var title = " " if let userAlias = activeAccount?.alias, !userAlias.isEmpty { @@ -250,7 +250,7 @@ class NCShareExtension: UIViewController { } } var navItems = [UIBarButtonItem(customView: profileButton)] - if serverUrl != NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) { + if serverUrl != NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) { let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) space.width = 20 navItems.append(contentsOf: [UIBarButtonItem(customView: backButton), space]) @@ -329,7 +329,7 @@ extension NCShareExtension { conflict.serverUrl = self.serverUrl conflict.metadatasUploadInConflict = conflicts conflict.delegate = self - conflict.isE2EE = CCUtility.isFolderEncrypted(self.serverUrl, e2eEncrypted: false, account: activeAccount.account, urlBase: activeAccount.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(self.serverUrl, e2eEncrypted: false, account: activeAccount.account, urlBase: activeAccount.urlBase, userId: activeAccount.userId) self.present(conflict, animated: true, completion: nil) } else { upload() @@ -345,7 +345,7 @@ extension NCShareExtension { metadata.iconName = results.iconName metadata.classFile = results.classFile // E2EE - metadata.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + metadata.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: activeAccount.userId) // CHUNCK metadata.chunk = chunckSize != 0 && metadata.size > chunckSize diff --git a/Widget/Dashboard/DashboardData.swift b/Widget/Dashboard/DashboardData.swift index 915b80454..5a47f9bc2 100644 --- a/Widget/Dashboard/DashboardData.swift +++ b/Widget/Dashboard/DashboardData.swift @@ -22,6 +22,7 @@ // import WidgetKit +import Intents import NextcloudKit import RealmSwift import SVGKit @@ -32,6 +33,7 @@ struct DashboardDataEntry: TimelineEntry { let dashboard: tableDashboardWidget? let buttons: [tableDashboardWidgetButton]? let isPlaceholder: Bool + let isEmpty: Bool let titleImage: UIImage let title: String let footerImage: String @@ -79,26 +81,34 @@ func getDashboardItems(displaySize: CGSize, withButton: Bool) -> Int { } } -func getDashboardDataEntry(intent: Applications?, isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: DashboardDataEntry) -> Void) { +func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: DashboardDataEntry) -> Void) { let dashboardItems = getDashboardItems(displaySize: displaySize, withButton: false) let datasPlaceholder = Array(dashboardDatasTest[0...dashboardItems - 1]) + var account: tableAccount? 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")) + return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, 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: ""))) + let accountIdentifier: String = configuration?.accounts?.identifier ?? "active" + if accountIdentifier == "active" { + account = NCManageDatabase.shared.getActiveAccount() + } else { + account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier)) + } + + guard let account = account else { + return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, 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 id: String = configuration?.applications?.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: ""))) + return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_widget_available_nc25_", comment: ""))) } // NETWORKING @@ -142,7 +152,7 @@ func getDashboardDataEntry(intent: Applications?, isPreview: Bool, displaySize: } let titleImage = imagetmp - NextcloudKit.shared.getDashboardWidgetsApplication(id, options: options) { account, results, data, error in + NextcloudKit.shared.getDashboardWidgetsApplication(id, options: options) { _, results, data, error in Task { var datas = [DashboardData]() @@ -222,12 +232,13 @@ func getDashboardDataEntry(intent: Applications?, isPreview: Bool, displaySize: buttons = tableButton.filter(({ $0.type != "more" })) } + let alias = (account.alias.isEmpty) ? "" : (" (" + account.alias + ")") + let footerText = "Dashboard " + NSLocalizedString("_of_", comment: "") + " " + account.displayName + alias + 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: ""))) + completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: tableDashboard, buttons: buttons, isPlaceholder: true, isEmpty: false, titleImage: titleImage, title: title, footerImage: "xmark.icloud", footerText: error.errorDescription)) } 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")) + completion(DashboardDataEntry(date: Date(), datas: datas, dashboard: tableDashboard, buttons: buttons, isPlaceholder: false, isEmpty: datas.isEmpty, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: footerText)) } } } diff --git a/Widget/Dashboard/DashboardWidgetProvider.swift b/Widget/Dashboard/DashboardWidgetProvider.swift index d7ccf1d9d..acfcb13c6 100644 --- a/Widget/Dashboard/DashboardWidgetProvider.swift +++ b/Widget/Dashboard/DashboardWidgetProvider.swift @@ -22,8 +22,8 @@ // import WidgetKit -import SwiftUI import Intents +import SwiftUI struct DashboardWidgetProvider: IntentTimelineProvider { @@ -35,17 +35,17 @@ struct DashboardWidgetProvider: IntentTimelineProvider { 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") + return Entry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, 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 + getDashboardDataEntry(configuration: configuration, 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 + getDashboardDataEntry(configuration: configuration, isPreview: context.isPreview, displaySize: context.displaySize) { entry in let timeLine = Timeline(entries: [entry], policy: .atEnd) completion(timeLine) } diff --git a/Widget/Dashboard/DashboardWidgetView.swift b/Widget/Dashboard/DashboardWidgetView.swift index 8a6348155..ff2c9c1f5 100644 --- a/Widget/Dashboard/DashboardWidgetView.swift +++ b/Widget/Dashboard/DashboardWidgetView.swift @@ -32,10 +32,25 @@ struct DashboardWidgetView: View { GeometryReader { geo in + if entry.isEmpty { + VStack(alignment: .center) { + Image(systemName: "checkmark") + .resizable() + .scaledToFit() + .frame(width: 50, height: 50) + Text(NSLocalizedString("_no_items_", comment: "")) + .font(.system(size: 25)) + .padding() + Text(NSLocalizedString("_check_back_later_", comment: "")) + .font(.system(size: 15)) + } + .frame(width: geo.size.width, height: geo.size.height) + } + ZStack(alignment: .topLeading) { HStack() { - + Image(uiImage: entry.titleImage) .renderingMode(.template) .resizable() @@ -51,88 +66,91 @@ struct DashboardWidgetView: View { } .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 let color = element.imageColor { - Image(uiImage: element.icon) - .renderingMode(.template) - .resizable() - .frame(width: 20, height: 20) - .foregroundColor(Color(color)) - } else if element.template { - if entry.dashboard?.itemIconsRound ?? false { + + if !entry.isEmpty { + + 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 let color = element.imageColor { Image(uiImage: element.icon) .renderingMode(.template) .resizable() - .scaledToFill() .frame(width: 20, height: 20) - .foregroundColor(.white) - .padding(8) - .background(Color(.systemGray4)) - .clipShape(Circle()) + .foregroundColor(Color(color)) + } 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 { - Image(uiImage: element.icon) - .renderingMode(.template) - .resizable() - .scaledToFill() - .frame(width: 25, height: 25) - .clipped() - .cornerRadius(5) + 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) + } } - } 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) { + VStack(alignment: .leading, spacing: 2) { - Text(element.title) - .font(.system(size: 12)) - .fontWeight(.regular) + Text(element.title) + .font(.system(size: 12)) + .fontWeight(.regular) - Text(element.subTitle) - .font(.system(size: CGFloat(10))) - .foregroundColor(subTitleColor) + Text(element.subTitle) + .font(.system(size: CGFloat(10))) + .foregroundColor(subTitleColor) + } + Spacer() } - Spacer() + .padding(.leading, 10) + .frame(height: 50) } - .padding(.leading, 10) - .frame(height: 50) + Divider() + .padding(.leading, 54) } - Divider() - .padding(.leading, 54) } } + .padding(.top, 35) + .redacted(reason: entry.isPlaceholder ? .placeholder : []) } - .padding(.top, 35) - .redacted(reason: entry.isPlaceholder ? .placeholder : []) if let buttons = entry.buttons, !buttons.isEmpty, !entry.isPlaceholder { @@ -167,10 +185,11 @@ struct DashboardWidgetView: View { Text(entry.footerText) .font(.caption2) - .padding(.trailing, 13.0) + .lineLimit(1) .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand)) } - .frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing) + .padding(.horizontal, 15.0) + .frame(maxWidth: geo.size.width, maxHeight: geo.size.height - 2, alignment: .bottomTrailing) } } } @@ -181,7 +200,7 @@ struct DashboardWidget_Previews: PreviewProvider { 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") + let entry = DashboardDataEntry(date: Date(), datas: datas, dashboard: nil, buttons: nil, isPlaceholder: false, isEmpty: true, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: "Nextcloud widget") DashboardWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge)) } } diff --git a/Widget/Dashboard/Intent/Base.lproj/Dashboard.intentdefinition b/Widget/Dashboard/Intent/Base.lproj/Dashboard.intentdefinition deleted file mode 100644 index cc728fd06..000000000 --- a/Widget/Dashboard/Intent/Base.lproj/Dashboard.intentdefinition +++ /dev/null @@ -1,169 +0,0 @@ -<?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> diff --git a/Widget/Dashboard/Intent/ca.lproj/Dashboard.strings b/Widget/Dashboard/Intent/ca.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/ca.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/cs-CZ.lproj/Dashboard.strings b/Widget/Dashboard/Intent/cs-CZ.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/cs-CZ.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/da.lproj/Dashboard.strings b/Widget/Dashboard/Intent/da.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/da.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/de.lproj/Dashboard.strings b/Widget/Dashboard/Intent/de.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/de.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/en-GB.lproj/Dashboard.strings b/Widget/Dashboard/Intent/en-GB.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/en-GB.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/en.lproj/Dashboard.strings b/Widget/Dashboard/Intent/en.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/en.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-419.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-419.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-419.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-CL.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-CL.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-CL.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-CO.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-CO.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-CO.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-CR.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-CR.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-CR.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-DO.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-DO.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-DO.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-EC.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-EC.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-EC.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-GT.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-GT.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-GT.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-HN.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-HN.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-HN.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-MX.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-MX.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-MX.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-NI.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-NI.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-NI.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-PA.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-PA.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-PA.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-PE.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-PE.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-PE.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-PR.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-PR.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-PR.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-PY.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-PY.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-PY.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-SV.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-SV.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-SV.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es-UY.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es-UY.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es-UY.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/es.lproj/Dashboard.strings b/Widget/Dashboard/Intent/es.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/es.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/eu.lproj/Dashboard.strings b/Widget/Dashboard/Intent/eu.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/eu.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/fr.lproj/Dashboard.strings b/Widget/Dashboard/Intent/fr.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/fr.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/gl.lproj/Dashboard.strings b/Widget/Dashboard/Intent/gl.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/gl.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/hu.lproj/Dashboard.strings b/Widget/Dashboard/Intent/hu.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/hu.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/is.lproj/Dashboard.strings b/Widget/Dashboard/Intent/is.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/is.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/it.lproj/Dashboard.strings b/Widget/Dashboard/Intent/it.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/it.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/ja-JP.lproj/Dashboard.strings b/Widget/Dashboard/Intent/ja-JP.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/ja-JP.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/ka-GE.lproj/Dashboard.strings b/Widget/Dashboard/Intent/ka-GE.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/ka-GE.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/ko.lproj/Dashboard.strings b/Widget/Dashboard/Intent/ko.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/ko.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/nb-NO.lproj/Dashboard.strings b/Widget/Dashboard/Intent/nb-NO.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/nb-NO.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/nl.lproj/Dashboard.strings b/Widget/Dashboard/Intent/nl.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/nl.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/pl.lproj/Dashboard.strings b/Widget/Dashboard/Intent/pl.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/pl.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/pt-BR.lproj/Dashboard.strings b/Widget/Dashboard/Intent/pt-BR.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/pt-BR.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/pt-PT.lproj/Dashboard.strings b/Widget/Dashboard/Intent/pt-PT.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/pt-PT.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/ru.lproj/Dashboard.strings b/Widget/Dashboard/Intent/ru.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/ru.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/sk-SK.lproj/Dashboard.strings b/Widget/Dashboard/Intent/sk-SK.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/sk-SK.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/sr.lproj/Dashboard.strings b/Widget/Dashboard/Intent/sr.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/sr.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/sv.lproj/Dashboard.strings b/Widget/Dashboard/Intent/sv.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/sv.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/tr.lproj/Dashboard.strings b/Widget/Dashboard/Intent/tr.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/tr.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/zh-Hans.lproj/Dashboard.strings b/Widget/Dashboard/Intent/zh-Hans.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/zh-Hans.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Dashboard/Intent/zh-Hant-TW.lproj/Dashboard.strings b/Widget/Dashboard/Intent/zh-Hant-TW.lproj/Dashboard.strings deleted file mode 100644 index a32d2733f..000000000 --- a/Widget/Dashboard/Intent/zh-Hant-TW.lproj/Dashboard.strings +++ /dev/null @@ -1,8 +0,0 @@ -"TRaTZg" = "Widget"; - -"gpCwrM" = "Dashboard"; - -"l090JH" = "Applications"; - -"tVvJ9c" = "Dashboard Widget"; - diff --git a/Widget/Files/FilesData.swift b/Widget/Files/FilesData.swift index 806b103eb..8ed5d33ce 100644 --- a/Widget/Files/FilesData.swift +++ b/Widget/Files/FilesData.swift @@ -22,12 +22,16 @@ // import WidgetKit +import Intents import NextcloudKit struct FilesDataEntry: TimelineEntry { let date: Date let datas: [FilesData] let isPlaceholder: Bool + let isEmpty: Bool + let userId: String + let url: String let tile: String let footerImage: String let footerText: String @@ -54,7 +58,7 @@ let filesDatasTest: [FilesData] = [ .init(id: "9", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!) ] -func getTitleFilesWidget() -> String { +func getTitleFilesWidget(account: tableAccount?) -> String { let hour = Calendar.current.component(.hour, from: Date()) var good = "" @@ -67,7 +71,7 @@ func getTitleFilesWidget() -> String { default: good = NSLocalizedString("_good_night_", value: "Good night", comment: "") } - if let account = NCManageDatabase.shared.getActiveAccount() { + if let account = account { return good + ", " + account.displayName } else { return good @@ -80,19 +84,25 @@ func getFilesItems(displaySize: CGSize) -> Int { return height } -func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: FilesDataEntry) -> Void) { +func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySize: CGSize, completion: @escaping (_ entry: FilesDataEntry) -> Void) { let filesItems = getFilesItems(displaySize: displaySize) let datasPlaceholder = Array(filesDatasTest[0...filesItems - 1]) - let title = getTitleFilesWidget() - - + var account: tableAccount? + if isPreview { - return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")) + return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", tile: getTitleFilesWidget(account: nil), footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")) + } + + let accountIdentifier: String = configuration?.accounts?.identifier ?? "active" + if accountIdentifier == "active" { + account = NCManageDatabase.shared.getActiveAccount() + } else { + account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier)) } - 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: ""))) + guard let account = account else { + return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", tile: getTitleFilesWidget(account: nil), footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: ""))) } @Sendable func isLive(file: NKFile, files: [NKFile]) -> Bool { @@ -128,25 +138,13 @@ func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escapi <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> @@ -204,8 +202,10 @@ func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escapi Task { var datas: [FilesData] = [] var imageRecent = UIImage(named: "file")! + let title = getTitleFilesWidget(account: account) for file in files { + guard !file.directory else { continue } guard !isLive(file: file, files: files) else { continue } @@ -227,7 +227,7 @@ func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escapi 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 fileNamePathOrFileId = CCUtility.returnFileNamePath(fromFileName: file.fileName, serverUrl: file.serverUrl, urlBase: file.urlBase, userId: file.userId, account: account.account)! let fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(file.ocId, etag: file.etag)! let fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(file.ocId, etag: file.etag)! let (_, _, imageIcon, _, _, _) = await NextcloudKit.shared.downloadPreview(fileNamePathOrFileId: fileNamePathOrFileId, fileNamePreviewLocalPath: fileNamePreviewLocalPath, widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon) @@ -236,23 +236,23 @@ func getFilesDataEntry(isPreview: Bool, displaySize: CGSize, completion: @escapi } } + // + let isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted: file.e2eEncrypted, account: account.account, urlBase: file.urlBase, userId: file.userId) + let metadata = NCManageDatabase.shared.convertNCFileToMetadata(file, isEncrypted: isEncrypted, account: account.account) + // DATA - let data = FilesData.init(id: file.ocId, image: imageRecent, title: file.fileName, subTitle: subTitle, url: url) + let data = FilesData.init(id: metadata.ocId, image: imageRecent, title: metadata.fileNameView, subTitle: subTitle, url: url) datas.append(data) if datas.count == filesItems { break} } + let alias = (account.alias.isEmpty) ? "" : (" (" + account.alias + ")") + let footerText = "Files " + NSLocalizedString("_of_", comment: "") + " " + account.displayName + alias + 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)) + completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: account.userId, url: account.urlBase, tile: title, footerImage: "xmark.icloud", footerText: error.errorDescription)) } else { - completion(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")) + completion(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: datas.isEmpty, userId: account.userId, url: account.urlBase, tile: title, footerImage: "checkmark.icloud", footerText: footerText)) } } } diff --git a/Widget/Files/FilesWidgetProvider.swift b/Widget/Files/FilesWidgetProvider.swift index 02a693280..da49127f0 100644 --- a/Widget/Files/FilesWidgetProvider.swift +++ b/Widget/Files/FilesWidgetProvider.swift @@ -22,27 +22,29 @@ // import WidgetKit +import Intents import SwiftUI -struct FilesWidgetProvider: TimelineProvider { +struct FilesWidgetProvider: IntentTimelineProvider { typealias Entry = FilesDataEntry + typealias Intent = AccountIntent 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") + let title = getTitleFilesWidget(account: nil) + return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", 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 + func getSnapshot(for configuration: AccountIntent, in context: Context, completion: @escaping (Entry) -> Void) { + getFilesDataEntry(configuration: configuration, 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 + func getTimeline(for configuration: AccountIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { + getFilesDataEntry(configuration: configuration, isPreview: context.isPreview, displaySize: context.displaySize) { entry in let timeLine = Timeline(entries: [entry], policy: .atEnd) completion(timeLine) } diff --git a/Widget/Files/FilesWidgetView.swift b/Widget/Files/FilesWidgetView.swift index 0cd1fb963..9b0c6c05a 100644 --- a/Widget/Files/FilesWidgetView.swift +++ b/Widget/Files/FilesWidgetView.swift @@ -27,11 +27,33 @@ import WidgetKit struct FilesWidgetView: View { var entry: FilesDataEntry - + var body: some View { - + + let parameterLink = "&user=\(entry.userId)&url=\(entry.url)" + let linkNoAction: URL = URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink)! : URL(string: NCGlobal.shared.widgetActionNoAction)! + let linkActionUploadAsset: URL = URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink)! : URL(string: NCGlobal.shared.widgetActionUploadAsset)! + let linkActionScanDocument: URL = URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionScanDocument)! + let linkActionTextDocument: URL = URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionTextDocument)! + let linkActionVoiceMemo: URL = URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink)! : URL(string: NCGlobal.shared.widgetActionVoiceMemo)! + GeometryReader { geo in - + + if entry.isEmpty { + VStack(alignment: .center) { + Image(systemName: "checkmark") + .resizable() + .scaledToFit() + .frame(width: 50, height: 50) + Text(NSLocalizedString("_no_items_", comment: "")) + .font(.system(size: 25)) + .padding() + Text(NSLocalizedString("_check_back_later_", comment: "")) + .font(.system(size: 15)) + } + .frame(width: geo.size.width, height: geo.size.height) + } + ZStack(alignment: .topLeading) { HStack() { @@ -45,52 +67,54 @@ struct FilesWidgetView: View { } .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)) + + if !entry.isEmpty { + 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() } - Spacer() + .padding(.leading, 10) + .frame(height: 50) } - .padding(.leading, 10) - .frame(height: 50) + Divider() + .padding(.leading, 54) } - Divider() - .padding(.leading, 54) } } + .padding(.top, 30) + .redacted(reason: entry.isPlaceholder ? .placeholder : []) } - .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: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionUploadAsset, label: { Image("addImage") .resizable() .renderingMode(.template) @@ -102,7 +126,7 @@ struct FilesWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionScanDocument, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionScanDocument, label: { Image("scan") .resizable() .renderingMode(.template) @@ -114,7 +138,7 @@ struct FilesWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionTextDocument, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionTextDocument, label: { Image("note.text") .resizable() .renderingMode(.template) @@ -126,7 +150,7 @@ struct FilesWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionVoiceMemo, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: { Image("microphone") .resizable() .renderingMode(.template) @@ -151,10 +175,11 @@ struct FilesWidgetView: View { Text(entry.footerText) .font(.caption2) - .padding(.trailing, 13.0) + .lineLimit(1) .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brand)) } - .frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing) + .padding(.horizontal, 15.0) + .frame(maxWidth: geo.size.width, maxHeight: geo.size.height - 2, alignment: .bottomTrailing) } } } @@ -163,7 +188,7 @@ struct FilesWidgetView: View { 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") + let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: true, userId: "", url: "", tile: "Good afternoon, Marino Faggiana", footerImage: "checkmark.icloud", footerText: "Nextcloud files") FilesWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge)) } } diff --git a/Widget/Intent/Base.lproj/Intent.intentdefinition b/Widget/Intent/Base.lproj/Intent.intentdefinition new file mode 100644 index 000000000..683f9259f --- /dev/null +++ b/Widget/Intent/Base.lproj/Intent.intentdefinition @@ -0,0 +1,347 @@ +<?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>4HSdD3</string> + <key>INIntentDefinitionSystemVersion</key> + <string>22A380</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>Account</string> + <key>INIntentDescriptionID</key> + <string>VfbA9C</string> + <key>INIntentEligibleForWidgets</key> + <true/> + <key>INIntentIneligibleForSuggestions</key> + <true/> + <key>INIntentLastParameterTag</key> + <integer>2</integer> + <key>INIntentName</key> + <string>Account</string> + <key>INIntentParameters</key> + <array> + <dict> + <key>INIntentParameterConfigurable</key> + <true/> + <key>INIntentParameterDisplayName</key> + <string>Account</string> + <key>INIntentParameterDisplayNameID</key> + <string>13zjVT</string> + <key>INIntentParameterDisplayPriority</key> + <integer>1</integer> + <key>INIntentParameterName</key> + <string>accounts</string> + <key>INIntentParameterObjectType</key> + <string>Accounts</string> + <key>INIntentParameterObjectTypeNamespace</key> + <string>4HSdD3</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>2</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> + </dict> + <key>INIntentTitle</key> + <string>Account</string> + <key>INIntentTitleID</key> + <string>V3exc2</string> + <key>INIntentType</key> + <string>Custom</string> + <key>INIntentVerb</key> + <string>View</string> + </dict> + <dict> + <key>INIntentCategory</key> + <string>information</string> + <key>INIntentDescription</key> + <string>Dashboard Widget</string> + <key>INIntentDescriptionID</key> + <string>ZgvlYN</string> + <key>INIntentEligibleForWidgets</key> + <true/> + <key>INIntentIneligibleForSuggestions</key> + <true/> + <key>INIntentLastParameterTag</key> + <integer>4</integer> + <key>INIntentName</key> + <string>Dashboard</string> + <key>INIntentParameters</key> + <array> + <dict> + <key>INIntentParameterConfigurable</key> + <true/> + <key>INIntentParameterDisplayName</key> + <string>Account</string> + <key>INIntentParameterDisplayNameID</key> + <string>DN8Bxl</string> + <key>INIntentParameterDisplayPriority</key> + <integer>1</integer> + <key>INIntentParameterName</key> + <string>accounts</string> + <key>INIntentParameterObjectType</key> + <string>Accounts</string> + <key>INIntentParameterObjectTypeNamespace</key> + <string>4HSdD3</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>2</integer> + <key>INIntentParameterType</key> + <string>Object</string> + </dict> + <dict> + <key>INIntentParameterConfigurable</key> + <true/> + <key>INIntentParameterDisplayName</key> + <string>Widget</string> + <key>INIntentParameterDisplayNameID</key> + <string>LIw8E9</string> + <key>INIntentParameterDisplayPriority</key> + <integer>2</integer> + <key>INIntentParameterName</key> + <string>applications</string> + <key>INIntentParameterObjectType</key> + <string>Applications</string> + <key>INIntentParameterObjectTypeNamespace</key> + <string>4HSdD3</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>4</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> + </dict> + <key>INIntentTitle</key> + <string>Dashboard</string> + <key>INIntentTitleID</key> + <string>NO1rJU</string> + <key>INIntentType</key> + <string>Custom</string> + <key>INIntentVerb</key> + <string>View</string> + </dict> + </array> + <key>INTypes</key> + <array> + <dict> + <key>INTypeDisplayName</key> + <string>Accounts</string> + <key>INTypeDisplayNameID</key> + <string>tAlZ1R</string> + <key>INTypeLastPropertyTag</key> + <integer>99</integer> + <key>INTypeName</key> + <string>Accounts</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> + <dict> + <key>INTypeDisplayName</key> + <string>Applications</string> + <key>INTypeDisplayNameID</key> + <string>CAIVXf</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> diff --git a/Widget/Intent/ca.lproj/Intent.strings b/Widget/Intent/ca.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/ca.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/cs-CZ.lproj/Intent.strings b/Widget/Intent/cs-CZ.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/cs-CZ.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/da.lproj/Intent.strings b/Widget/Intent/da.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/da.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/de.lproj/Intent.strings b/Widget/Intent/de.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/de.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/en-GB.lproj/Intent.strings b/Widget/Intent/en-GB.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/en-GB.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/en.lproj/Intent.strings b/Widget/Intent/en.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/en.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-419.lproj/Intent.strings b/Widget/Intent/es-419.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-419.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-CL.lproj/Intent.strings b/Widget/Intent/es-CL.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-CL.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-CO.lproj/Intent.strings b/Widget/Intent/es-CO.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-CO.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-CR.lproj/Intent.strings b/Widget/Intent/es-CR.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-CR.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-DO.lproj/Intent.strings b/Widget/Intent/es-DO.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-DO.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-EC.lproj/Intent.strings b/Widget/Intent/es-EC.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-EC.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-GT.lproj/Intent.strings b/Widget/Intent/es-GT.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-GT.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-HN.lproj/Intent.strings b/Widget/Intent/es-HN.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-HN.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-MX.lproj/Intent.strings b/Widget/Intent/es-MX.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-MX.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-NI.lproj/Intent.strings b/Widget/Intent/es-NI.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-NI.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-PA.lproj/Intent.strings b/Widget/Intent/es-PA.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-PA.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-PE.lproj/Intent.strings b/Widget/Intent/es-PE.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-PE.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-PR.lproj/Intent.strings b/Widget/Intent/es-PR.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-PR.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-PY.lproj/Intent.strings b/Widget/Intent/es-PY.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-PY.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-SV.lproj/Intent.strings b/Widget/Intent/es-SV.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-SV.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es-UY.lproj/Intent.strings b/Widget/Intent/es-UY.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es-UY.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/es.lproj/Intent.strings b/Widget/Intent/es.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/es.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/eu.lproj/Intent.strings b/Widget/Intent/eu.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/eu.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/fr.lproj/Intent.strings b/Widget/Intent/fr.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/fr.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/gl.lproj/Intent.strings b/Widget/Intent/gl.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/gl.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/hu.lproj/Intent.strings b/Widget/Intent/hu.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/hu.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/is.lproj/Intent.strings b/Widget/Intent/is.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/is.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/it.lproj/Intent.strings b/Widget/Intent/it.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/it.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/ja-JP.lproj/Intent.strings b/Widget/Intent/ja-JP.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/ja-JP.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/ka-GE.lproj/Intent.strings b/Widget/Intent/ka-GE.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/ka-GE.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/ko.lproj/Intent.strings b/Widget/Intent/ko.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/ko.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/nb-NO.lproj/Intent.strings b/Widget/Intent/nb-NO.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/nb-NO.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/nl.lproj/Intent.strings b/Widget/Intent/nl.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/nl.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/pl.lproj/Intent.strings b/Widget/Intent/pl.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/pl.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/pt-BR.lproj/Intent.strings b/Widget/Intent/pt-BR.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/pt-BR.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/pt-PT.lproj/Intent.strings b/Widget/Intent/pt-PT.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/pt-PT.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/ru.lproj/Intent.strings b/Widget/Intent/ru.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/ru.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/sk-SK.lproj/Intent.strings b/Widget/Intent/sk-SK.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/sk-SK.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/sr.lproj/Intent.strings b/Widget/Intent/sr.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/sr.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/sv.lproj/Intent.strings b/Widget/Intent/sv.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/sv.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/tr.lproj/Intent.strings b/Widget/Intent/tr.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/tr.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/zh-Hans.lproj/Intent.strings b/Widget/Intent/zh-Hans.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/zh-Hans.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Intent/zh-Hant-TW.lproj/Intent.strings b/Widget/Intent/zh-Hant-TW.lproj/Intent.strings new file mode 100644 index 000000000..c23b077d5 --- /dev/null +++ b/Widget/Intent/zh-Hant-TW.lproj/Intent.strings @@ -0,0 +1,30 @@ +"13zjVT" = "Account"; + +"296XDb" = "There are ${count} options matching ‘${accounts}’."; + +"Am6y6p" = "Just to confirm, you wanted ‘${applications}’?"; + +"CAIVXf" = "Applications"; + +"DN8Bxl" = "Account"; + +"LIw8E9" = "Widget"; + +"NO1rJU" = "Dashboard"; + +"ObH8NN" = "There are ${count} options matching ‘${accounts}’."; + +"TVGjNQ" = "Just to confirm, you wanted ‘${accounts}’?"; + +"V3exc2" = "Account"; + +"VfbA9C" = "Account"; + +"XjFf0X" = "There are ${count} options matching ‘${applications}’."; + +"ZgvlYN" = "Dashboard Widget"; + +"q5lvSu" = "Just to confirm, you wanted ‘${accounts}’?"; + +"tAlZ1R" = "Accounts"; + diff --git a/Widget/Lockscreen/LockscreenData.swift b/Widget/Lockscreen/LockscreenData.swift index 03ff6e224..c6c597140 100644 --- a/Widget/Lockscreen/LockscreenData.swift +++ b/Widget/Lockscreen/LockscreenData.swift @@ -32,64 +32,86 @@ struct LockscreenData: TimelineEntry { let quotaRelative: Float let quotaUsed: String let quotaTotal: String + let error: Bool } -func getLockscreenDataEntry(isPreview: Bool, completion: @escaping (_ entry: LockscreenData) -> Void) { +func getLockscreenDataEntry(configuration: AccountIntent?, isPreview: Bool, family: WidgetFamily, completion: @escaping (_ entry: LockscreenData) -> Void) { + + var account: tableAccount? + var quotaRelative: Float = 0 + let options = NKRequestOptions(timeout: 15, queue: NKCommon.shared.backgroundQueue) if isPreview { - return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "")) + return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: false)) } - guard let account = NCManageDatabase.shared.getActiveAccount() else { - return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "")) + let accountIdentifier: String = configuration?.accounts?.identifier ?? "active" + if accountIdentifier == "active" { + account = NCManageDatabase.shared.getActiveAccount() + } else { + account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier)) } - var quotaRelative: Float = 0 - if account.quotaRelative > 0 { - quotaRelative = Float(account.quotaRelative) / 100 + guard let account = account else { + return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: false)) } - 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 { + completion(LockscreenData(date: Date(), isPlaceholder: false, activity: NSLocalizedString("_widget_available_nc25_", comment: ""), link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: true)) } - 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) - // 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) + if #available(iOSApplicationExtension 16.0, *) { + if family == .accessoryCircular { + NextcloudKit.shared.getUserProfile(options: options) { _, userProfile, _, error in + if error == .success, let userProfile = userProfile, let account = NCManageDatabase.shared.setAccountUserProfile(userProfile) { + if account.quotaRelative > 0 { + quotaRelative = Float(account.quotaRelative) / 100 + } + let quotaUsed: String = CCUtility.transformedSize(account.quotaUsed) + var quotaTotal: String = "" - 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 } + switch account.quotaTotal { + case -1: + quotaTotal = "" + case -2: + quotaTotal = "" + case -3: + quotaTotal = "" + default: + quotaTotal = CCUtility.transformedSize(account.quotaTotal) + } + completion(LockscreenData(date: Date(), isPlaceholder: false, activity: "", link: URL(string: "https://")!, quotaRelative: quotaRelative, quotaUsed: quotaUsed, quotaTotal: quotaTotal, error: false)) + } else { + completion(LockscreenData(date: Date(), isPlaceholder: false, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: true)) + } + } + } else if family == .accessoryRectangular { + 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: 0, quotaUsed: "", quotaTotal: "", error: false)) + } else { + completion(LockscreenData(date: Date(), isPlaceholder: false, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: true)) } } - 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)) } } diff --git a/Widget/Lockscreen/LockscreenWidgetProvider.swift b/Widget/Lockscreen/LockscreenWidgetProvider.swift index 963c8a0d5..6d3ac5b89 100644 --- a/Widget/Lockscreen/LockscreenWidgetProvider.swift +++ b/Widget/Lockscreen/LockscreenWidgetProvider.swift @@ -22,24 +22,26 @@ // import WidgetKit +import Intents import SwiftUI -struct LockscreenWidgetProvider: TimelineProvider { +struct LockscreenWidgetProvider: IntentTimelineProvider { typealias Entry = LockscreenData + typealias Intent = AccountIntent func placeholder(in context: Context) -> Entry { - return Entry(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "") + return Entry(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: false) } - func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) { - getLockscreenDataEntry(isPreview: false) { entry in + func getSnapshot(for configuration: AccountIntent, in context: Context, completion: @escaping (Entry) -> Void) { + getLockscreenDataEntry(configuration: configuration, isPreview: false, family: context.family) { entry in completion(entry) } } - func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { - getLockscreenDataEntry(isPreview: context.isPreview) { entry in + func getTimeline(for configuration: AccountIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { + getLockscreenDataEntry(configuration: configuration, isPreview: context.isPreview, family: context.family) { entry in let timeLine = Timeline(entries: [entry], policy: .atEnd) completion(timeLine) } diff --git a/Widget/Lockscreen/LockscreenWidgetView.swift b/Widget/Lockscreen/LockscreenWidgetView.swift index de03865c0..fdcb1f2b6 100644 --- a/Widget/Lockscreen/LockscreenWidgetView.swift +++ b/Widget/Lockscreen/LockscreenWidgetView.swift @@ -33,13 +33,25 @@ struct LockscreenWidgetView: View { 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 : []) + if entry.error { + Gauge( + value: 0, + label: {}, + currentValueLabel: { + Image(systemName: "xmark.icloud") + .font(.system(size: 25.0)) + } + ) + .gaugeStyle(.accessoryCircularCapacity) + } else { + 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) { @@ -54,8 +66,16 @@ struct LockscreenWidgetView: View { .fontWeight(.heavy) .foregroundColor(.gray) } - Text(entry.activity) - .font(.system(size: 12)).bold() + if entry.error { + VStack(spacing: 1) { + Image(systemName: "xmark.icloud") + .font(.system(size: 25.0)) + .frame(maxWidth: .infinity, alignment: .center) + }.padding(8) + } else { + Text(entry.activity) + .font(.system(size: 12)).bold() + } } .widgetURL(entry.link) .redacted(reason: entry.isPlaceholder ? .placeholder : []) @@ -68,7 +88,7 @@ struct LockscreenWidgetView: View { @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") + 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", error: true) LockscreenWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .accessoryRectangular)).previewDisplayName("Rectangular") LockscreenWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .accessoryCircular)).previewDisplayName("Circular") } diff --git a/Widget/Toolbar/ToolbarData.swift b/Widget/Toolbar/ToolbarData.swift index 00efdb9fd..67146ea5d 100644 --- a/Widget/Toolbar/ToolbarData.swift +++ b/Widget/Toolbar/ToolbarData.swift @@ -26,19 +26,29 @@ import WidgetKit struct ToolbarDataEntry: TimelineEntry { let date: Date let isPlaceholder: Bool + let userId: String + let url: String let footerImage: String let footerText: String } func getToolbarDataEntry(isPreview: Bool, completion: @escaping (_ entry: ToolbarDataEntry) -> Void) { + var userId = "" + var url = "" + + if let account = NCManageDatabase.shared.getActiveAccount() { + userId = account.userId + url = account.urlBase + } + if isPreview { - return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")) + return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, 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: ""))) + return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, 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")) + completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: userId, url: url, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")) } diff --git a/Widget/Toolbar/ToolbarWidgetProvider.swift b/Widget/Toolbar/ToolbarWidgetProvider.swift index d834a2fc0..303b73eac 100644 --- a/Widget/Toolbar/ToolbarWidgetProvider.swift +++ b/Widget/Toolbar/ToolbarWidgetProvider.swift @@ -29,7 +29,7 @@ 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") + return Entry(date: Date(), isPlaceholder: true, userId: "", url: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar") } func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) { diff --git a/Widget/Toolbar/ToolbarWidgetView.swift b/Widget/Toolbar/ToolbarWidgetView.swift index 6841b4259..3fdab5f51 100644 --- a/Widget/Toolbar/ToolbarWidgetView.swift +++ b/Widget/Toolbar/ToolbarWidgetView.swift @@ -30,6 +30,13 @@ struct ToolbarWidgetView: View { var body: some View { + let parameterLink = "&user=\(entry.userId)&url=\(entry.url)" + let linkNoAction: URL = URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionNoAction + parameterLink)! : URL(string: NCGlobal.shared.widgetActionNoAction)! + let linkActionUploadAsset: URL = URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionUploadAsset + parameterLink)! : URL(string: NCGlobal.shared.widgetActionUploadAsset)! + let linkActionScanDocument: URL = URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionScanDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionScanDocument)! + let linkActionTextDocument: URL = URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionTextDocument + parameterLink)! : URL(string: NCGlobal.shared.widgetActionTextDocument)! + let linkActionVoiceMemo: URL = URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink) != nil ? URL(string: NCGlobal.shared.widgetActionVoiceMemo + parameterLink)! : URL(string: NCGlobal.shared.widgetActionVoiceMemo)! + GeometryReader { geo in ZStack(alignment: .topLeading) { @@ -41,7 +48,7 @@ struct ToolbarWidgetView: View { let sizeButton: CGFloat = 65 - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionUploadAsset, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionUploadAsset, label: { Image("addImage") .resizable() .renderingMode(.template) @@ -53,7 +60,7 @@ struct ToolbarWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionScanDocument, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionScanDocument, label: { Image("scan") .resizable() .renderingMode(.template) @@ -65,7 +72,7 @@ struct ToolbarWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionTextDocument, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionTextDocument, label: { Image("note.text") .resizable() .renderingMode(.template) @@ -77,7 +84,7 @@ struct ToolbarWidgetView: View { .frame(width: geo.size.width / 4, height: sizeButton) }) - Link(destination: entry.isPlaceholder ? NCGlobal.shared.widgetActionNoAction : NCGlobal.shared.widgetActionVoiceMemo, label: { + Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: { Image("microphone") .resizable() .foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText)) @@ -112,7 +119,7 @@ struct ToolbarWidgetView: View { struct ToolbarWidget_Previews: PreviewProvider { static var previews: some View { - let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar") + let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: "", url: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar") ToolbarWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemMedium)) } } diff --git a/Widget/Widget.swift b/Widget/Widget.swift index fe301a39b..2fc72d841 100644 --- a/Widget/Widget.swift +++ b/Widget/Widget.swift @@ -22,6 +22,7 @@ // import WidgetKit +import Intents import SwiftUI @main @@ -53,7 +54,7 @@ struct FilesWidget: Widget { let kind: String = "FilesWidget" var body: some WidgetConfiguration { - StaticConfiguration(kind: kind, provider: FilesWidgetProvider()) { entry in + IntentConfiguration(kind: kind, intent: AccountIntent.self, provider: FilesWidgetProvider()) { entry in FilesWidgetView(entry: entry) } .supportedFamilies([.systemLarge]) @@ -80,7 +81,7 @@ struct LockscreenWidget: Widget { var body: some WidgetConfiguration { if #available(iOSApplicationExtension 16.0, *) { - return StaticConfiguration(kind: kind, provider: LockscreenWidgetProvider()) { entry in + return IntentConfiguration(kind: kind, intent: AccountIntent.self, provider: LockscreenWidgetProvider()) { entry in LockscreenWidgetView(entry: entry) } .supportedFamilies([.accessoryRectangular, .accessoryCircular]) diff --git a/WidgetDashboardIntentHandler/IntentHandler.swift b/WidgetDashboardIntentHandler/IntentHandler.swift index 0be2ead90..9e4cd8c54 100644 --- a/WidgetDashboardIntentHandler/IntentHandler.swift +++ b/WidgetDashboardIntentHandler/IntentHandler.swift @@ -9,15 +9,60 @@ import Intents import RealmSwift -class IntentHandler: INExtension, DashboardIntentHandling { +class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling { + + // MARK: - Account + + // Account + + func provideAccountsOptionsCollection(for intent: AccountIntent, with completion: @escaping (INObjectCollection<Accounts>?, Error?) -> Void) { + + var accounts: [Accounts] = [] + let results = NCManageDatabase.shared.getAllAccount() + + accounts.append(Accounts(identifier: "active", display: "Active account")) + + if results.isEmpty { + return completion(nil, nil) + } else if results.count == 1 { + return completion(INObjectCollection(items: accounts), nil) + } + for result in results { + let display = (result.alias.isEmpty) ? result.account : result.alias + let account = Accounts(identifier: result.account, display: display) + accounts.append(account) + } + + completion(INObjectCollection(items: accounts), nil) + } + + func defaultAccounts(for intent: AccountIntent) -> Accounts? { + + if NCManageDatabase.shared.getActiveAccount() == nil { + return nil + } else { + return Accounts(identifier: "active", display: "Active account") + } + } + + // MARK: - Dashboard + + // Application func provideApplicationsOptionsCollection(for intent: DashboardIntent, with completion: @escaping (INObjectCollection<Applications>?, Error?) -> Void) { var applications: [Applications] = [] + var account: tableAccount? - guard let account = NCManageDatabase.shared.getActiveAccount() else { - completion(nil, nil) - return + let accountIdentifier: String = intent.accounts?.identifier ?? "active" + if accountIdentifier == "active" { + account = NCManageDatabase.shared.getActiveAccount() + } else { + account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier)) + } + + guard let account = account else { + return completion(nil, nil) } let results = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account) @@ -39,4 +84,36 @@ class IntentHandler: INExtension, DashboardIntentHandling { } return nil } + + // Account + + func provideAccountsOptionsCollection(for intent: DashboardIntent, with completion: @escaping (INObjectCollection<Accounts>?, Error?) -> Void) { + + var accounts: [Accounts] = [] + let results = NCManageDatabase.shared.getAllAccount() + + accounts.append(Accounts(identifier: "active", display: "Active account")) + + if results.isEmpty { + return completion(nil, nil) + } else if results.count == 1 { + return completion(INObjectCollection(items: accounts), nil) + } + for result in results { + let display = (result.alias.isEmpty) ? result.account : result.alias + let account = Accounts(identifier: result.account, display: display) + accounts.append(account) + } + + completion(INObjectCollection(items: accounts), nil) + } + + func defaultAccounts(for intent: DashboardIntent) -> Accounts? { + + if NCManageDatabase.shared.getActiveAccount() == nil { + return nil + } else { + return Accounts(identifier: "active", display: "Active account") + } + } } diff --git a/iOSClient/AppDelegate.swift b/iOSClient/AppDelegate.swift index 7d02e50ae..676853532 100644 --- a/iOSClient/AppDelegate.swift +++ b/iOSClient/AppDelegate.swift @@ -56,10 +56,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD var disableSharesView: Bool = false var documentPickerViewController: NCDocumentPickerViewController? - var networkingProcessUpload: NCNetworkingProcessUpload? var shares: [tableShare] = [] var timerErrorNetworking: Timer? - var timerProcess: Timer? private var privacyProtectionWindow: UIWindow? @@ -201,15 +199,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD NCSettingsBundleHelper.setVersionAndBuildNumber() if !account.isEmpty { - networkingProcessUpload?.verifyUploadZombie() + NCNetworkingProcessUpload.shared.verifyUploadZombie() } // Start Auto Upload NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in NKCommon.shared.writeLog("[INFO] Initialize Auto upload with \(items) uploads") - DispatchQueue.main.async { self.networkingProcessUpload = NCNetworkingProcessUpload() } } + // START UPLOAD PROCESS + NCNetworkingProcessUpload.shared.startTimer() + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterApplicationDidBecomeActive) } @@ -249,6 +249,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD showPrivacyProtectionWindow() } + // STOP UPLOAD PROCESS + NCNetworkingProcessUpload.shared.stopTimer() + // Reload Widget WidgetCenter.shared.reloadAllTimelines() @@ -272,9 +275,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD NKCommon.shared.writeLog("[INFO] Application did enter in background") - // STOP UPLOAD PROCESS - networkingProcessUpload?.stopTimer() - scheduleAppRefresh() scheduleAppProcessing() @@ -369,11 +369,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } 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) + NKCommon.shared.writeLog("[INFO] Refresh task auto upload with \(items) uploads") + NCNetworkingProcessUpload.shared.process { items in + NKCommon.shared.writeLog("[INFO] Refresh task upload process with \(items) uploads") + task.setTaskCompleted(success: true) + } } } @@ -385,11 +387,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD return } - NKCommon.shared.setup(delegate: NCNetworking.shared) - NKCommon.shared.writeLog("[INFO] Start handler processing task [Reload widget]") - - WidgetCenter.shared.reloadAllTimelines() - + NKCommon.shared.writeLog("[INFO] Processing task") task.setTaskCompleted(success: true) } @@ -406,7 +404,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // MARK: - Push Notifications func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - completionHandler(UNNotificationPresentationOptions.alert) + completionHandler([.list, .banner, .sound]) } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { @@ -564,8 +562,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD @objc func settingAccount(_ account: String, urlBase: String, user: String, userId: String, password: String) { - let accountBackup = self.account - let userIdBackup = self.userId + let accountTestBackup = self.account + "/" + self.userId + let accountTest = account + "/" + userId self.account = account self.urlBase = urlBase @@ -583,7 +581,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD NCKTVHTTPCache.shared.restartProxy(user: user, password: password) DispatchQueue.main.async { - if UIApplication.shared.applicationState != .background && (accountBackup != account || userIdBackup != userId) { + if UIApplication.shared.applicationState != .background && accountTestBackup != accountTest { NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterInitialize, second: 0.2) } } @@ -715,12 +713,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let passcodeViewController = privacyProtectionWindow?.rootViewController?.presentedViewController as? TOPasscodeViewController else { return } - LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: NCBrandOptions.shared.brand) { (success, error) in - if success { - DispatchQueue.main.async { - passcodeViewController.dismiss(animated: true) { - self.hidePrivacyProtectionWindow() - self.requestAccount() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: NCBrandOptions.shared.brand) { (success, error) in + if success { + DispatchQueue.main.async { + passcodeViewController.dismiss(animated: true) { + self.hidePrivacyProtectionWindow() + self.requestAccount() + } } } } @@ -782,19 +782,32 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let action = url.host var fileName: String = "" var serverUrl: String = "" - var matchedAccount: tableAccount? /* Example: - nextcloud://open-action?action=create-voice-memo + nextcloud://open-action?action=create-voice-memo&&user=marinofaggiana&url=https://cloud.nextcloud.com */ 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 } - + guard let userScheme = CCUtility.value(forKey: "user", fromQueryItems: queryItems) else { return false } + guard let urlScheme = CCUtility.value(forKey: "url", fromQueryItems: queryItems) else { return false } + if getMatchedAccount(userId: userScheme, url: urlScheme) == nil { + let message = String(format: NSLocalizedString("_account_not_exists_", comment: ""), userScheme, urlScheme) + + let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) + + window?.rootViewController?.present(alertController, animated: true, completion: { }) + + return false + } + + switch actionScheme { case NCGlobal.shared.actionUploadAsset: @@ -858,52 +871,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD guard let userScheme = CCUtility.value(forKey: "user", fromQueryItems: queryItems) else { return false } guard let pathScheme = CCUtility.value(forKey: "path", fromQueryItems: queryItems) else { return false } guard let linkScheme = CCUtility.value(forKey: "link", fromQueryItems: queryItems) else { return false } + guard let matchedAccount = getMatchedAccount(userId: userScheme, url: linkScheme) else { + guard let domain = URL(string: linkScheme)?.host else { return true } + fileName = (pathScheme as NSString).lastPathComponent + let message = String(format: NSLocalizedString("_account_not_available_", comment: ""), userScheme, domain, fileName) - if let activeAccount = NCManageDatabase.shared.getActiveAccount() { - - let urlBase = URL(string: activeAccount.urlBase) - if linkScheme.contains(urlBase?.host ?? "") && userScheme == activeAccount.userId { - matchedAccount = activeAccount - } else { - let accounts = NCManageDatabase.shared.getAllAccount() - for account in accounts { - let urlBase = URL(string: account.urlBase) - if linkScheme.contains(urlBase?.host ?? "") && userScheme == account.userId { - changeAccount(account.account) - matchedAccount = account - break - } - } - } - - if matchedAccount != nil { + let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) - let webDAV = NCUtilityFileSystem.shared.getWebDAV(account: self.account) + "/files/" + self.userId - if pathScheme.contains("/") { - fileName = (pathScheme as NSString).lastPathComponent - serverUrl = matchedAccount!.urlBase + "/" + webDAV + "/" + (pathScheme as NSString).deletingLastPathComponent - } else { - fileName = pathScheme - serverUrl = matchedAccount!.urlBase + "/" + webDAV - } + window?.rootViewController?.present(alertController, animated: true, completion: { }) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - NCFunctionCenter.shared.openFileViewInFolder(serverUrl: serverUrl, fileNameBlink: nil, fileNameOpen: fileName) - } - - } else { - - guard let domain = URL(string: linkScheme)?.host else { return true } - fileName = (pathScheme as NSString).lastPathComponent - let message = String(format: NSLocalizedString("_account_not_available_", comment: ""), userScheme, domain, fileName) - - let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert) - alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) + return false + } - window?.rootViewController?.present(alertController, animated: true, completion: { }) + let davFiles = NCGlobal.shared.davfiles + self.userId + if pathScheme.contains("/") { + fileName = (pathScheme as NSString).lastPathComponent + serverUrl = matchedAccount.urlBase + "/" + davFiles + "/" + (pathScheme as NSString).deletingLastPathComponent + } else { + fileName = pathScheme + serverUrl = matchedAccount.urlBase + "/" + davFiles + } - return false - } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + NCFunctionCenter.shared.openFileViewInFolder(serverUrl: serverUrl, fileNameBlink: nil, fileNameOpen: fileName) } } } else { @@ -912,6 +903,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD return true } + + func getMatchedAccount(userId: String, url: String) -> tableAccount? { + + if let activeAccount = NCManageDatabase.shared.getActiveAccount() { + let urlBase = URL(string: activeAccount.urlBase) + if url.contains(urlBase?.host ?? "") && userId == activeAccount.userId { + return activeAccount + } else { + let accounts = NCManageDatabase.shared.getAllAccount() + for account in accounts { + let urlBase = URL(string: account.urlBase) + if url.contains(urlBase?.host ?? "") && userId == account.userId { + changeAccount(account.account) + return account + } + } + } + } + return nil + } } // MARK: - NCAudioRecorder ViewController Delegate @@ -936,6 +947,6 @@ extension AppDelegate: NCAudioRecorderViewControllerDelegate { extension AppDelegate: NCCreateFormUploadConflictDelegate { func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) { guard let metadatas = metadatas, !metadatas.isEmpty else { return } - networkingProcessUpload?.createProcessUploads(metadatas: metadatas, completion: { _ in }) + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: metadatas) { _ in } } } diff --git a/iOSClient/Brand/WidgetDashboardIntentHandler.plist b/iOSClient/Brand/WidgetDashboardIntentHandler.plist index bd92093ac..9b9988eb8 100644 --- a/iOSClient/Brand/WidgetDashboardIntentHandler.plist +++ b/iOSClient/Brand/WidgetDashboardIntentHandler.plist @@ -17,6 +17,7 @@ <array/> <key>IntentsSupported</key> <array> + <string>AccountIntent</string> <string>DashboardIntent</string> </array> </dict> diff --git a/iOSClient/Brand/iOSClient.plist b/iOSClient/Brand/iOSClient.plist index 121991ec4..8838f25df 100755 --- a/iOSClient/Brand/iOSClient.plist +++ b/iOSClient/Brand/iOSClient.plist @@ -77,6 +77,7 @@ <string>Photo library access is required to upload your photos and videos to your cloud.</string> <key>NSUserActivityTypes</key> <array> + <string>AccountIntent</string> <string>DashboardIntent</string> </array> <key>PHPhotoLibraryPreventAutomaticLimitedAccessAlert</key> diff --git a/iOSClient/Data/NCManageDatabase+Account.swift b/iOSClient/Data/NCManageDatabase+Account.swift index 3f6956ca5..1f840b083 100644 --- a/iOSClient/Data/NCManageDatabase+Account.swift +++ b/iOSClient/Data/NCManageDatabase+Account.swift @@ -36,7 +36,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableAccount() addObject.account = account @@ -68,7 +68,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { realm.add(account, update: .all) } } catch let error { @@ -81,7 +81,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableAccount.self).filter("account == %@", account) realm.delete(result) @@ -161,7 +161,7 @@ extension NCManageDatabase { } } - @objc func getAccountAutoUploadDirectory(urlBase: String, account: String) -> String { + @objc func getAccountAutoUploadDirectory(urlBase: String, userId: String, account: String) -> String { let realm = try! Realm() @@ -172,19 +172,19 @@ extension NCManageDatabase { if result.autoUploadDirectory.count > 0 { // FIX change webdav -> /dav/files/ if result.autoUploadDirectory.contains("/webdav") { - return NCUtilityFileSystem.shared.getHomeServer(account: account) + return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId) } else { return result.autoUploadDirectory } } else { - return NCUtilityFileSystem.shared.getHomeServer(account: account) + return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId) } } - @objc func getAccountAutoUploadPath(urlBase: String, account: String) -> String { + @objc func getAccountAutoUploadPath(urlBase: String, userId: String, account: String) -> String { let cameraFileName = self.getAccountAutoUploadFileName() - let cameraDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, account: account) + let cameraDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, userId: userId, account: account) let folderPhotos = CCUtility.stringAppendServerUrl(cameraDirectory, addFileName: cameraFileName)! @@ -198,7 +198,7 @@ extension NCManageDatabase { var accountReturn = tableAccount() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableAccount.self) for result in results { @@ -223,7 +223,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("account == %@", account).first { result.password = "********" @@ -239,7 +239,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("active == true").first { if (tableAccount().objectSchema.properties.contains { $0.name == property }) { result[property] = state @@ -256,7 +256,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("active == true").first { if let fileName = fileName { result.autoUploadFileName = fileName @@ -270,17 +270,17 @@ extension NCManageDatabase { } } - @objc func setAccountAutoUploadDirectory(_ serverUrl: String?, urlBase: String, account: String) { + @objc func setAccountAutoUploadDirectory(_ serverUrl: String?, urlBase: String, userId: String, account: String) { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("active == true").first { if let serverUrl = serverUrl { result.autoUploadDirectory = serverUrl } else { - result.autoUploadDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, account: account) + result.autoUploadDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, userId: userId, account: account) } } } @@ -300,7 +300,7 @@ extension NCManageDatabase { return nil } - try realm.safeWrite { + try realm.write { guard let result = realm.objects(tableAccount.self).filter("account == %@", activeAccount.account).first else { return @@ -350,7 +350,7 @@ extension NCManageDatabase { return nil } - try realm.safeWrite { + try realm.write { guard let result = realm.objects(tableAccount.self).filter("account == %@", activeAccount.account).first else { return @@ -377,7 +377,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("account == %@", account).first { result.mediaPath = path } @@ -391,7 +391,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("account == %@", account).first { result.userStatusClearAt = userStatusClearAt result.userStatusIcon = userStatusIcon @@ -413,7 +413,7 @@ extension NCManageDatabase { let alias = alias?.trimmingCharacters(in: .whitespacesAndNewlines) do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAccount.self).filter("active == true").first { if let alias = alias { result.alias = alias diff --git a/iOSClient/Data/NCManageDatabase+Activity.swift b/iOSClient/Data/NCManageDatabase+Activity.swift index 401258164..91769b6a3 100644 --- a/iOSClient/Data/NCManageDatabase+Activity.swift +++ b/iOSClient/Data/NCManageDatabase+Activity.swift @@ -204,7 +204,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId) realm.delete(results) diff --git a/iOSClient/Data/NCManageDatabase+DashboardWidget.swift b/iOSClient/Data/NCManageDatabase+DashboardWidget.swift index ebd58d4bf..3981716a4 100644 --- a/iOSClient/Data/NCManageDatabase+DashboardWidget.swift +++ b/iOSClient/Data/NCManageDatabase+DashboardWidget.swift @@ -52,7 +52,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let resultDashboard = realm.objects(tableDashboardWidget.self).filter("account == %@", account) realm.delete(resultDashboard) diff --git a/iOSClient/Data/NCManageDatabase+Metadata.swift b/iOSClient/Data/NCManageDatabase+Metadata.swift index 59868cdeb..7927b2657 100644 --- a/iOSClient/Data/NCManageDatabase+Metadata.swift +++ b/iOSClient/Data/NCManageDatabase+Metadata.swift @@ -146,7 +146,7 @@ extension NCManageDatabase { if let key = listServerUrl[file.serverUrl] { isEncrypted = key } else { - isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted: file.e2eEncrypted, account: account, urlBase: file.urlBase) + isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted: file.e2eEncrypted, account: account, urlBase: file.urlBase, userId: file.userId) listServerUrl[file.serverUrl] = isEncrypted } @@ -231,7 +231,7 @@ extension NCManageDatabase { let returnMetadata = tableMetadata.init(value: metadata) do { - try realm.safeWrite { + try realm.write { realm.add(metadata, update: .all) } } catch let error { @@ -246,7 +246,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { for metadata in metadatas { realm.add(metadata, update: .all) } @@ -261,7 +261,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter(predicate) realm.delete(results) } @@ -275,7 +275,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first { result.serverUrl = serverUrlTo } @@ -290,7 +290,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter("ocId == %@", ocId) for result in results { result.serverUrl = serverUrl @@ -306,7 +306,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first { let resultsType = NKCommon.shared.getInternalType(fileName: fileNameTo, mimeType: "", directory: result.directory) result.fileName = fileNameTo @@ -338,10 +338,8 @@ extension NCManageDatabase { var metadatasUpdate: [tableMetadata] = [] var metadatasLocalUpdate: [tableMetadata] = [] - realm.refresh() - do { - try realm.safeWrite { + try realm.write { // DELETE for metadataResult in metadatasResult { @@ -414,10 +412,9 @@ extension NCManageDatabase { func setMetadataSession(ocId: String, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil) { let realm = try! Realm() - realm.refresh() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first if let session = session { result?.session = session @@ -450,7 +447,7 @@ extension NCManageDatabase { var result: tableMetadata? do { - try realm.safeWrite { + try realm.write { result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first result?.status = status } @@ -472,7 +469,7 @@ extension NCManageDatabase { guard let etagResource = etagResource else { return } do { - try realm.safeWrite { + try realm.write { result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first result?.etagResource = etagResource } @@ -486,7 +483,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first result?.favorite = favorite } @@ -500,7 +497,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter("account == %@ AND favorite == true", account) for result in results { result.favorite = false @@ -519,7 +516,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first result?.e2eEncrypted = encrypted } @@ -533,7 +530,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first result?.fileNameView = newFileNameView } @@ -667,14 +664,14 @@ extension NCManageDatabase { return tableMetadata.init(value: result) } - @objc func getMetadataFolder(account: String, urlBase: String, serverUrl: String) -> tableMetadata? { + @objc func getMetadataFolder(account: String, urlBase: String, userId: String, serverUrl: String) -> tableMetadata? { let realm = try! Realm() realm.refresh() var serverUrl = serverUrl var fileName = "" - let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(account: account) + let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId) if serverUrlHome == serverUrl { fileName = "." serverUrl = ".." @@ -712,7 +709,7 @@ extension NCManageDatabase { realm.refresh() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter("account == %@ AND (status == %d OR status == %@)", account, NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusUploadError) realm.delete(results) @@ -727,7 +724,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter("account == %@ AND fileId == %@", account, fileId) for result in results { result.commentsUnread = false @@ -758,7 +755,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier IN %@", account, assetLocalIdentifiers) for result in results { result.assetLocalIdentifier = "" @@ -775,8 +772,6 @@ extension NCManageDatabase { let realm = try! Realm() var classFile = metadata.classFile - realm.refresh() - if !metadata.livePhoto || !CCUtility.getLivePhoto() { return nil } diff --git a/iOSClient/Data/NCManageDatabase+Video.swift b/iOSClient/Data/NCManageDatabase+Video.swift index 2ea740cb4..44d0b5d9f 100644 --- a/iOSClient/Data/NCManageDatabase+Video.swift +++ b/iOSClient/Data/NCManageDatabase+Video.swift @@ -33,7 +33,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first { if let durationTime = durationTime { @@ -69,7 +69,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first { if let codecNameVideo = codecNameVideo { result.codecNameVideo = codecNameVideo } if let codecNameAudio = codecNameAudio { result.codecNameAudio = codecNameAudio } @@ -141,7 +141,7 @@ extension NCManageDatabase { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId) realm.delete(result) } diff --git a/iOSClient/Data/NCManageDatabase.swift b/iOSClient/Data/NCManageDatabase.swift index e57458eba..c63cd2c4b 100644 --- a/iOSClient/Data/NCManageDatabase.swift +++ b/iOSClient/Data/NCManageDatabase.swift @@ -157,7 +157,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { var results: Results<Object> if let account = account { @@ -252,7 +252,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { // Add new let addObject = tableAvatar() @@ -285,7 +285,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableAvatar.self) for result in results { @@ -306,7 +306,7 @@ class NCManageDatabase: NSObject { var image: UIImage? do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first { if let imageAvatar = UIImage(contentsOfFile: fileNameLocalPath) { result.loaded = true @@ -347,7 +347,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableCapabilities() addObject.account = account @@ -480,7 +480,7 @@ class NCManageDatabase: NSObject { var size: Int64 = 0 do { - try realm.safeWrite { + try realm.write { for fileName in fileNames { @@ -518,7 +518,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@ AND fileName == %@", account, ocId, fileName)) realm.delete(result) @@ -533,7 +533,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@", account, ocId)) realm.delete(result) @@ -551,7 +551,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let resultsCreators = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account) realm.delete(resultsCreators) @@ -650,7 +650,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { var addObject = tableDirectory() let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first @@ -694,7 +694,7 @@ class NCManageDatabase: NSObject { // Delete table Dirrectory do { - try realm.safeWrite { + try realm.write { realm.delete(results) } } catch let error { @@ -707,7 +707,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { guard let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return @@ -770,7 +770,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first result?.serverUrl = serverUrl } @@ -784,7 +784,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first result?.offline = offline } @@ -800,7 +800,7 @@ class NCManageDatabase: NSObject { var result: tableDirectory? do { - try realm.safeWrite { + try realm.write { result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first result?.richWorkspace = richWorkspace } @@ -822,7 +822,7 @@ class NCManageDatabase: NSObject { var result: tableDirectory? do { - try realm.safeWrite { + try realm.write { result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first result?.colorFolder = colorFolder } @@ -845,7 +845,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { realm.add(e2e, update: .all) } } catch let error { @@ -858,7 +858,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableE2eEncryption.self).filter(predicate) realm.delete(results) @@ -948,7 +948,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableE2eEncryptionLock() addObject.account = account @@ -968,7 +968,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first { realm.delete(result) } @@ -986,7 +986,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableExternalSites() addObject.account = account @@ -1009,7 +1009,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableExternalSites.self).filter("account == %@", account) realm.delete(results) } @@ -1087,7 +1087,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) ?? tableLocalFile() @@ -1111,7 +1111,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableLocalFile() @@ -1135,7 +1135,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableLocalFile.self).filter(predicate) realm.delete(results) } @@ -1149,7 +1149,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first if let fileName = fileName { result?.fileName = fileName @@ -1168,7 +1168,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first { result.exifDate = exifDate result.exifLatitude = exifLatitude @@ -1215,7 +1215,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first result?.offline = offline } @@ -1233,30 +1233,24 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { - - var creationDateString = "" + try realm.write { for asset in assets { + var creationDateString = "" let addObject = tablePhotoLibrary() addObject.account = account addObject.assetLocalIdentifier = asset.localIdentifier addObject.mediaType = asset.mediaType.rawValue - if let creationDate = asset.creationDate { addObject.creationDate = creationDate as NSDate creationDateString = String(describing: creationDate) - } else { - creationDateString = "" } - if let modificationDate = asset.modificationDate { addObject.modificationDate = modificationDate as NSDate } - - addObject.idAsset = "\(account)\(asset.localIdentifier)\(creationDateString)" + addObject.idAsset = account + asset.localIdentifier + creationDateString realm.add(addObject, update: .all) } @@ -1297,13 +1291,13 @@ class NCManageDatabase: NSObject { // MARK: - // MARK: Table Share - @objc func addShare(urlBase: String, account: String, shares: [NKShare]) { + @objc func addShare(account: String, urlBase: String, userId: String, shares: [NKShare]) { let realm = try! Realm() - let home = NCUtilityFileSystem.shared.getHomeServer(account: account) + let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId) do { - try realm.safeWrite { + try realm.write { for share in shares { @@ -1461,7 +1455,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { // Add new let addObject = tableTag() @@ -1534,7 +1528,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let addObject = tableTip() addObject.tipName = tipName realm.add(addObject, update: .all) @@ -1552,7 +1546,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { for trash in items { let object = tableTrash() @@ -1585,7 +1579,7 @@ class NCManageDatabase: NSObject { var predicate = NSPredicate() do { - try realm.safeWrite { + try realm.write { if filePath == nil { predicate = NSPredicate(format: "account == %@", account) @@ -1607,7 +1601,7 @@ class NCManageDatabase: NSObject { var predicate = NSPredicate() do { - try realm.safeWrite { + try realm.write { if fileId == nil { predicate = NSPredicate(format: "account == %@", account) @@ -1653,7 +1647,7 @@ class NCManageDatabase: NSObject { let realm = try! Realm() do { - try realm.safeWrite { + try realm.write { let results = realm.objects(tableUserStatus.self).filter("account == %@ AND predefined == %@", account, predefined) realm.delete(results) @@ -1681,15 +1675,3 @@ class NCManageDatabase: NSObject { } } } - -// MARK: - - -extension Realm { - public func safeWrite(_ block: (() throws -> Void)) throws { - if isInWriteTransaction { - try block() - } else { - try write(block) - } - } -} diff --git a/iOSClient/Diagnostics/NCCapabilitiesViewController.swift b/iOSClient/Diagnostics/NCCapabilitiesViewController.swift index 3e5bde1bd..32472e522 100644 --- a/iOSClient/Diagnostics/NCCapabilitiesViewController.swift +++ b/iOSClient/Diagnostics/NCCapabilitiesViewController.swift @@ -189,7 +189,7 @@ class NCCapabilitiesViewController: UIViewController, UIDocumentInteractionContr } homeImage.image = UIImage(named: "home")!.image(color: NCBrandColor.shared.gray, size: 50) - homeServer.text = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + "/" + homeServer.text = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) + "/" } @objc func updateCapabilities() { diff --git a/iOSClient/Extensions/Array+Extensions.swift b/iOSClient/Extensions/Array+Extensions.swift index 1b6a9790a..b23c74627 100644 --- a/iOSClient/Extensions/Array+Extensions.swift +++ b/iOSClient/Extensions/Array+Extensions.swift @@ -29,11 +29,9 @@ extension Array { func unique<T: Hashable>(map: ((Element) -> (T))) -> [Element] { var set = Set<T>() // the unique list kept in a Set for fast retrieval var arrayOrdered = [Element]() // keeping the unique list of elements but ordered - for value in self { - if !set.contains(map(value)) { - set.insert(map(value)) - arrayOrdered.append(value) - } + for value in self where !set.contains(map(value)) { + set.insert(map(value)) + arrayOrdered.append(value) } return arrayOrdered diff --git a/iOSClient/Extensions/UIAlertController+Extension.swift b/iOSClient/Extensions/UIAlertController+Extension.swift index 5c7dc93a8..d670efd5e 100644 --- a/iOSClient/Extensions/UIAlertController+Extension.swift +++ b/iOSClient/Extensions/UIAlertController+Extension.swift @@ -36,7 +36,7 @@ extension UIAlertController { let okAction = UIAlertAction(title: NSLocalizedString("_save_", comment: ""), style: .default, handler: { _ in guard let fileNameFolder = alertController.textFields?.first?.text else { return } - NCNetworking.shared.createFolder(fileName: fileNameFolder, serverUrl: serverUrl, account: urlBase.account, urlBase: urlBase.urlBase, overwrite: false) { error in + NCNetworking.shared.createFolder(fileName: fileNameFolder, serverUrl: serverUrl, account: urlBase.account, urlBase: urlBase.urlBase, userId: urlBase.userId, overwrite: false) { error in if let completion = completion { completion(error) } else if error != .success { diff --git a/iOSClient/Extensions/UIApplication+Orientation.swift b/iOSClient/Extensions/UIApplication+Orientation.swift index 432b2ed08..3b6632a2c 100644 --- a/iOSClient/Extensions/UIApplication+Orientation.swift +++ b/iOSClient/Extensions/UIApplication+Orientation.swift @@ -27,7 +27,7 @@ extension UIApplication { var isLandscape: Bool { if UIDevice.current.orientation.isValidInterfaceOrientation { return UIDevice.current.orientation.isLandscape - } else { + } else { return windows.first?.windowScene?.interfaceOrientation.isLandscape ?? false } } diff --git a/iOSClient/Favorites/NCFavorite.swift b/iOSClient/Favorites/NCFavorite.swift index d6f2d3894..682d3d850 100644 --- a/iOSClient/Favorites/NCFavorite.swift +++ b/iOSClient/Favorites/NCFavorite.swift @@ -103,13 +103,9 @@ class NCFavorite: NCCollectionViewCommon { } else { networkReadFolder(forced: forced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in - if error == .success { - for metadata in metadatas ?? [] { - if !metadata.directory { - if NCManageDatabase.shared.isDownloadMetadata(metadata, download: false) { - NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile) - } - } + if error == .success, let metadatas = metadatas { + for metadata in metadatas where (!metadata.directory && NCManageDatabase.shared.isDownloadMetadata(metadata, download: false)) { + NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile) } } diff --git a/iOSClient/Files/NCFiles.swift b/iOSClient/Files/NCFiles.swift index dd7d413fe..ab5d68f5a 100644 --- a/iOSClient/Files/NCFiles.swift +++ b/iOSClient/Files/NCFiles.swift @@ -49,7 +49,7 @@ class NCFiles: NCCollectionViewCommon { override func viewWillAppear(_ animated: Bool) { if isRoot { - serverUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) titleCurrentFolder = getNavigationTitle() } super.viewWillAppear(animated) @@ -69,7 +69,7 @@ class NCFiles: NCCollectionViewCommon { override func initialize() { if isRoot { - serverUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) titleCurrentFolder = getNavigationTitle() } super.initialize() @@ -98,7 +98,7 @@ class NCFiles: NCCollectionViewCommon { let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl)) if self.metadataFolder == nil { - self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, serverUrl: self.serverUrl) + self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, serverUrl: self.serverUrl) } let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl)) let metadataTransfer = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "status != %i AND serverUrl == %@", NCGlobal.shared.metadataStatusNormal, self.serverUrl)) diff --git a/iOSClient/Login/NCLogin.swift b/iOSClient/Login/NCLogin.swift index 9354d4e1f..38ee5c00c 100644 --- a/iOSClient/Login/NCLogin.swift +++ b/iOSClient/Login/NCLogin.swift @@ -311,8 +311,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate { let user = valueArray[0].replacingOccurrences(of: "user:", with: "") let password = valueArray[1].replacingOccurrences(of: "password:", with: "") let urlBase = valueArray[2].replacingOccurrences(of: "server:", with: "") - let webDAV = NCUtilityFileSystem.shared.getWebDAV(account: appDelegate.account) - let serverUrl = urlBase + "/" + webDAV + let serverUrl = urlBase + "/" + NCGlobal.shared.dav loginButton.isEnabled = false diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift index 06b363cf2..c66ad1c8d 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift @@ -199,7 +199,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS NotificationCenter.default.addObserver(self, selector: #selector(triggerProgressTask(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterProgressTask), object: nil) if serverUrl == "" { - appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) } else { appDelegate.activeServerUrl = serverUrl } @@ -297,7 +297,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS if self.view?.window != nil { if serverUrl == "" { - appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + appDelegate.activeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) } else { appDelegate.activeServerUrl = serverUrl } @@ -647,7 +647,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS func showTip() { - if self is NCFiles, self.view.window != nil, !NCBrandOptions.shared.disable_multiaccount, !NCBrandOptions.shared.disable_manage_account, self.serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account), let view = self.navigationItem.leftBarButtonItem?.customView { + if self is NCFiles, self.view.window != nil, !NCBrandOptions.shared.disable_multiaccount, !NCBrandOptions.shared.disable_manage_account, self.serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId), let view = self.navigationItem.leftBarButtonItem?.customView { if !NCManageDatabase.shared.tipExists(NCGlobal.shared.tipNCCollectionViewCommonAccountRequest), NCManageDatabase.shared.getAllAccountOrderAlias().count > 0 { self.tipView?.show(forView: view) } @@ -673,7 +673,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS let button = UIButton(type: .custom) button.setImage(image, for: .normal) - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { var titleButton = " " @@ -999,11 +999,11 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS guard !appDelegate.account.isEmpty else { return } // E2EE - isEncryptedFolder = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: metadataFolder?.e2eEncrypted ?? false, account: appDelegate.account, urlBase: appDelegate.urlBase) + isEncryptedFolder = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: metadataFolder?.e2eEncrypted ?? false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) // get auto upload folder autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName() - autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, account: appDelegate.account) + autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account) // get layout for view layoutForView = NCUtility.shared.getLayoutForView(key: layoutKey, serverUrl: serverUrl) @@ -1123,7 +1123,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS if let metadataFolder = metadataFolder, metadataFolder.e2eEncrypted, CCUtility.isEnd(toEndEnabled: self.appDelegate.account) { NextcloudKit.shared.getE2EEMetadata(fileId: metadataFolder.ocId, e2eToken: nil) { account, e2eMetadata, data, error in if error == .success, let e2eMetadata = e2eMetadata { - if NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: self.serverUrl, account: account, urlBase: self.appDelegate.urlBase) { + if NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId) { self.reloadDataSource() } else { let error = NKError(errorCode: NCGlobal.shared.errorDecodeMetadata, errorDescription: "_e2e_error_decode_metadata_") @@ -1531,9 +1531,6 @@ extension NCCollectionViewCommon: UICollectionViewDataSource { cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderExternal } else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory { cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folderAutomaticUpload - if cell is NCListCell { - cell.fileTitleLabel?.text = (cell.fileTitleLabel?.text ?? "") + " - " + NSLocalizedString("_auto_upload_folder_", comment: "") - } } else { cell.filePreviewImageView?.image = NCBrandColor.cacheImages.folder } diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift index 1eca7852d..7b9d86fc4 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift @@ -52,7 +52,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { self.init() - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { titleServerUrl = "/" } else { if let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl)) { @@ -304,7 +304,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { self.serverUrl = serverUrl! - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { self.titleServerUrl = "/" } else { if let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, self.serverUrl)) { @@ -330,15 +330,15 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { var useSubFolder: Bool = false var metadatasNOConflict: [tableMetadata] = [] var metadatasUploadInConflict: [tableMetadata] = [] - let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: self.appDelegate.urlBase, account: self.appDelegate.account) + let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, account: self.appDelegate.account) if (useFolderPhotoRow.value! as AnyObject).boolValue == true { - self.serverUrl = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: self.appDelegate.urlBase, account: self.appDelegate.account) + self.serverUrl = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, account: self.appDelegate.account) useSubFolder = (useSubFolderRow.value! as AnyObject).boolValue } if autoUploadPath == self.serverUrl { - if !NCNetworking.shared.createFolder(assets: self.assets, selector: NCGlobal.shared.selectorUploadFile, useSubFolder: useSubFolder, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase) { + if !NCNetworking.shared.createFolder(assets: self.assets, selector: NCGlobal.shared.selectorUploadFile, useSubFolder: useSubFolder, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId) { let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_error_createsubfolders_upload_") NCContentPresenter.shared.showError(error: error) @@ -350,8 +350,8 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { var serverUrl = self.serverUrl var livePhoto: Bool = false - let fileName = CCUtility.createFileName(asset.value(forKey: "filename") as? String, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: NCGlobal.shared.keyFileNameMask, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false)! - let assetDate = asset.creationDate ?? Date() + let creationDate = asset.creationDate ?? Date() + let fileName = CCUtility.createFileName(asset.value(forKey: "filename") as? String, fileDate: creationDate, fileType: asset.mediaType, keyFileName: NCGlobal.shared.keyFileNameMask, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false)! if asset.mediaSubtypes.contains(.photoLive) && CCUtility.getLivePhoto() { livePhoto = true @@ -360,9 +360,9 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { if useSubFolder { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy" - let yearString = dateFormatter.string(from: assetDate) + let yearString = dateFormatter.string(from: creationDate) dateFormatter.dateFormat = "MM" - let monthString = dateFormatter.string(from: assetDate) + let monthString = dateFormatter.string(from: creationDate) serverUrl = autoUploadPath + "/" + yearString + "/" + monthString } @@ -394,15 +394,14 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { conflict.metadatasNOConflict = metadatasNOConflict conflict.metadatasUploadInConflict = metadatasUploadInConflict conflict.delegate = self.appDelegate - conflict.isE2EE = CCUtility.isFolderEncrypted(self.serverUrl, e2eEncrypted: false, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(self.serverUrl, e2eEncrypted: false, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId) self.appDelegate.window?.rootViewController?.present(conflict, animated: true, completion: nil) } } } else { - - self.appDelegate.networkingProcessUpload?.createProcessUploads(metadatas: metadatasNOConflict, completion: { _ in }) + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: metadatasNOConflict, completion: { _ in }) } DispatchQueue.main.async {self.dismiss(animated: true, completion: nil) } @@ -420,6 +419,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { var returnString: String = "" let asset = assets[0] + let creationDate = asset.creationDate ?? Date() if CCUtility.getOriginalFileName(NCGlobal.shared.keyFileNameOriginal) { @@ -435,18 +435,18 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { CCUtility.setFileNameMask(valueRename, key: NCGlobal.shared.keyFileNameMask) self.form.delegate = self - returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: NCGlobal.shared.keyFileNameMask, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) + returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: creationDate, fileType: asset.mediaType, keyFileName: NCGlobal.shared.keyFileNameMask, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) } else { CCUtility.setFileNameMask("", key: NCGlobal.shared.keyFileNameMask) - returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) + returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) } } else { CCUtility.setFileNameMask("", key: NCGlobal.shared.keyFileNameMask) - returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) + returnString = CCUtility.createFileName(asset.value(forKey: "filename") as! String?, fileDate: creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: NCGlobal.shared.keyFileNameType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginal, forcedNewFileName: false) } return String(format: NSLocalizedString("_preview_filename_", comment: ""), "MM, MMM, DD, YY, YYYY, HH, hh, mm, ss, ampm") + ":" + "\n\n" + returnString diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift index 7e57a43cd..223512855 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift @@ -24,6 +24,7 @@ import UIKit import NextcloudKit import Photos +import JGProgressHUD @objc protocol NCCreateFormUploadConflictDelegate { @objc func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) @@ -315,7 +316,7 @@ extension NCCreateFormUploadConflict: UITableViewDataSource { cell.backgroundColor = tableView.backgroundColor - let metadataNewFile = metadatasUploadInConflict[indexPath.row] + let metadataNewFile = tableMetadata.init(value: metadatasUploadInConflict[indexPath.row]) cell.ocId = metadataNewFile.ocId cell.delegate = self @@ -390,7 +391,7 @@ extension NCCreateFormUploadConflict: UITableViewDataSource { } else { // PREVIEW - NCUtility.shared.extractImageVideoFromAssetLocalIdentifier(metadata: metadataNewFile, modifyMetadataForUpload: false) { metadata, fileNamePath, error in + NCUtility.shared.extractImageVideoFromAssetLocalIdentifier(metadata: metadataNewFile, modifyMetadataForUpload: false, viewController: self, hud: JGProgressHUD()) { metadata, fileNamePath, error in if !error { self.fileNamesPath[metadataNewFile.fileNameView] = fileNamePath! do { diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift index 21b24e6bb..d4dc71051 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift @@ -57,7 +57,7 @@ import XLForm override func viewDidLoad() { super.viewDidLoad() - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { fileNameFolder = "/" } else { fileNameFolder = (serverUrl as NSString).lastPathComponent @@ -218,7 +218,7 @@ import XLForm } self.serverUrl = serverUrl - if serverUrl == NCUtilityFileSystem.shared.getHomeServer( account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { fileNameFolder = "/" } else { fileNameFolder = (serverUrl as NSString).lastPathComponent @@ -279,13 +279,13 @@ import XLForm conflict.serverUrl = serverUrl conflict.metadatasUploadInConflict = [metadataForUpload] conflict.delegate = self - conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) self.present(conflict, animated: true, completion: nil) } else { - let fileNamePath = CCUtility.returnFileNamePath(fromFileName: String(describing: fileNameForm), serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)! + let fileNamePath = CCUtility.returnFileNamePath(fromFileName: String(describing: fileNameForm), serverUrl: serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account)! createDocument(fileNamePath: fileNamePath, fileName: String(describing: fileNameForm)) } } @@ -302,7 +302,7 @@ import XLForm } else { let fileName = metadatas![0].fileName - let fileNamePath = CCUtility.returnFileNamePath(fromFileName: fileName, serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)! + let fileNamePath = CCUtility.returnFileNamePath(fromFileName: fileName, serverUrl: serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account)! createDocument(fileNamePath: fileNamePath, fileName: fileName) } diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift index 4e46599ad..f77d8bf24 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift @@ -54,7 +54,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC self.init() - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { titleServerUrl = "/" } else { titleServerUrl = (serverUrl as NSString).lastPathComponent @@ -365,7 +365,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC CCUtility.setDirectoryScanDocuments(serverUrl!) self.serverUrl = serverUrl! - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { self.titleServerUrl = "/" } else { self.titleServerUrl = (serverUrl! as NSString).lastPathComponent @@ -412,7 +412,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC conflict.serverUrl = serverUrl conflict.metadatasUploadInConflict = [metadataForUpload] conflict.delegate = self - conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) self.present(conflict, animated: true, completion: nil) @@ -582,7 +582,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC NCActivityIndicator.shared.stop() - appDelegate.networkingProcessUpload?.createProcessUploads(metadatas: [metadata], completion: { _ in }) + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: [metadata], completion: { _ in }) // Request delete all image scanned let alertController = UIAlertController(title: "", message: NSLocalizedString("_delete_all_scanned_images_", comment: ""), preferredStyle: .alert) diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift index d38a6cce5..1a6c74271 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift @@ -91,7 +91,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud public func setup(serverUrl: String, fileNamePath: String, fileName: String) { - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { titleServerUrl = "/" } else { titleServerUrl = (serverUrl as NSString).lastPathComponent @@ -196,7 +196,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud self.serverUrl = serverUrl! - if serverUrl == NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) { + if serverUrl == NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) { self.titleServerUrl = "/" } else { self.titleServerUrl = (serverUrl! as NSString).lastPathComponent @@ -239,7 +239,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud conflict.serverUrl = serverUrl conflict.metadatasUploadInConflict = [metadataForUpload] conflict.delegate = self - conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) self.present(conflict, animated: true, completion: nil) @@ -263,7 +263,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud CCUtility.copyFile(atPath: self.fileNamePath, toPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)) - appDelegate.networkingProcessUpload?.createProcessUploads(metadatas: [metadata], completion: { _ in }) + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: [metadata], completion: { _ in }) self.dismiss(animated: true, completion: nil) } diff --git a/iOSClient/Main/NCFunctionCenter.swift b/iOSClient/Main/NCFunctionCenter.swift index c8fd1c6f1..baa2aafad 100644 --- a/iOSClient/Main/NCFunctionCenter.swift +++ b/iOSClient/Main/NCFunctionCenter.swift @@ -352,9 +352,9 @@ import Photos if let indicatorView = hud.indicatorView as? JGProgressHUDRingIndicatorView { indicatorView.ringWidth = 1.5 } - hud.show(in: (appDelegate.window?.rootViewController?.view)!) hud.textLabel.text = NSLocalizedString("_saving_", comment: "") - + hud.show(in: (appDelegate.window?.rootViewController?.view)!) + NCLivePhoto.generate(from: fileNameImage, videoURL: fileNameMov, progress: { progress in hud.progress = Float(progress) @@ -466,7 +466,7 @@ import Photos DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { var topNavigationController: UINavigationController? - var pushServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: self.appDelegate.account) + var pushServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId) guard var mostViewController = self.appDelegate.window?.rootViewController?.topMostViewController() else { return } if mostViewController.isModal { @@ -545,7 +545,7 @@ import Photos copyItems.append(item) } - let homeUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + let homeUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) var serverUrl = copyItems[0].serverUrl // Setup view controllers such that the current view is of the same directory the items to be copied are in @@ -594,7 +594,7 @@ import Photos guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return UIMenu() } - let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) var titleDeleteConfirmFile = NSLocalizedString("_delete_file_", comment: "") if metadata.directory { titleDeleteConfirmFile = NSLocalizedString("_delete_folder_", comment: "") } var titleSave: String = NSLocalizedString("_save_selected_files_", comment: "") diff --git a/iOSClient/Main/NCPickerViewController.swift b/iOSClient/Main/NCPickerViewController.swift index be8f7af75..0621f7149 100644 --- a/iOSClient/Main/NCPickerViewController.swift +++ b/iOSClient/Main/NCPickerViewController.swift @@ -169,13 +169,13 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { conflict.delegate = appDelegate conflict.serverUrl = serverUrl conflict.metadatasUploadInConflict = [metadataForUpload] - conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase) + conflict.isE2EE = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) appDelegate.window?.rootViewController?.present(conflict, animated: true, completion: nil) } } else { - appDelegate.networkingProcessUpload?.createProcessUploads(metadatas: [metadataForUpload], completion: { _ in }) + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: [metadataForUpload], completion: { _ in }) } } else { diff --git a/iOSClient/Media/NCMedia.swift b/iOSClient/Media/NCMedia.swift index 660c42f65..17ee00c74 100644 --- a/iOSClient/Media/NCMedia.swift +++ b/iOSClient/Media/NCMedia.swift @@ -274,7 +274,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate { func dismissSelect(serverUrl: String?, metadata: tableMetadata?, type: String, items: [Any], overwrite: Bool, copy: Bool, move: Bool) { guard let serverUrl = serverUrl else { return } - let path = CCUtility.returnPathfromServerUrl(serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account) ?? "" + let path = CCUtility.returnPathfromServerUrl(serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account) ?? "" NCManageDatabase.shared.setAccountMediaPath(path, account: appDelegate.account) reloadDataSourceWithCompletion { _ in self.searchNewMedia() @@ -449,7 +449,7 @@ extension NCMedia { if let activeAccount = NCManageDatabase.shared.getActiveAccount() { self.mediaPath = activeAccount.mediaPath } - let startServerUrl = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + mediaPath + let startServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) + mediaPath predicateDefault = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (classFile == %@ OR classFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.account, startServerUrl, NKCommon.typeClassFile.image.rawValue, NKCommon.typeClassFile.video.rawValue) diff --git a/iOSClient/Menu/AppDelegate+Menu.swift b/iOSClient/Menu/AppDelegate+Menu.swift index 559c78d78..d04bb97d7 100644 --- a/iOSClient/Menu/AppDelegate+Menu.swift +++ b/iOSClient/Menu/AppDelegate+Menu.swift @@ -35,7 +35,7 @@ extension AppDelegate { let appDelegate = UIApplication.shared.delegate as! AppDelegate let directEditingCreators = NCManageDatabase.shared.getDirectEditingCreators(account: appDelegate.account) - let isEncrypted = CCUtility.isFolderEncrypted(appDelegate.activeServerUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase) + let isEncrypted = CCUtility.isFolderEncrypted(appDelegate.activeServerUrl, e2eEncrypted: false, account: appDelegate.account, urlBase: appDelegate.urlBase, userId: appDelegate.userId) let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, appDelegate.activeServerUrl)) let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor) diff --git a/iOSClient/Menu/NCCollectionViewCommon+Menu.swift b/iOSClient/Menu/NCCollectionViewCommon+Menu.swift index 93fd5cd0a..600ac9bb3 100644 --- a/iOSClient/Menu/NCCollectionViewCommon+Menu.swift +++ b/iOSClient/Menu/NCCollectionViewCommon+Menu.swift @@ -38,8 +38,8 @@ extension NCCollectionViewCommon { guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadata.ocId) else { return } let serverUrl = metadata.serverUrl + "/" + metadata.fileName - let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) - let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(account: appDelegate.account) + let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) + let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) let isOffline: Bool if metadata.directory, let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl)) { diff --git a/iOSClient/Menu/NCViewer+Menu.swift b/iOSClient/Menu/NCViewer+Menu.swift index 1429e72a1..c6ebba9b8 100644 --- a/iOSClient/Menu/NCViewer+Menu.swift +++ b/iOSClient/Menu/NCViewer+Menu.swift @@ -35,7 +35,7 @@ extension NCViewer { var titleFavorite = NSLocalizedString("_add_favorites_", comment: "") if metadata.favorite { titleFavorite = NSLocalizedString("_remove_favorites_", comment: "") } let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) - let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) let isOffline = localFile?.offline == true // diff --git a/iOSClient/Menu/UIViewController+Menu.swift b/iOSClient/Menu/UIViewController+Menu.swift index b61ca8173..d3ccff46c 100644 --- a/iOSClient/Menu/UIViewController+Menu.swift +++ b/iOSClient/Menu/UIViewController+Menu.swift @@ -65,7 +65,7 @@ extension UIViewController { let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor) guard serverVersionMajor >= NCGlobal.shared.nextcloudVersion23 else { return } - NextcloudKit.shared.getHovercard(for: userId) { account, card, data, _ in + NextcloudKit.shared.getHovercard(for: userId) { account, card, _, _ in guard let card = card, account == appDelegate.account else { return } let personHeader = NCMenuAction( diff --git a/iOSClient/More/NCMore.swift b/iOSClient/More/NCMore.swift index 09b2522e0..c4bdc16bf 100644 --- a/iOSClient/More/NCMore.swift +++ b/iOSClient/More/NCMore.swift @@ -167,6 +167,7 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { settingsMenu.append(item) // ITEM: Test API + /* if NCUtility.shared.isSimulator() { item = NKExternalSite() item.name = "Test API" @@ -174,7 +175,8 @@ class NCMore: UIViewController, UITableViewDelegate, UITableViewDataSource { item.url = "test" settingsMenu.append(item) } - + */ + if quotaMenu.count > 0 { let item = quotaMenu[0] labelQuotaExternalSite.text = item.name diff --git a/iOSClient/NCGlobal.swift b/iOSClient/NCGlobal.swift index b914c3fef..252db23d9 100644 --- a/iOSClient/NCGlobal.swift +++ b/iOSClient/NCGlobal.swift @@ -101,7 +101,12 @@ class NCGlobal: NSObject { // @objc let appName = "files" @objc let talkName = "talk-message" - + + // DAV - + // + @objc let dav = "remote.php/dav" + @objc let davfiles = "remote.php/dav/files/" + // Nextcloud version // let nextcloudVersion12: Int = 12 @@ -323,10 +328,6 @@ class NCGlobal: NSObject { let metadataStatusUploading: Int = 3 let metadataStatusUploadError: Int = 4 - // Upload Operation Background - // - let maxConcurrentOperationUpload = 10 - // Notification Center // @objc let notificationCenterApplicationDidEnterBackground = "applicationDidEnterBackground" @@ -399,11 +400,11 @@ class NCGlobal: NSObject { // WIDGET ACTION // - let widgetActionNoAction = URL(string: "nextcloud://open-action?action=no-action")! - let widgetActionUploadAsset = URL(string: "nextcloud://open-action?action=upload-asset")! - let widgetActionScanDocument = URL(string: "nextcloud://open-action?action=add-scan-document")! - let widgetActionTextDocument = URL(string: "nextcloud://open-action?action=create-text-document")! - let widgetActionVoiceMemo = URL(string: "nextcloud://open-action?action=create-voice-memo")! + let widgetActionNoAction = "nextcloud://open-action?action=no-action" + let widgetActionUploadAsset = "nextcloud://open-action?action=upload-asset" + let widgetActionScanDocument = "nextcloud://open-action?action=add-scan-document" + let widgetActionTextDocument = "nextcloud://open-action?action=create-text-document" + let widgetActionVoiceMemo = "nextcloud://open-action?action=create-voice-memo" // APPCONFIG // diff --git a/iOSClient/Networking/NCAutoUpload.swift b/iOSClient/Networking/NCAutoUpload.swift index 22eef062f..7919dc4cb 100644 --- a/iOSClient/Networking/NCAutoUpload.swift +++ b/iOSClient/Networking/NCAutoUpload.swift @@ -82,7 +82,7 @@ class NCAutoUpload: NSObject { return } - let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: account.urlBase, account: account.account) + let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: account.urlBase, userId: account.userId, account: account.account) var metadatas: [tableMetadata] = [] self.getCameraRollAssets(viewController: viewController, account: account, selector: selector, alignPhotoLibrary: false) { assets in @@ -93,7 +93,7 @@ class NCAutoUpload: NSObject { } NKCommon.shared.writeLog("[INFO] Automatic upload, new \(assets.count) assets found [" + log + "]") // Create the folder for auto upload & if request the subfolders - if !NCNetworking.shared.createFolder(assets: assets, selector: selector, useSubFolder: account.autoUploadCreateSubfolder, account: account.account, urlBase: account.urlBase) { + if !NCNetworking.shared.createFolder(assets: assets, selector: selector, useSubFolder: account.autoUploadCreateSubfolder, account: account.account, urlBase: account.urlBase, userId: account.userId) { if selector == NCGlobal.shared.selectorUploadAutoUploadAll { let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_error_createsubfolders_upload_") NCContentPresenter.shared.showError(error: error, priority: .max) @@ -107,15 +107,15 @@ class NCAutoUpload: NSObject { var livePhoto = false var session: String = "" - guard let assetDate = asset.creationDate else { continue } + let dateFormatter = DateFormatter() + let assetDate = asset.creationDate ?? Date() + dateFormatter.dateFormat = "yyyy" + let year = dateFormatter.string(from: assetDate) + dateFormatter.dateFormat = "MM" + let month = dateFormatter.string(from: assetDate) let assetMediaType = asset.mediaType var serverUrl: String = "" let fileName = CCUtility.createFileName(asset.value(forKey: "filename") as? String, fileDate: assetDate, fileType: assetMediaType, keyFileName: NCGlobal.shared.keyFileNameAutoUploadMask, keyFileNameType: NCGlobal.shared.keyFileNameAutoUploadType, keyFileNameOriginal: NCGlobal.shared.keyFileNameOriginalAutoUpload, forcedNewFileName: false)! - let formatter = DateFormatter() - formatter.dateFormat = "yyyy" - let yearString = formatter.string(from: assetDate) - formatter.dateFormat = "MM" - let monthString = formatter.string(from: assetDate) if asset.mediaSubtypes.contains(.photoLive) && CCUtility.getLivePhoto() { livePhoto = true @@ -136,7 +136,7 @@ class NCAutoUpload: NSObject { } if account.autoUploadCreateSubfolder { - serverUrl = autoUploadPath + "/" + yearString + "/" + monthString + serverUrl = autoUploadPath + "/" + year + "/" + month } else { serverUrl = autoUploadPath } @@ -144,9 +144,11 @@ class NCAutoUpload: NSObject { // MOST COMPATIBLE SEARCH --> HEIC --> JPG var fileNameSearchMetadata = fileName let ext = (fileNameSearchMetadata as NSString).pathExtension.uppercased() + if ext == "HEIC" && CCUtility.getFormatCompatibility() { fileNameSearchMetadata = (fileNameSearchMetadata as NSString).deletingPathExtension + ".jpg" } + if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView == %@", account.account, serverUrl, fileNameSearchMetadata)) != nil { if selector == NCGlobal.shared.selectorUploadAutoUpload { NCManageDatabase.shared.addPhotoLibrary([asset], account: account.account) @@ -171,19 +173,9 @@ class NCAutoUpload: NSObject { } self.endForAssetToUpload = true - if selector == NCGlobal.shared.selectorUploadAutoUploadAll || self.applicationState == .active { - NKCommon.shared.writeLog("[INFO] Start createProcessUploads") - self.appDelegate?.networkingProcessUpload?.createProcessUploads(metadatas: metadatas, completion: completion) - } else { - NKCommon.shared.writeLog("[INFO] Start createUploadProcessAutoUploadInBackground") - var metadatasForUpload: [tableMetadata] = [] - for metadata in metadatas { - if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ && serverUrl == %@ && fileName == %@ && session != ''", metadata.account, metadata.serverUrl, metadata.fileName)) != nil { continue } - metadatasForUpload.append(metadata) - } - NCManageDatabase.shared.addMetadatas(metadatasForUpload) - NCNetworking.shared.createUploadProcessAutoUploadInBackground(completion: completion) - } + + NKCommon.shared.writeLog("[INFO] Start createProcessUploads") + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: metadatas, completion: completion) } } @@ -234,13 +226,14 @@ class NCAutoUpload: NSObject { let assets: PHFetchResult<PHAsset> = PHAsset.fetchAssets(in: assetCollection.firstObject!, options: fetchOptions) if selector == NCGlobal.shared.selectorUploadAutoUpload { - var creationDate = "" - var idAsset = "" - let idsAsset = NCManageDatabase.shared.getPhotoLibraryIdAsset(image: account.autoUploadImage, video: account.autoUploadVideo, account: account.account) + let idAssets = NCManageDatabase.shared.getPhotoLibraryIdAsset(image: account.autoUploadImage, video: account.autoUploadVideo, account: account.account) assets.enumerateObjects { asset, _, _ in - if asset.creationDate != nil { creationDate = String(describing: asset.creationDate!) } - idAsset = account.account + asset.localIdentifier + creationDate - if !(idsAsset?.contains(idAsset) ?? false) { + var creationDateString = "" + if let creationDate = asset.creationDate { + creationDateString = String(describing: creationDate) + } + let idAsset = account.account + asset.localIdentifier + creationDateString + if !(idAssets?.contains(idAsset) ?? false) { newAssets.append(asset) } } diff --git a/iOSClient/Networking/NCNetworking.swift b/iOSClient/Networking/NCNetworking.swift index 9a52f7a26..9852ba384 100644 --- a/iOSClient/Networking/NCNetworking.swift +++ b/iOSClient/Networking/NCNetworking.swift @@ -173,16 +173,13 @@ import Photos } } #endif - - if let serverTrust: SecTrust = protectionSpace.serverTrust, let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) { - + + if let serverTrust: SecTrust = protectionSpace.serverTrust, let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) { + // extarct certificate txt saveX509Certificate(certificate, host: host, directoryCertificate: directoryCertificate) - var secresult = SecTrustResultType.invalid - let status = SecTrustEvaluate(serverTrust, &secresult) - let isServerTrusted = SecTrustEvaluateWithError(serverTrust, nil) - + let isServerTrusted = SecTrustEvaluateWithError(serverTrust, nil) let certificateCopyData = SecCertificateCopyData(certificate) let data = CFDataGetBytePtr(certificateCopyData); let size = CFDataGetLength(certificateCopyData); @@ -192,7 +189,7 @@ import Photos if isServerTrusted { isTrusted = true - } else if status == errSecSuccess, let certificateDataSaved = NSData(contentsOfFile: certificateSavedPath), certificateData.isEqual(to: certificateDataSaved as Data) { + } else if let certificateDataSaved = NSData(contentsOfFile: certificateSavedPath), certificateData.isEqual(to: certificateDataSaved as Data) { isTrusted = true } else { isTrusted = false @@ -558,6 +555,10 @@ import Photos } } + // Update Badge + let counterBadge = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d OR status == %d", NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUpdateBadgeNumber, userInfo: ["counter":counterBadge.count]) + self.uploadMetadataInBackground.removeValue(forKey: fileName + serverUrl) self.delegate?.uploadComplete?(fileName: fileName, serverUrl: serverUrl, ocId: ocId, etag: etag, date: date, size: size, description: description, task: task, error: error) } @@ -593,55 +594,6 @@ import Photos } } - func createUploadProcessAutoUploadInBackground(completion: @escaping (_ items: Int) -> Void) { - - var numStartUpload: Int = 0 - let isWiFi = NCNetworking.shared.networkReachability == NKCommon.typeReachability.reachableEthernetOrWiFi - - let metadatasInUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) - let counterUpload = NCGlobal.shared.maxConcurrentOperationUpload - metadatasInUpload.count - if counterUpload <= 0 { return completion(0) } - - // Extract file - let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "sessionSelector == %@ AND status == %d", NCGlobal.shared.selectorUploadAutoUpload, NCGlobal.shared.metadataStatusWaitUpload), page: 0, limit: counterUpload, sorted: "date", ascending: true) - for metadata in metadatas { - - let metadata = tableMetadata.init(value: metadata) - let semaphore = DispatchSemaphore(value: 0) - - NCUtility.shared.extractFiles(from: metadata) { metadatas in - if metadatas.isEmpty { - NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) - } - for metadata in metadatas { - if (metadata.e2eEncrypted || metadata.chunk) { - NKCommon.shared.writeLog("[INFO] Autoupload file skipped, E2E:\(metadata.e2eEncrypted) - CHUNK:\(metadata.chunk)") - continue - } - if (metadata.session == NCNetworking.shared.sessionIdentifierBackgroundWWan && !isWiFi) { - NKCommon.shared.writeLog("[INFO] Autoupload file skipped, required WiFi") - continue - } - guard let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusInUpload) else { - NKCommon.shared.writeLog("[INFO] Autoupload file skipped, file status in upload error") - continue - } - // Upload - let semaphoreUpload = DispatchSemaphore(value: 1) - NCNetworking.shared.upload(metadata: metadata) { - numStartUpload += 1 - } completion: { error in - semaphoreUpload.signal() - } - semaphoreUpload.wait() - } - semaphore.signal() - } - semaphore.wait() - } - completion(numStartUpload) - } - func getOcIdInBackgroundSession(queue: DispatchQueue = .main, completion: @escaping (_ listOcId: [String]) -> Void) { var listOcId: [String] = [] @@ -815,7 +767,7 @@ import Photos return } - let isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted: file.e2eEncrypted, account: account, urlBase: file.urlBase) + let isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted: file.e2eEncrypted, account: account, urlBase: file.urlBase, userId: file.userId) let metadata = NCManageDatabase.shared.convertNCFileToMetadata(file, isEncrypted: isEncrypted, account: account) completion(account, metadata, error) @@ -1000,14 +952,14 @@ import Photos // MARK: - WebDav Create Folder - @objc func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, overwrite: Bool = false, completion: @escaping (_ error: NKError) -> Void) { + @objc func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String, overwrite: Bool = false, completion: @escaping (_ error: NKError) -> Void) { - let isDirectoryEncrypted = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: account, urlBase: urlBase) + let isDirectoryEncrypted = CCUtility.isFolderEncrypted(serverUrl, e2eEncrypted: false, account: account, urlBase: urlBase, userId: userId) let fileName = fileName.trimmingCharacters(in: .whitespacesAndNewlines) if isDirectoryEncrypted { #if !EXTENSION - NCNetworkingE2EE.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, completion: completion) + NCNetworkingE2EE.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, completion: completion) #endif } else { createFolderPlain(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, overwrite: overwrite, completion: completion) @@ -1052,18 +1004,18 @@ import Photos } } - func createFolder(assets: [PHAsset], selector: String, useSubFolder: Bool, account: String, urlBase: String) -> Bool { + func createFolder(assets: [PHAsset], selector: String, useSubFolder: Bool, account: String, urlBase: String, userId: String) -> Bool { - let serverUrl = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: urlBase, account: account) + let serverUrl = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: urlBase, userId: userId, account: account) let fileName = NCManageDatabase.shared.getAccountAutoUploadFileName() - let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: urlBase, account: account) - var result = createFolderWithSemaphore(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase) + let autoUploadPath = NCManageDatabase.shared.getAccountAutoUploadPath(urlBase: urlBase, userId: userId, account: account) + var result = createFolderWithSemaphore(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId) if useSubFolder && result { - for dateSubFolder in CCUtility.createNameSubFolder(assets) { - let fileName = (dateSubFolder as! NSString).lastPathComponent - let serverUrl = ((autoUploadPath + "/" + (dateSubFolder as! String)) as NSString).deletingLastPathComponent - result = createFolderWithSemaphore(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase) + for dateSubFolder in createNameSubFolder(assets: assets) { + let fileName = (dateSubFolder as NSString).lastPathComponent + let serverUrl = ((autoUploadPath + "/" + dateSubFolder) as NSString).deletingLastPathComponent + result = createFolderWithSemaphore(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId) if !result { break } } } @@ -1071,12 +1023,12 @@ import Photos return result } - private func createFolderWithSemaphore(fileName: String, serverUrl: String, account: String, urlBase: String) -> Bool { + private func createFolderWithSemaphore(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String) -> Bool { var result: Bool = false let semaphore = DispatchSemaphore(value: 0) - NCNetworking.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, overwrite: true) { error in + NCNetworking.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, overwrite: true) { error in if error == .success { result = true } semaphore.signal() } @@ -1085,6 +1037,23 @@ import Photos return result } + func createNameSubFolder(assets: [PHAsset]) -> [String] { + + var datesSubFolder: [String] = [] + let dateFormatter = DateFormatter() + + for asset in assets { + let date = asset.creationDate ?? Date() + dateFormatter.dateFormat = "yyyy" + let year = dateFormatter.string(from: date) + dateFormatter.dateFormat = "MM" + let month = dateFormatter.string(from: date) + datesSubFolder.append("\(year)/\(month)") + } + + return Array(Set(datesSubFolder)) + } + // MARK: - WebDav Delete @objc func deleteMetadata(_ metadata: tableMetadata, onlyLocalCache: Bool, completion: @escaping (_ error: NKError) -> Void) { @@ -1114,7 +1083,7 @@ import Photos return completion(NKError()) } - let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) if isDirectoryEncrypted { @@ -1199,7 +1168,7 @@ import Photos private func favoriteMetadataPlain(_ metadata: tableMetadata, completion: @escaping (_ error: NKError) -> Void) { - let fileName = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)! + let fileName = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! let favorite = !metadata.favorite let ocId = metadata.ocId @@ -1263,7 +1232,7 @@ import Photos @objc func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, viewController: UIViewController?, completion: @escaping (_ error: NKError) -> Void) { - let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let isDirectoryEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) let fileNameNew = fileNameNew.trimmingCharacters(in: .whitespacesAndNewlines) let fileNameNewLive = (fileNameNew as NSString).deletingPathExtension + ".mov" diff --git a/iOSClient/Networking/NCNetworkingChunkedUpload.swift b/iOSClient/Networking/NCNetworkingChunkedUpload.swift index 9f66cfeae..62f0f6e80 100644 --- a/iOSClient/Networking/NCNetworkingChunkedUpload.swift +++ b/iOSClient/Networking/NCNetworkingChunkedUpload.swift @@ -30,7 +30,7 @@ extension NCNetworking { let directoryProviderStorageOcId = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)! let chunkFolder = NCManageDatabase.shared.getChunkFolder(account: metadata.account, ocId: metadata.ocId) - let chunkFolderPath = metadata.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: metadata.account) + "/uploads/" + metadata.userId + "/" + chunkFolder + let chunkFolderPath = metadata.urlBase + "/" + NCGlobal.shared.dav + "/uploads/" + metadata.userId + "/" + chunkFolder let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)! let chunkSize = CCUtility.getChunkSize() let fileSizeInGB = Double(metadata.size) / 1e9 @@ -134,8 +134,8 @@ extension NCNetworking { // Assembling the chunks let serverUrlFileNameSource = chunkFolderPath + "/.file" - let pathServerUrl = CCUtility.returnPathfromServerUrl(metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)! - let serverUrlFileNameDestination = metadata.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: metadata.account) + "/files/" + metadata.userId + pathServerUrl + "/" + metadata.fileName + let pathServerUrl = CCUtility.returnPathfromServerUrl(metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! + let serverUrlFileNameDestination = metadata.urlBase + "/" + NCGlobal.shared.davfiles + metadata.userId + pathServerUrl + "/" + metadata.fileName var customHeader: [String: String] = [:] let creationDate = "\(metadata.creationDate.timeIntervalSince1970)" diff --git a/iOSClient/Networking/NCNetworkingE2EE.swift b/iOSClient/Networking/NCNetworkingE2EE.swift index 99916f4fe..80b2eba27 100644 --- a/iOSClient/Networking/NCNetworkingE2EE.swift +++ b/iOSClient/Networking/NCNetworkingE2EE.swift @@ -33,7 +33,7 @@ import Alamofire // MARK: - WebDav Create Folder - func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, completion: @escaping (_ error: NKError) -> Void) { + func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String, completion: @escaping (_ error: NKError) -> Void) { var fileNameFolder = CCUtility.removeForbiddenCharactersServer(fileName)! var fileNameFolderUrl = "" @@ -90,7 +90,7 @@ import Alamofire NCManageDatabase.shared.addE2eEncryption(object) - self.sendE2EMetadata(account: account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, urlBase: urlBase) { e2eToken, error in + self.sendE2EMetadata(account: account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, urlBase: urlBase, userId: userId) { e2eToken, error in // unlock if let tableLock = NCManageDatabase.shared.getE2ETokenLock(account: account, serverUrl: serverUrl) { NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, method: "DELETE") { _, _, _, _ in } @@ -134,9 +134,9 @@ import Alamofire let deleteE2eEncryption = NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", metadata.account, metadata.serverUrl, metadata.fileName) NCNetworking.shared.deleteMetadataPlain(metadata, customHeader: ["e2e-token": e2eToken!]) { error in - let home = NCUtilityFileSystem.shared.getHomeServer(account: metadata.account) + let home = NCUtilityFileSystem.shared.getHomeServer(urlBase: metadata.urlBase, userId: metadata.userId) if metadata.serverUrl != home { - self.sendE2EMetadata(account: metadata.account, serverUrl: metadata.serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: deleteE2eEncryption, urlBase: metadata.urlBase) { e2eToken, error in + self.sendE2EMetadata(account: metadata.account, serverUrl: metadata.serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: deleteE2eEncryption, urlBase: metadata.urlBase, userId: metadata.userId) { e2eToken, error in // unlock if let tableLock = NCManageDatabase.shared.getE2ETokenLock(account: metadata.account, serverUrl: metadata.serverUrl) { NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, method: "DELETE") { _, _, _, _ in } @@ -168,7 +168,7 @@ import Alamofire } else { - self.sendE2EMetadata(account: metadata.account, serverUrl: metadata.serverUrl, fileNameRename: metadata.fileName, fileNameNewRename: fileNameNew, deleteE2eEncryption: nil, urlBase: metadata.urlBase) { e2eToken, error in + self.sendE2EMetadata(account: metadata.account, serverUrl: metadata.serverUrl, fileNameRename: metadata.fileName, fileNameNewRename: fileNameNew, deleteE2eEncryption: nil, urlBase: metadata.urlBase, userId: metadata.userId) { e2eToken, error in if error == .success { NCManageDatabase.shared.setMetadataFileNameView(serverUrl: metadata.serverUrl, fileName: metadata.fileName, newFileNameView: fileNameNew, account: metadata.account) @@ -260,7 +260,7 @@ import Alamofire NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource, userInfo: ["serverUrl": metadata.serverUrl]) NCContentPresenter.shared.noteTop(text: NSLocalizedString("_upload_e2ee_", comment: ""), image: nil, type: NCContentPresenter.messageType.info, delay: NCGlobal.shared.dismissAfterSecond, priority: .max) - NCNetworkingE2EE.shared.sendE2EMetadata(account: metadata.account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, urlBase: metadata.urlBase, upload: true) { e2eToken, error in + NCNetworkingE2EE.shared.sendE2EMetadata(account: metadata.account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, urlBase: metadata.urlBase, userId: metadata.userId, upload: true) { e2eToken, error in start() @@ -384,7 +384,7 @@ import Alamofire } } - @objc func sendE2EMetadata(account: String, serverUrl: String, fileNameRename: String?, fileNameNewRename: String?, deleteE2eEncryption: NSPredicate?, urlBase: String, upload: Bool = false, completion: @escaping (_ e2eToken: String?, _ error: NKError) -> Void) { + @objc func sendE2EMetadata(account: String, serverUrl: String, fileNameRename: String?, fileNameNewRename: String?, deleteE2eEncryption: NSPredicate?, urlBase: String, userId: String, upload: Bool = false, completion: @escaping (_ e2eToken: String?, _ error: NKError) -> Void) { self.lock(account: account, serverUrl: serverUrl) { directory, e2eToken, error in if error == .success && e2eToken != nil && directory != nil { @@ -394,7 +394,7 @@ import Alamofire var e2eMetadataNew: String? if error == .success && e2eMetadata != nil { - if !NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata!, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: serverUrl, account: account, urlBase: urlBase) { + if !NCEndToEndMetadata.shared.decoderMetadata(e2eMetadata!, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId) { return completion(e2eToken, NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: NSLocalizedString("_e2e_error_encode_metadata_", comment: ""))) } method = "PUT" @@ -402,7 +402,7 @@ import Alamofire // Rename if fileNameRename != nil && fileNameNewRename != nil { - NCManageDatabase.shared.renameFileE2eEncryption(serverUrl: serverUrl, fileNameIdentifier: fileNameRename!, newFileName: fileNameNewRename!, newFileNamePath: CCUtility.returnFileNamePath(fromFileName: fileNameNewRename!, serverUrl: serverUrl, urlBase: urlBase, account: account)) + NCManageDatabase.shared.renameFileE2eEncryption(serverUrl: serverUrl, fileNameIdentifier: fileNameRename!, newFileName: fileNameNewRename!, newFileNamePath: CCUtility.returnFileNamePath(fromFileName: fileNameNewRename!, serverUrl: serverUrl, urlBase: urlBase, userId: userId, account: account)) } // Delete diff --git a/iOSClient/Networking/NCNetworkingProcessUpload.swift b/iOSClient/Networking/NCNetworkingProcessUpload.swift index 375528e84..47757d533 100644 --- a/iOSClient/Networking/NCNetworkingProcessUpload.swift +++ b/iOSClient/Networking/NCNetworkingProcessUpload.swift @@ -24,161 +24,177 @@ import UIKit import NextcloudKit import Photos +import JGProgressHUD class NCNetworkingProcessUpload: NSObject { + public static let shared: NCNetworkingProcessUpload = { + let instance = NCNetworkingProcessUpload() + return instance + }() - let appDelegate = UIApplication.shared.delegate as? AppDelegate + var timerProcess: Timer? - override init() { - super.init() - startTimer() + func startTimer() { + DispatchQueue.main.async { + self.timerProcess?.invalidate() + self.timerProcess = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.processTimer), userInfo: nil, repeats: true) + } } - private func startProcess() { - if appDelegate?.timerProcess?.isValid ?? false { - DispatchQueue.main.async { self.process() } + func stopTimer() { + DispatchQueue.main.async { + self.timerProcess?.invalidate() } } - func startTimer() { - appDelegate?.timerProcess?.invalidate() - appDelegate?.timerProcess = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(process), userInfo: nil, repeats: true) + @objc func processTimer() { + process { _ in } } - func stopTimer() { - appDelegate?.timerProcess?.invalidate() - } + func process(completition: @escaping (_ items: Int) -> Void) { - @objc private func process() { - - guard let account = NCManageDatabase.shared.getActiveAccount(), UIApplication.shared.applicationState == .active else { return } - let metadatasUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) - if metadatasUpload.filter({ $0.chunk || $0.e2eEncrypted }).count > 0 { return } - let isWiFi = NCNetworking.shared.networkReachability == NKCommon.typeReachability.reachableEthernetOrWiFi + guard let account = NCManageDatabase.shared.getActiveAccount() else { return } stopTimer() - var counterUpload: Int = 0 - let sessionSelectors = [NCGlobal.shared.selectorUploadFileNODelete, NCGlobal.shared.selectorUploadFile, NCGlobal.shared.selectorUploadAutoUpload, NCGlobal.shared.selectorUploadAutoUploadAll] + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let applicationState = UIApplication.shared.applicationState + let isPasscodePresented = appDelegate.isPasscodePresented() + let queue = DispatchQueue.global() + var maxConcurrentOperationUpload = 10 + let viewController = appDelegate.window?.rootViewController + let hud = JGProgressHUD() - counterUpload = metadatasUpload.count + queue.async { - print("[LOG] PROCESS-UPLOAD \(counterUpload)") + let metadatasUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) + let isWiFi = NCNetworking.shared.networkReachability == NKCommon.typeReachability.reachableEthernetOrWiFi + var counterUpload: Int = 0 + let sessionSelectors = [NCGlobal.shared.selectorUploadFileNODelete, NCGlobal.shared.selectorUploadFile, NCGlobal.shared.selectorUploadAutoUpload, NCGlobal.shared.selectorUploadAutoUploadAll] - // Update Badge - let counterBadge = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d OR status == %d", NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUpdateBadgeNumber, userInfo: ["counter":counterBadge.count]) + counterUpload = metadatasUpload.count - NCNetworking.shared.getOcIdInBackgroundSession(queue: DispatchQueue.global(), completion: { listOcId in + print("[LOG] PROCESS-UPLOAD \(counterUpload)") - for sessionSelector in sessionSelectors where counterUpload < NCGlobal.shared.maxConcurrentOperationUpload { + // Update Badge + let counterBadge = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d OR status == %d", NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)) + NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUpdateBadgeNumber, userInfo: ["counter":counterBadge.count]) - let limit = NCGlobal.shared.maxConcurrentOperationUpload - counterUpload - let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "sessionSelector == %@ AND status == %d", sessionSelector, NCGlobal.shared.metadataStatusWaitUpload), page: 1, limit: limit, sorted: "date", ascending: true) - if metadatas.count > 0 { - NKCommon.shared.writeLog("[INFO] PROCESS-UPLOAD find \(metadatas.count) items") - } + NCNetworking.shared.getOcIdInBackgroundSession(queue: queue, completion: { listOcId in - for metadata in metadatas where counterUpload < NCGlobal.shared.maxConcurrentOperationUpload { + for sessionSelector in sessionSelectors where counterUpload < maxConcurrentOperationUpload { - // Different account - if account.account != metadata.account { - NKCommon.shared.writeLog("[INFO] Process auto upload skipped file: \(metadata.serverUrl)/\(metadata.fileNameView) on account: \(metadata.account), because the actual account is \(account.account).") - continue + let limit = maxConcurrentOperationUpload - counterUpload + let metadatas = NCManageDatabase.shared.getAdvancedMetadatas(predicate: NSPredicate(format: "sessionSelector == %@ AND status == %d", sessionSelector, NCGlobal.shared.metadataStatusWaitUpload), page: 1, limit: limit, sorted: "date", ascending: true) + if metadatas.count > 0 { + NKCommon.shared.writeLog("[INFO] PROCESS-UPLOAD find \(metadatas.count) items") } - // Is already in upload background? skipped - if listOcId.contains(metadata.ocId) { - NKCommon.shared.writeLog("[INFO] Process auto upload skipped file: \(metadata.serverUrl)/\(metadata.fileNameView), because is already in session.") - continue - } + for metadata in metadatas where counterUpload < maxConcurrentOperationUpload { - // Session Extension ? skipped - if metadata.session == NCNetworking.shared.sessionIdentifierBackgroundExtension { - continue - } + // Different account + if account.account != metadata.account { + NKCommon.shared.writeLog("[INFO] Process auto upload skipped file: \(metadata.serverUrl)/\(metadata.fileNameView) on account: \(metadata.account), because the actual account is \(account.account).") + continue + } - let semaphore = DispatchSemaphore(value: 0) - NCUtility.shared.extractFiles(from: metadata) { metadatas in - if metadatas.isEmpty { - NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + // Is already in upload background? skipped + if listOcId.contains(metadata.ocId) { + NKCommon.shared.writeLog("[INFO] Process auto upload skipped file: \(metadata.serverUrl)/\(metadata.fileNameView), because is already in session.") + continue } - for metadata in metadatas { - if !isWiFi && metadata.session == NCNetworking.shared.sessionIdentifierBackgroundWWan { - continue - } + // Chunk or E2EE ... only one ? skipped + if metadatasUpload.filter({ $0.chunk || $0.e2eEncrypted }).count > 0 { + continue + } - if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusInUpload) { - NCNetworking.shared.upload(metadata: metadata) - } + // Session Extension ? skipped + if metadata.session == NCNetworking.shared.sessionIdentifierBackgroundExtension { + continue + } - if metadata.e2eEncrypted || metadata.chunk { - // Only one - counterUpload = NCGlobal.shared.maxConcurrentOperationUpload - break - } else { - counterUpload += 1 + let semaphore = DispatchSemaphore(value: 0) + NCUtility.shared.extractFiles(from: metadata, viewController: viewController, hud: hud) { metadatas in + if metadatas.isEmpty { + NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + } + for metadata in metadatas where counterUpload < maxConcurrentOperationUpload { + + // NO WiFi + if !isWiFi && metadata.session == NCNetworking.shared.sessionIdentifierBackgroundWWan { + continue + } + + // NO E2EE, CHUCK in background + if applicationState != .active && (metadata.e2eEncrypted || metadata.chunk) { + continue + } + + if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusInUpload) { + NCNetworking.shared.upload(metadata: metadata) + if metadata.e2eEncrypted || metadata.chunk { + maxConcurrentOperationUpload = 1 + } + counterUpload += 1 + } } + semaphore.signal() } - semaphore.signal() + semaphore.wait() } - semaphore.wait() } - } - // No upload available ? --> Retry Upload in Error - if counterUpload == 0 { - let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d", NCGlobal.shared.metadataStatusUploadError)) - for metadata in metadatas { - NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCNetworking.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0, status: NCGlobal.shared.metadataStatusWaitUpload) + // No upload available ? --> Retry Upload in Error + if counterUpload == 0 { + let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "status == %d", NCGlobal.shared.metadataStatusUploadError)) + for metadata in metadatas { + NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: NCNetworking.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0, status: NCGlobal.shared.metadataStatusWaitUpload) + } } - } - - // verify delete Asset Local Identifiers in auto upload (DELETE Photos album) - DispatchQueue.main.async { - if counterUpload == 0 && !(UIApplication.shared.delegate as! AppDelegate).isPasscodePresented() { + + // verify delete Asset Local Identifiers in auto upload (DELETE Photos album) + if applicationState == .active && counterUpload == 0 && !isPasscodePresented { self.deleteAssetLocalIdentifiers(account: account.account) { self.startTimer() } - } else { + } else if applicationState == .active { self.startTimer() } - } - }) + completition(counterUpload) + }) + } } private func deleteAssetLocalIdentifiers(account: String, completition: @escaping () -> Void) { - if UIApplication.shared.applicationState != .active { - completition() - return - } - let metadatasSessionUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND session CONTAINS[cd] %@", account, "upload")) - if !metadatasSessionUpload.isEmpty { - completition() - return - } - let localIdentifiers = NCManageDatabase.shared.getAssetLocalIdentifiersUploaded(account: account) - if localIdentifiers.isEmpty { - completition() - return - } - let assets = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil) - - PHPhotoLibrary.shared().performChanges({ - PHAssetChangeRequest.deleteAssets(assets as NSFastEnumeration) - }, completionHandler: { _, _ in - DispatchQueue.main.async { - NCManageDatabase.shared.clearAssetLocalIdentifiers(localIdentifiers, account: account) + DispatchQueue.main.async { + let metadatasSessionUpload = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND session CONTAINS[cd] %@", account, "upload")) + if !metadatasSessionUpload.isEmpty { + completition() + return + } + let localIdentifiers = NCManageDatabase.shared.getAssetLocalIdentifiersUploaded(account: account) + if localIdentifiers.isEmpty { completition() + return } - }) + let assets = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil) + + PHPhotoLibrary.shared().performChanges({ + PHAssetChangeRequest.deleteAssets(assets as NSFastEnumeration) + }, completionHandler: { _, _ in + DispatchQueue.main.async { + NCManageDatabase.shared.clearAssetLocalIdentifiers(localIdentifiers, account: account) + completition() + } + }) + } } // MARK: - - @objc func createProcessUploads(metadatas: [tableMetadata], verifyAlreadyExists: Bool = false, completion: @escaping (_ items: Int) -> Void) { + func createProcessUploads(metadatas: [tableMetadata], verifyAlreadyExists: Bool = false, completion: @escaping (_ items: Int) -> Void) { var metadatasForUpload: [tableMetadata] = [] for metadata in metadatas { @@ -190,13 +206,12 @@ class NCNetworkingProcessUpload: NSObject { metadatasForUpload.append(metadata) } NCManageDatabase.shared.addMetadatas(metadatasForUpload) - startProcess() completion(metadatasForUpload.count) } // MARK: - - @objc func verifyUploadZombie() { + func verifyUploadZombie() { var session: URLSession? @@ -208,7 +223,7 @@ class NCNetworkingProcessUpload: NSObject { NCManageDatabase.shared.deleteChunks(account: metadata.account, ocId: metadata.ocId) NCUtilityFileSystem.shared.deleteFile(filePath: path) } - + // verify metadataStatusInUpload (BACKGROUND) let metadatasInUploadBackground = NCManageDatabase.shared.getMetadatas( predicate: NSPredicate( @@ -268,3 +283,4 @@ class NCNetworkingProcessUpload: NSObject { } } } + diff --git a/iOSClient/Networking/NCOperationQueue.swift b/iOSClient/Networking/NCOperationQueue.swift index 260e0f785..10af71153 100644 --- a/iOSClient/Networking/NCOperationQueue.swift +++ b/iOSClient/Networking/NCOperationQueue.swift @@ -82,7 +82,7 @@ import NextcloudKit func delete(metadata: tableMetadata, onlyLocalCache: Bool) { - let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let isFolderEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) if isFolderEncrypted { for case let operation as NCOperationDelete in deleteQueueE2EE.operations where operation.metadata.ocId == metadata.ocId { return @@ -440,7 +440,7 @@ class NCOperationDownloadThumbnail: ConcurrentOperation { self.metadata = tableMetadata.init(value: metadata) self.cell = cell self.view = view - self.fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)! + self.fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! self.fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)! self.fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)! } diff --git a/iOSClient/Networking/NCService.swift b/iOSClient/Networking/NCService.swift index a6393e3c6..67612963a 100644 --- a/iOSClient/Networking/NCService.swift +++ b/iOSClient/Networking/NCService.swift @@ -199,7 +199,7 @@ class NCService: NSObject { if error == .success { NCManageDatabase.shared.deleteTableShare(account: account) if let shares = shares, !shares.isEmpty { - NCManageDatabase.shared.addShare(urlBase: self.appDelegate.urlBase, account: account, shares: shares) + NCManageDatabase.shared.addShare(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, shares: shares) } self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: account) } diff --git a/iOSClient/Offline/NCOffline.swift b/iOSClient/Offline/NCOffline.swift index 934bf2bba..3b39693b8 100644 --- a/iOSClient/Offline/NCOffline.swift +++ b/iOSClient/Offline/NCOffline.swift @@ -103,13 +103,9 @@ class NCOffline: NCCollectionViewCommon { collectionView?.reloadData() networkReadFolder(forced: forced) { tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error in - if error == .success { - for metadata in metadatas ?? [] { - if !metadata.directory { - if NCManageDatabase.shared.isDownloadMetadata(metadata, download: true) { - NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile) - } - } + if error == .success, let metadatas = metadatas { + for metadata in metadatas where (!metadata.directory && NCManageDatabase.shared.isDownloadMetadata(metadata, download: true)) { + NCOperationQueue.shared.download(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile) } } diff --git a/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift b/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift index 5e9359357..20e2d0125 100644 --- a/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift +++ b/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift @@ -40,7 +40,7 @@ import NextcloudKit NCActivityIndicator.shared.start(backgroundView: viewController.view) - let fileNamePath = CCUtility.returnFileNamePath(fromFileName: NCGlobal.shared.fileNameRichWorkspace, serverUrl: serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)! + let fileNamePath = CCUtility.returnFileNamePath(fromFileName: NCGlobal.shared.fileNameRichWorkspace, serverUrl: serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account)! NextcloudKit.shared.NCTextCreateFile(fileNamePath: fileNamePath, editorId: directEditingCreator.editor, creatorId: directEditingCreator.identifier, templateId: "") { account, url, data, error in NCActivityIndicator.shared.stop() @@ -75,7 +75,7 @@ import NextcloudKit NCActivityIndicator.shared.start(backgroundView: viewController.view) - let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: appDelegate.urlBase, account: appDelegate.account)! + let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: appDelegate.account)! NextcloudKit.shared.NCTextOpenFile(fileNamePath: fileNamePath, editor: "text") { account, url, data, error in NCActivityIndicator.shared.stop() diff --git a/iOSClient/ScanDocument/NCScan.swift b/iOSClient/ScanDocument/NCScan.swift index 0a1e4c863..24c60179a 100755 --- a/iOSClient/ScanDocument/NCScan.swift +++ b/iOSClient/ScanDocument/NCScan.swift @@ -186,17 +186,13 @@ class NCScan: UIViewController, NCScanCellCellDelegate { @IBAction func transferDown(sender: UIButton) { - for fileName in itemsSource { + for fileName in itemsSource where !itemsDestination.contains(fileName) { - if !itemsDestination.contains(fileName) { + let fileNamePathAt = CCUtility.getDirectoryScan() + "/" + fileName + guard let data = try? Data(contentsOf: URL(fileURLWithPath: fileNamePathAt)), let image = UIImage(data: data) else { return } - let fileNamePathAt = CCUtility.getDirectoryScan() + "/" + fileName - - guard let data = try? Data(contentsOf: URL(fileURLWithPath: fileNamePathAt)), let image = UIImage(data: data) else { return } - - imagesDestination.append(image) - itemsDestination.append(fileName) - } + imagesDestination.append(image) + itemsDestination.append(fileName) } // Save button diff --git a/iOSClient/Security/NCEndToEndEncryption.m b/iOSClient/Security/NCEndToEndEncryption.m index d613957ce..be5dc793b 100644 --- a/iOSClient/Security/NCEndToEndEncryption.m +++ b/iOSClient/Security/NCEndToEndEncryption.m @@ -906,25 +906,6 @@ return keyData; } -- (NSString *)getMD5:(NSString *)input -{ - // Create pointer to the string as UTF8 - const char *ptr = [input cStringUsingEncoding:NSUTF8StringEncoding]; - - // Create byte array of unsigned chars - unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH]; - - // Create 16 byte MD5 hash value, store in buffer - CC_MD5(ptr, (unsigned int)strlen(ptr), md5Buffer); - - // Convert MD5 value in the buffer to NSString of hex values - NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; - for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) - [output appendFormat:@"%02x",md5Buffer[i]]; - - return output; -} - - (NSString *)getSHA1:(NSString *)input { const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding]; diff --git a/iOSClient/Security/NCEndToEndMetadata.swift b/iOSClient/Security/NCEndToEndMetadata.swift index fdaa8a4af..655273575 100644 --- a/iOSClient/Security/NCEndToEndMetadata.swift +++ b/iOSClient/Security/NCEndToEndMetadata.swift @@ -140,7 +140,7 @@ class NCEndToEndMetadata: NSObject { } @discardableResult - @objc func decoderMetadata(_ e2eMetaDataJSON: String, privateKey: String, serverUrl: String, account: String, urlBase: String) -> Bool { + @objc func decoderMetadata(_ e2eMetaDataJSON: String, privateKey: String, serverUrl: String, account: String, urlBase: String, userId: String) -> Bool { let jsonDecoder = JSONDecoder() let data = e2eMetaDataJSON.data(using: .utf8) @@ -199,7 +199,7 @@ class NCEndToEndMetadata: NSObject { object.authenticationTag = filesCodable.authenticationTag ?? "" object.fileName = encryptedFileAttributes.filename object.fileNameIdentifier = fileNameIdentifier - object.fileNamePath = CCUtility.returnFileNamePath(fromFileName: encryptedFileAttributes.filename, serverUrl: serverUrl, urlBase: urlBase, account: account) + object.fileNamePath = CCUtility.returnFileNamePath(fromFileName: encryptedFileAttributes.filename, serverUrl: serverUrl, urlBase: urlBase, userId: userId, account: account) object.key = encryptedFileAttributes.key object.initializationVector = filesCodable.initializationVector object.metadataKey = metadataKey! diff --git a/iOSClient/Select/NCSelect.swift b/iOSClient/Select/NCSelect.swift index 8b9ce9203..be42db581 100644 --- a/iOSClient/Select/NCSelect.swift +++ b/iOSClient/Select/NCSelect.swift @@ -168,12 +168,12 @@ class NCSelect: UIViewController, UIGestureRecognizerDelegate, UIAdaptivePresent // set the serverUrl if serverUrl == "" { - serverUrl = NCUtilityFileSystem.shared.getHomeServer(account: activeAccount.account) + serverUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) } // get auto upload folder autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName() - autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, account: activeAccount.account) + autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, userId: activeAccount.userId, account: activeAccount.account) layoutForView = NCUtility.shared.getLayoutForView(key: layoutKey, serverUrl: serverUrl) gridLayout.itemForLine = CGFloat(layoutForView?.itemForLine ?? 3) diff --git a/iOSClient/Settings/CCManageAutoUpload.m b/iOSClient/Settings/CCManageAutoUpload.m index 9256cd83b..77eee089e 100644 --- a/iOSClient/Settings/CCManageAutoUpload.m +++ b/iOSClient/Settings/CCManageAutoUpload.m @@ -218,7 +218,7 @@ // Default [[NCManageDatabase shared] setAccountAutoUploadFileName:nil]; - [[NCManageDatabase shared] setAccountAutoUploadDirectory:nil urlBase:appDelegate.urlBase account:appDelegate.account]; + [[NCManageDatabase shared] setAccountAutoUploadDirectory:nil urlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account]; // verifichiamo che almeno uno dei servizi (foto video) siano attivi, in caso contrario attiviamo le foto if (activeAccount.autoUploadImage == NO && activeAccount.autoUploadVideo == NO) { @@ -364,7 +364,7 @@ { tableAccount *activeAccount = [[NCManageDatabase shared] getActiveAccount]; NSString *sectionName; - NSString *autoUploadPath = [NSString stringWithFormat:@"%@/%@", [[NCManageDatabase shared] getAccountAutoUploadDirectoryWithUrlBase:appDelegate.urlBase account:appDelegate.account], [[NCManageDatabase shared] getAccountAutoUploadFileName]]; + NSString *autoUploadPath = [NSString stringWithFormat:@"%@/%@", [[NCManageDatabase shared] getAccountAutoUploadDirectoryWithUrlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account], [[NCManageDatabase shared] getAccountAutoUploadFileName]]; switch (section) { @@ -372,7 +372,7 @@ sectionName = NSLocalizedString(@"_autoupload_description_", nil); break; case 1: - if (activeAccount.autoUpload) sectionName = [NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"_autoupload_current_folder_", nil), [CCUtility returnPathfromServerUrl:autoUploadPath urlBase:appDelegate.urlBase account:appDelegate.account]]; + if (activeAccount.autoUpload) sectionName = [NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"_autoupload_current_folder_", nil), [CCUtility returnPathfromServerUrl:autoUploadPath urlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account]]; else sectionName = @""; break; case 4: @@ -395,7 +395,7 @@ { if (serverUrl != nil) { - NSString* home = [[NCUtilityFileSystem shared] getHomeServerWithAccount:appDelegate.account]; + NSString* home = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:appDelegate.urlBase userId:appDelegate.userId]; if ([serverUrl isEqualToString:home]) { NKError *error = [[NKError alloc] initWithErrorCode:NCGlobal.shared.errorInternalError errorDescription:@"_autoupload_error_select_folder_"]; [[NCContentPresenter shared] messageNotification:@"_error_" error:error delay:[[NCGlobal shared] dismissAfterSecond] type:messageTypeError]; @@ -406,7 +406,7 @@ [[NCManageDatabase shared] setAccountAutoUploadFileName:serverUrl.lastPathComponent]; NSString *path = [[NCUtilityFileSystem shared] deleteLastPathWithServerUrlPath:serverUrl home:home]; if (path != nil) { - [[NCManageDatabase shared] setAccountAutoUploadDirectory:path urlBase:appDelegate.urlBase account:appDelegate.account]; + [[NCManageDatabase shared] setAccountAutoUploadDirectory:path urlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account]; } // Reload [self.tableView reloadData]; diff --git a/iOSClient/Share/NCShare.swift b/iOSClient/Share/NCShare.swift index 512657fd0..6645bc5ec 100644 --- a/iOSClient/Share/NCShare.swift +++ b/iOSClient/Share/NCShare.swift @@ -87,7 +87,7 @@ class NCShare: UIViewController, NCShareNetworkingDelegate, NCSharePagingContent reloadData() - networking = NCShareNetworking(metadata: metadata, urlBase: appDelegate.urlBase, view: self.view, delegate: self) + networking = NCShareNetworking(metadata: metadata, view: self.view, delegate: self) if sharingEnabled { let isVisible = (self.navigationController?.topViewController as? NCSharePaging)?.indexPage == .sharing networking?.readShare(showLoadingIndicator: isVisible) diff --git a/iOSClient/Share/NCShareNetworking.swift b/iOSClient/Share/NCShareNetworking.swift index 0cd001d79..360e643a1 100644 --- a/iOSClient/Share/NCShareNetworking.swift +++ b/iOSClient/Share/NCShareNetworking.swift @@ -27,14 +27,12 @@ class NCShareNetworking: NSObject { private let appDelegate = UIApplication.shared.delegate as! AppDelegate - var urlBase: String weak var delegate: NCShareNetworkingDelegate? var view: UIView var metadata: tableMetadata - init(metadata: tableMetadata, urlBase: String, view: UIView, delegate: NCShareNetworkingDelegate?) { + init(metadata: tableMetadata, view: UIView, delegate: NCShareNetworkingDelegate?) { self.metadata = metadata - self.urlBase = urlBase self.view = view self.delegate = delegate @@ -46,7 +44,7 @@ class NCShareNetworking: NSObject { NCActivityIndicator.shared.start(backgroundView: view) } - let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: urlBase, account: metadata.account)! + let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! let parameter = NKShareParameter(path: filenamePath) NextcloudKit.shared.readShares(parameters: parameter) { account, shares, data, error in if showLoadingIndicator { @@ -54,7 +52,7 @@ class NCShareNetworking: NSObject { } if error == .success, let shares = shares { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: shares) + NCManageDatabase.shared.addShare(account: self.metadata.account, urlBase: self.metadata.urlBase, userId: self.metadata.userId, shares: shares) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) } else { NCContentPresenter.shared.showError(error: error) @@ -72,13 +70,13 @@ class NCShareNetworking: NSObject { // https://github.com/nextcloud/ios-communication-library/pull/104 NCActivityIndicator.shared.start(backgroundView: view) - let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: urlBase, account: metadata.account)! + let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account)! NextcloudKit.shared.createShare(path: filenamePath, shareType: option.shareType, shareWith: option.shareWith, password: option.password, permissions: option.permissions) { (account, share, data, error) in NCActivityIndicator.shared.stop() if error == .success, let share = share { option.idShare = share.idShare - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share]) + NCManageDatabase.shared.addShare(account: self.metadata.account, urlBase: self.metadata.urlBase, userId: self.metadata.userId, shares: [share]) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) if option.hasChanges(comparedTo: share) { self.updateShare(option: option) @@ -108,7 +106,7 @@ class NCShareNetworking: NSObject { NextcloudKit.shared.updateShare(idShare: option.idShare, password: option.password, expireDate: option.expDateString, permissions: option.permissions, note: option.note, label: option.label, hideDownload: option.hideDownload) { account, share, data, error in NCActivityIndicator.shared.stop() if error == .success, let share = share { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share]) + NCManageDatabase.shared.addShare(account: self.metadata.account, urlBase: self.metadata.urlBase, userId: self.metadata.userId, shares: [share]) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) self.delegate?.readShareCompleted() } else { diff --git a/iOSClient/Shares/NCShares.swift b/iOSClient/Shares/NCShares.swift index 7ce079ebc..b4dbdf7cc 100644 --- a/iOSClient/Shares/NCShares.swift +++ b/iOSClient/Shares/NCShares.swift @@ -100,7 +100,7 @@ class NCShares: NCCollectionViewCommon { if error == .success { NCManageDatabase.shared.deleteTableShare(account: account) if let shares = shares, !shares.isEmpty { - NCManageDatabase.shared.addShare(urlBase: self.appDelegate.urlBase, account: account, shares: shares) + NCManageDatabase.shared.addShare(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, shares: shares) } self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: account) self.reloadDataSource() diff --git a/iOSClient/Supporting Files/af.lproj/Localizable.strings b/iOSClient/Supporting Files/af.lproj/Localizable.strings Binary files differindex 9a138fce8..afe3cde27 100644 --- a/iOSClient/Supporting Files/af.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/af.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/an.lproj/Localizable.strings b/iOSClient/Supporting Files/an.lproj/Localizable.strings Binary files differindex e1b8c8f01..f24ad86f7 100644 --- a/iOSClient/Supporting Files/an.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/an.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ar.lproj/Localizable.strings b/iOSClient/Supporting Files/ar.lproj/Localizable.strings Binary files differindex 1c78c6dcc..ab9329081 100644 --- a/iOSClient/Supporting Files/ar.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ar.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ast.lproj/Localizable.strings b/iOSClient/Supporting Files/ast.lproj/Localizable.strings Binary files differindex 189dc6e97..2cbdd9973 100644 --- a/iOSClient/Supporting Files/ast.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ast.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/az.lproj/Localizable.strings b/iOSClient/Supporting Files/az.lproj/Localizable.strings Binary files differindex 875f6d04d..6baba2325 100644 --- a/iOSClient/Supporting Files/az.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/az.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/be.lproj/Localizable.strings b/iOSClient/Supporting Files/be.lproj/Localizable.strings Binary files differindex fd4c1abda..0eb7385a3 100644 --- a/iOSClient/Supporting Files/be.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/be.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings b/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings Binary files differindex f38ba9f3d..7c76764ea 100644 --- a/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings b/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings Binary files differindex 5bfdf340f..72020eacc 100644 --- a/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/br.lproj/Localizable.strings b/iOSClient/Supporting Files/br.lproj/Localizable.strings Binary files differindex df7174417..780587118 100644 --- a/iOSClient/Supporting Files/br.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/br.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bs.lproj/Localizable.strings b/iOSClient/Supporting Files/bs.lproj/Localizable.strings Binary files differindex 2db28b4f3..c2e044f92 100644 --- a/iOSClient/Supporting Files/bs.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bs.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ca.lproj/Localizable.strings b/iOSClient/Supporting Files/ca.lproj/Localizable.strings Binary files differindex fe294b838..5f76c2cce 100644 --- a/iOSClient/Supporting Files/ca.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ca.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings b/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings Binary files differindex 7fd86f8ff..b23199474 100644 --- a/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings b/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings Binary files differindex 6dcd96dd8..ed82c57d5 100644 --- a/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/da.lproj/Localizable.strings b/iOSClient/Supporting Files/da.lproj/Localizable.strings Binary files differindex 161f57870..9130d52c1 100644 --- a/iOSClient/Supporting Files/da.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/da.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/de.lproj/Localizable.strings b/iOSClient/Supporting Files/de.lproj/Localizable.strings Binary files differindex 5770e34a4..dfd46b8ec 100644 --- a/iOSClient/Supporting Files/de.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/de.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/el.lproj/Localizable.strings b/iOSClient/Supporting Files/el.lproj/Localizable.strings Binary files differindex 42a3bd61c..b0761613e 100644 --- a/iOSClient/Supporting Files/el.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/el.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings b/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings Binary files differindex db5357242..083b209e9 100644 --- a/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/en.lproj/Localizable.strings b/iOSClient/Supporting Files/en.lproj/Localizable.strings index c2230d118..1f9b1d551 100644 --- a/iOSClient/Supporting Files/en.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en.lproj/Localizable.strings @@ -111,6 +111,7 @@ "_force_start_" = "Force the start"; "_purchase_" = "Purchase"; "_account_not_available_" = "The account %@ of %@ does not exist, please add it to be able to read the file %@"; +"_account_not_exists_" = "The account %@ of %@ does not exist"; "_error_parameter_schema_" = "Wrong parameters, impossible to continue"; "_comments_" = "Comments"; "_sharing_" = "Sharing"; @@ -894,6 +895,9 @@ "_recent_activity_" = "Recent activity"; "_title_lockscreenwidget_" = "Status"; "_description_lockscreenwidget_" = "Keep an eye on available space and recent activity"; +"_no_items_" = "No items"; +"_check_back_later_" = "Check back later"; +"_exporting_video_" = "Exporting video … Tap to cancel …"; // Video "_select_trace_" = "Select the trace"; diff --git a/iOSClient/Supporting Files/eo.lproj/Localizable.strings b/iOSClient/Supporting Files/eo.lproj/Localizable.strings Binary files differindex 2e4e79914..7f9f724d8 100644 --- a/iOSClient/Supporting Files/eo.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/eo.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-419.lproj/Localizable.strings b/iOSClient/Supporting Files/es-419.lproj/Localizable.strings Binary files differindex 744a75265..a0614923d 100644 --- a/iOSClient/Supporting Files/es-419.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-419.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings Binary files differindex 490b47309..604c11dcb 100644 --- a/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings Binary files differindex 12dfe029a..ca7f070c0 100644 --- a/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings Binary files differindex a70be0831..b9516b928 100644 --- a/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings Binary files differindex b8e2207ab..5de451d24 100644 --- a/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings b/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings Binary files differindex 4f89066de..24d86bafd 100644 --- a/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings b/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings Binary files differindex c774f01f7..f230348a7 100644 --- a/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings b/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings Binary files differindex 5ab1c8d28..262bbe7f1 100644 --- a/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings b/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings Binary files differindex da2f70866..e3ade1ff1 100644 --- a/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings b/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings Binary files differindex 9f7fa42c3..c73ae08cc 100644 --- a/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings b/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings Binary files differindex 9d335d874..2042a1ddd 100644 --- a/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings Binary files differindex 9d335d874..2042a1ddd 100644 --- a/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings Binary files differindex 9d335d874..2042a1ddd 100644 --- a/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings Binary files differindex 9d335d874..2042a1ddd 100644 --- a/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings Binary files differindex d8f262a34..06379c0cb 100644 --- a/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings b/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings Binary files differindex b8e2207ab..5de451d24 100644 --- a/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings b/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings Binary files differindex 65892d241..756d93b3c 100644 --- a/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es.lproj/Localizable.strings b/iOSClient/Supporting Files/es.lproj/Localizable.strings Binary files differindex 2688cd26e..bb9e5e3c4 100644 --- a/iOSClient/Supporting Files/es.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings b/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings Binary files differindex 862c5d5a4..7a7dea27f 100644 --- a/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/eu.lproj/Localizable.strings b/iOSClient/Supporting Files/eu.lproj/Localizable.strings Binary files differindex b5fc9a00e..c678d71e8 100644 --- a/iOSClient/Supporting Files/eu.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/eu.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fa.lproj/Localizable.strings b/iOSClient/Supporting Files/fa.lproj/Localizable.strings Binary files differindex 98dac602f..d40f14027 100644 --- a/iOSClient/Supporting Files/fa.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fa.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings Binary files differindex 1d0f51131..e33d9f89e 100644 --- a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fo.lproj/Localizable.strings b/iOSClient/Supporting Files/fo.lproj/Localizable.strings Binary files differindex 43f6713c2..48aad3f30 100644 --- a/iOSClient/Supporting Files/fo.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fo.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fr.lproj/Localizable.strings b/iOSClient/Supporting Files/fr.lproj/Localizable.strings Binary files differindex 104a348a8..c30cc2ee0 100644 --- a/iOSClient/Supporting Files/fr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/gd.lproj/Localizable.strings b/iOSClient/Supporting Files/gd.lproj/Localizable.strings Binary files differindex 1aed668aa..69b9c0aa8 100644 --- a/iOSClient/Supporting Files/gd.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/gd.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/gl.lproj/Localizable.strings b/iOSClient/Supporting Files/gl.lproj/Localizable.strings Binary files differindex 5a465544a..bf01bfcef 100644 --- a/iOSClient/Supporting Files/gl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/gl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/he.lproj/Localizable.strings b/iOSClient/Supporting Files/he.lproj/Localizable.strings Binary files differindex 14c593393..58b60b2f1 100644 --- a/iOSClient/Supporting Files/he.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/he.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings b/iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings Binary files differindex b9ced7e14..19456b87d 100644 --- a/iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hi_IN.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hr.lproj/Localizable.strings b/iOSClient/Supporting Files/hr.lproj/Localizable.strings Binary files differindex 8a19c4e1b..5a1bf3629 100644 --- a/iOSClient/Supporting Files/hr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hsb.lproj/Localizable.strings b/iOSClient/Supporting Files/hsb.lproj/Localizable.strings Binary files differindex cca796eec..6993b4412 100644 --- a/iOSClient/Supporting Files/hsb.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hsb.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hu.lproj/Localizable.strings b/iOSClient/Supporting Files/hu.lproj/Localizable.strings Binary files differindex 08c1142fd..820076b0d 100644 --- a/iOSClient/Supporting Files/hu.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hu.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hy.lproj/Localizable.strings b/iOSClient/Supporting Files/hy.lproj/Localizable.strings Binary files differindex 7aafd9845..26564ce6e 100644 --- a/iOSClient/Supporting Files/hy.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hy.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ia.lproj/Localizable.strings b/iOSClient/Supporting Files/ia.lproj/Localizable.strings Binary files differindex b590d932a..a5b1100fc 100644 --- a/iOSClient/Supporting Files/ia.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ia.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/id.lproj/Localizable.strings b/iOSClient/Supporting Files/id.lproj/Localizable.strings Binary files differindex cac6d526c..2b53fd14f 100644 --- a/iOSClient/Supporting Files/id.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/id.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ig.lproj/Localizable.strings b/iOSClient/Supporting Files/ig.lproj/Localizable.strings Binary files differindex 24da63500..397d9b1b5 100644 --- a/iOSClient/Supporting Files/ig.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ig.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/is.lproj/Localizable.strings b/iOSClient/Supporting Files/is.lproj/Localizable.strings Binary files differindex f8976eb0f..b34891c78 100644 --- a/iOSClient/Supporting Files/is.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/is.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/it.lproj/Localizable.strings b/iOSClient/Supporting Files/it.lproj/Localizable.strings Binary files differindex bf5a71971..f1d6c1879 100644 --- a/iOSClient/Supporting Files/it.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/it.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings b/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings Binary files differindex 0292b6862..5702f9b79 100644 --- a/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings b/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings Binary files differindex 8fa8b6000..dabbc558c 100644 --- a/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ka.lproj/Localizable.strings b/iOSClient/Supporting Files/ka.lproj/Localizable.strings Binary files differindex 0a8e42b84..76e522987 100644 --- a/iOSClient/Supporting Files/ka.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ka.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/kab.lproj/Localizable.strings b/iOSClient/Supporting Files/kab.lproj/Localizable.strings Binary files differindex 664aead6b..622674daa 100644 --- a/iOSClient/Supporting Files/kab.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/kab.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/km.lproj/Localizable.strings b/iOSClient/Supporting Files/km.lproj/Localizable.strings Binary files differindex a774ab28c..787b53062 100644 --- a/iOSClient/Supporting Files/km.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/km.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/kn.lproj/Localizable.strings b/iOSClient/Supporting Files/kn.lproj/Localizable.strings Binary files differindex 5f3ba140e..70e94314a 100644 --- a/iOSClient/Supporting Files/kn.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/kn.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ko.lproj/Localizable.strings b/iOSClient/Supporting Files/ko.lproj/Localizable.strings Binary files differindex 5b9e49e31..f9fbf7316 100644 --- a/iOSClient/Supporting Files/ko.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ko.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/la.lproj/Localizable.strings b/iOSClient/Supporting Files/la.lproj/Localizable.strings Binary files differindex 34c0df1ec..5b1f152f0 100644 --- a/iOSClient/Supporting Files/la.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/la.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lb.lproj/Localizable.strings b/iOSClient/Supporting Files/lb.lproj/Localizable.strings Binary files differindex 34b1e5230..df074d481 100644 --- a/iOSClient/Supporting Files/lb.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lb.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lo.lproj/Localizable.strings b/iOSClient/Supporting Files/lo.lproj/Localizable.strings Binary files differindex 01e2620fc..3fc3e5026 100644 --- a/iOSClient/Supporting Files/lo.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lo.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings b/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings Binary files differindex 4ecd37496..5103e6839 100644 --- a/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lv.lproj/Localizable.strings b/iOSClient/Supporting Files/lv.lproj/Localizable.strings Binary files differindex 97851d71d..7b4c03967 100644 --- a/iOSClient/Supporting Files/lv.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lv.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/mk.lproj/Localizable.strings b/iOSClient/Supporting Files/mk.lproj/Localizable.strings Binary files differindex 018982953..09aa730be 100644 --- a/iOSClient/Supporting Files/mk.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/mk.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/mn.lproj/Localizable.strings b/iOSClient/Supporting Files/mn.lproj/Localizable.strings Binary files differindex 6c431fd5a..ac096f1b5 100644 --- a/iOSClient/Supporting Files/mn.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/mn.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/mr.lproj/Localizable.strings b/iOSClient/Supporting Files/mr.lproj/Localizable.strings Binary files differindex e9cc00a41..253451741 100644 --- a/iOSClient/Supporting Files/mr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/mr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings b/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings Binary files differindex 2516257c7..0cb3d12a7 100644 --- a/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/my.lproj/Localizable.strings b/iOSClient/Supporting Files/my.lproj/Localizable.strings Binary files differindex 3f02a258b..75c147117 100644 --- a/iOSClient/Supporting Files/my.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/my.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings b/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings Binary files differindex 2a59d46b5..bf98565cf 100644 --- a/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ne.lproj/Localizable.strings b/iOSClient/Supporting Files/ne.lproj/Localizable.strings Binary files differindex 76e448634..552ffd632 100644 --- a/iOSClient/Supporting Files/ne.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ne.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nl.lproj/Localizable.strings b/iOSClient/Supporting Files/nl.lproj/Localizable.strings Binary files differindex 8ad5ca0f3..38f16ce26 100644 --- a/iOSClient/Supporting Files/nl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings b/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings Binary files differindex 85bd4b47d..80f0efc17 100644 --- a/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/oc.lproj/Localizable.strings b/iOSClient/Supporting Files/oc.lproj/Localizable.strings Binary files differindex 80a0a515c..dae296c8a 100644 --- a/iOSClient/Supporting Files/oc.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/oc.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pl.lproj/Localizable.strings b/iOSClient/Supporting Files/pl.lproj/Localizable.strings Binary files differindex 1797947dc..a8a7512e3 100644 --- a/iOSClient/Supporting Files/pl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ps.lproj/Localizable.strings b/iOSClient/Supporting Files/ps.lproj/Localizable.strings Binary files differindex fa35b201b..054a95058 100644 --- a/iOSClient/Supporting Files/ps.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ps.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings b/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings Binary files differindex 7ee7931dd..716d837f1 100644 --- a/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings b/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings Binary files differindex f0d1c8376..d487c00a5 100644 --- a/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ro.lproj/Localizable.strings b/iOSClient/Supporting Files/ro.lproj/Localizable.strings Binary files differindex 08e7cd9fb..7a6384fe8 100644 --- a/iOSClient/Supporting Files/ro.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ro.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ru.lproj/Localizable.strings b/iOSClient/Supporting Files/ru.lproj/Localizable.strings Binary files differindex 696027d60..c0274f8ed 100644 --- a/iOSClient/Supporting Files/ru.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ru.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sc.lproj/Localizable.strings b/iOSClient/Supporting Files/sc.lproj/Localizable.strings Binary files differindex 05ae29eee..bb94ba064 100644 --- a/iOSClient/Supporting Files/sc.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sc.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/si.lproj/Localizable.strings b/iOSClient/Supporting Files/si.lproj/Localizable.strings Binary files differindex d55f196a3..5bf8e604f 100644 --- a/iOSClient/Supporting Files/si.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/si.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings b/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings Binary files differindex db33cd898..9b71eb232 100644 --- a/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sl.lproj/Localizable.strings b/iOSClient/Supporting Files/sl.lproj/Localizable.strings Binary files differindex fa26273f2..21cf5fd72 100644 --- a/iOSClient/Supporting Files/sl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sq.lproj/Localizable.strings b/iOSClient/Supporting Files/sq.lproj/Localizable.strings Binary files differindex 98613fd07..d81a2884c 100644 --- a/iOSClient/Supporting Files/sq.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sq.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sr.lproj/Localizable.strings b/iOSClient/Supporting Files/sr.lproj/Localizable.strings Binary files differindex dce54aa2b..266488c86 100644 --- a/iOSClient/Supporting Files/sr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings b/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings Binary files differindex 7cdacac8a..6658bb9b2 100644 --- a/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sv.lproj/Localizable.strings b/iOSClient/Supporting Files/sv.lproj/Localizable.strings Binary files differindex 87dadabe5..c46753af7 100644 --- a/iOSClient/Supporting Files/sv.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sv.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sw.lproj/Localizable.strings b/iOSClient/Supporting Files/sw.lproj/Localizable.strings Binary files differindex b9ced7e14..19456b87d 100644 --- a/iOSClient/Supporting Files/sw.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sw.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ta.lproj/Localizable.strings b/iOSClient/Supporting Files/ta.lproj/Localizable.strings Binary files differindex 733e296e4..a91e820e0 100644 --- a/iOSClient/Supporting Files/ta.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ta.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings b/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings Binary files differindex 1b1ff3bfa..705e428e6 100644 --- a/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/tk.lproj/Localizable.strings b/iOSClient/Supporting Files/tk.lproj/Localizable.strings Binary files differindex 8976dc7d9..fb22850cb 100644 --- a/iOSClient/Supporting Files/tk.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/tk.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/tr.lproj/Localizable.strings b/iOSClient/Supporting Files/tr.lproj/Localizable.strings Binary files differindex fae13eb54..9c69e89a7 100644 --- a/iOSClient/Supporting Files/tr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/tr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ug.lproj/Localizable.strings b/iOSClient/Supporting Files/ug.lproj/Localizable.strings Binary files differindex 2d3de2a31..7032a34ac 100644 --- a/iOSClient/Supporting Files/ug.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ug.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/uk.lproj/Localizable.strings b/iOSClient/Supporting Files/uk.lproj/Localizable.strings Binary files differindex 50c3c7563..bbc1b2ac1 100644 --- a/iOSClient/Supporting Files/uk.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/uk.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings b/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings Binary files differindex 6d03423d0..4572e1de3 100644 --- a/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/uz.lproj/Localizable.strings b/iOSClient/Supporting Files/uz.lproj/Localizable.strings Binary files differindex b9ced7e14..19456b87d 100644 --- a/iOSClient/Supporting Files/uz.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/uz.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/vi.lproj/Localizable.strings b/iOSClient/Supporting Files/vi.lproj/Localizable.strings Binary files differindex 145f606a8..97acb8c53 100644 --- a/iOSClient/Supporting Files/vi.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/vi.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings b/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings Binary files differindex 9cacf6f5c..758b4158a 100644 --- a/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings b/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings Binary files differindex 91b0e17b6..b7e6b465d 100644 --- a/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings Binary files differindex fa9f526ee..9fb451d4a 100644 --- a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings diff --git a/iOSClient/Transfers/NCTransfers.swift b/iOSClient/Transfers/NCTransfers.swift index f2b603144..cdf4862b6 100644 --- a/iOSClient/Transfers/NCTransfers.swift +++ b/iOSClient/Transfers/NCTransfers.swift @@ -23,6 +23,7 @@ import UIKit import NextcloudKit +import JGProgressHUD class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate { @@ -135,7 +136,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate { guard let metadata = metadataTemp else { return } guard appDelegate.account == metadata.account else { return } - NCUtility.shared.extractFiles(from: metadata) { metadatas in + NCUtility.shared.extractFiles(from: metadata, viewController: self, hud: JGProgressHUD()) { metadatas in for metadata in metadatas { if let metadata = NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusInUpload) { NCNetworking.shared.upload(metadata: metadata) @@ -183,7 +184,7 @@ class NCTransfers: NCCollectionViewCommon, NCTransferCellDelegate { cell.imageItem.backgroundColor = nil cell.labelTitle.text = metadata.fileNameView cell.labelTitle.textColor = .label - let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(account: metadata.account) + let serverUrlHome = NCUtilityFileSystem.shared.getHomeServer(urlBase: metadata.urlBase, userId: metadata.userId) var pathText = metadata.serverUrl.replacingOccurrences(of: serverUrlHome, with: "") if pathText == "" { pathText = "/" } cell.labelPath.text = pathText diff --git a/iOSClient/Trash/NCTrash.swift b/iOSClient/Trash/NCTrash.swift index 7a451135f..dc5ffb452 100644 --- a/iOSClient/Trash/NCTrash.swift +++ b/iOSClient/Trash/NCTrash.swift @@ -262,7 +262,7 @@ class NCTrash: UIViewController, NCSelectableNavigationView, NCTrashListCellDele if self.trashPath.isEmpty { guard let userId = (appDelegate.userId as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed) else { return nil } - let trashPath = appDelegate.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: appDelegate.account) + "/trashbin/" + userId + "/trash/" + let trashPath = appDelegate.urlBase + "/" + NCGlobal.shared.dav + "/trashbin/" + userId + "/trash/" return trashPath } else { return self.trashPath @@ -278,7 +278,7 @@ extension NCTrash { let options = NKRequestOptions(queue: NKCommon.shared.backgroundQueue) - NextcloudKit.shared.listingTrash(showHiddenFiles: false, options: options) { account, items, data, error in + NextcloudKit.shared.listingTrash(showHiddenFiles: false, options: options) { account, items, _, error in DispatchQueue.main.async { self.refreshControl.endRefreshing() } @@ -298,7 +298,7 @@ extension NCTrash { guard let tableTrash = NCManageDatabase.shared.getTrashItem(fileId: fileId, account: appDelegate.account) else { return } let fileNameFrom = tableTrash.filePath + tableTrash.fileName - let fileNameTo = appDelegate.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: appDelegate.account) + "/trashbin/" + appDelegate.userId + "/restore/" + tableTrash.fileName + let fileNameTo = appDelegate.urlBase + "/" + NCGlobal.shared.dav + "/trashbin/" + appDelegate.userId + "/restore/" + tableTrash.fileName NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: true) { account, error in @@ -314,7 +314,7 @@ extension NCTrash { func emptyTrash() { - let serverUrlFileName = appDelegate.urlBase + "/" + NCUtilityFileSystem.shared.getWebDAV(account: appDelegate.account) + "/trashbin/" + appDelegate.userId + "/trash" + let serverUrlFileName = appDelegate.urlBase + "/" + NCGlobal.shared.dav + "/trashbin/" + appDelegate.userId + "/trash" NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName) { account, error in diff --git a/iOSClient/Utility/CCUtility.h b/iOSClient/Utility/CCUtility.h index 82193eb15..6584ea665 100644 --- a/iOSClient/Utility/CCUtility.h +++ b/iOSClient/Utility/CCUtility.h @@ -232,9 +232,8 @@ + (void)removeFileAtPath:(NSString *)atPath; + (void)createDirectoryAtPath:(NSString *)atPath; -+ (NSString *)returnPathfromServerUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase account:(NSString *)account; -+ (NSString *)returnFileNamePathFromFileName:(NSString *)metadataFileName serverUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase account:(NSString *)account; -+ (NSArray *)createNameSubFolder:(NSArray *)assets; ++ (NSString *)returnPathfromServerUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase userId:(NSString *)userId account:(NSString *)account; ++ (NSString *)returnFileNamePathFromFileName:(NSString *)metadataFileName serverUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase userId:(NSString *)userId account:(NSString *)account; + (NSString *)getDirectoryScan; @@ -243,7 +242,7 @@ // ===== E2E Encrypted ===== + (NSString *)generateRandomIdentifier; -+ (BOOL)isFolderEncrypted:(NSString *)serverUrl e2eEncrypted:(BOOL)e2eEncrypted account:(NSString *)account urlBase:(NSString *)urlBase; ++ (BOOL)isFolderEncrypted:(NSString *)serverUrl e2eEncrypted:(BOOL)e2eEncrypted account:(NSString *)account urlBase:(NSString *)urlBase userId:(NSString *)userId; // ===== Share Permissions ===== diff --git a/iOSClient/Utility/CCUtility.m b/iOSClient/Utility/CCUtility.m index c2a739c34..01aba493c 100644 --- a/iOSClient/Utility/CCUtility.m +++ b/iOSClient/Utility/CCUtility.m @@ -1125,7 +1125,7 @@ { NSString *fileNameViewPath = [self getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView]; NSString *fileNamePath = [self getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileName]; - BOOL isFolderEncrypted = [self isFolderEncrypted:metadata.serverUrl e2eEncrypted:metadata.e2eEncrypted account:metadata.account urlBase:metadata.urlBase]; + BOOL isFolderEncrypted = [self isFolderEncrypted:metadata.serverUrl e2eEncrypted:metadata.e2eEncrypted account:metadata.account urlBase:metadata.urlBase userId:metadata.userId]; unsigned long long fileNameViewSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileNameViewPath error:nil] fileSize]; unsigned long long fileNameSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileNamePath error:nil] fileSize]; @@ -1246,20 +1246,20 @@ [[NSFileManager defaultManager] createDirectoryAtPath:atPath withIntermediateDirectories:true attributes:nil error:nil]; } -+ (NSString *)returnPathfromServerUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase account:(NSString *)account ++ (NSString *)returnPathfromServerUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase userId:(NSString *)userId account:(NSString *)account { - NSString *homeServer = [[NCUtilityFileSystem shared] getHomeServerWithAccount:account]; + NSString *homeServer = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:urlBase userId:userId]; NSString *path = [serverUrl stringByReplacingOccurrencesOfString:homeServer withString:@""]; return path; } -+ (NSString *)returnFileNamePathFromFileName:(NSString *)metadataFileName serverUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase account:(NSString *)account ++ (NSString *)returnFileNamePathFromFileName:(NSString *)metadataFileName serverUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase userId:(NSString *)userId account:(NSString *)account { if (metadataFileName == nil || serverUrl == nil || urlBase == nil) { return @""; } - NSString *homeServer = [[NCUtilityFileSystem shared] getHomeServerWithAccount:account]; + NSString *homeServer = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:urlBase userId:userId]; NSString *fileName = [NSString stringWithFormat:@"%@/%@", [serverUrl stringByReplacingOccurrencesOfString:homeServer withString:@""], metadataFileName]; if ([fileName hasPrefix:@"/"]) fileName = [fileName substringFromIndex:1]; @@ -1267,30 +1267,6 @@ return fileName; } -+ (NSArray *)createNameSubFolder:(NSArray *)assets -{ - NSMutableOrderedSet *datesSubFolder = [NSMutableOrderedSet new]; - - for (PHAsset *asset in assets) { - - NSDate *assetDate = asset.creationDate; - - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setDateFormat:@"yyyy"]; - NSString *yearString = [formatter stringFromDate:assetDate]; - if (yearString) - [datesSubFolder addObject:yearString]; - - [formatter setDateFormat:@"MM"]; - NSString *monthString = [formatter stringFromDate:assetDate]; - monthString = [NSString stringWithFormat:@"%@/%@", yearString, monthString]; - if (monthString) - [datesSubFolder addObject:monthString]; - } - - return (NSArray *)datesSubFolder; -} - + (NSString *)getMimeType:(NSString *)fileNameView { CFStringRef fileUTI = nil; @@ -1336,9 +1312,9 @@ return [[UUID stringByReplacingOccurrencesOfString:@"-" withString:@""] lowercaseString]; } -+ (BOOL)isFolderEncrypted:(NSString *)serverUrl e2eEncrypted:(BOOL)e2eEncrypted account:(NSString *)account urlBase:(NSString *)urlBase ++ (BOOL)isFolderEncrypted:(NSString *)serverUrl e2eEncrypted:(BOOL)e2eEncrypted account:(NSString *)account urlBase:(NSString *)urlBase userId:(NSString *)userId { - NSString *home = [[NCUtilityFileSystem shared] getHomeServerWithAccount:account]; + NSString *home = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:urlBase userId:userId]; if (e2eEncrypted) { @@ -1356,7 +1332,7 @@ if (directory.e2eEncrypted == true) { return true; } - NSString* home = [[NCUtilityFileSystem shared] getHomeServerWithAccount:account]; + NSString* home = [[NCUtilityFileSystem shared] getHomeServerWithUrlBase:urlBase userId:userId]; NSString* path = [[NCUtilityFileSystem shared] deleteLastPathWithServerUrlPath:serverUrl home:home]; if (path != nil) { serverUrl = path; diff --git a/iOSClient/Utility/NCUtility.swift b/iOSClient/Utility/NCUtility.swift index 54dcc90f6..48d5c7ed1 100644 --- a/iOSClient/Utility/NCUtility.swift +++ b/iOSClient/Utility/NCUtility.swift @@ -30,6 +30,7 @@ import Accelerate import CoreMedia import Queuer import Photos +import JGProgressHUD class NCUtility: NSObject { @objc static let shared: NCUtility = { @@ -379,7 +380,7 @@ class NCUtility: NSObject { // MARK: - - func extractFiles(from metadata: tableMetadata, completition: @escaping (_ metadatas: [tableMetadata]) -> Void) { + func extractFiles(from metadata: tableMetadata, viewController: UIViewController?, hud: JGProgressHUD, completition: @escaping (_ metadatas: [tableMetadata]) -> Void) { let chunckSize = CCUtility.getChunkSize() * 1000000 var metadatas: [tableMetadata] = [] @@ -393,10 +394,14 @@ class NCUtility: NSObject { metadataSource.contentType = results.mimeType metadataSource.iconName = results.iconName metadataSource.classFile = results.classFile - if let date = NCUtilityFileSystem.shared.getFileCreationDate(filePath: filePath) { metadataSource.creationDate = date } - if let date = NCUtilityFileSystem.shared.getFileModificationDate(filePath: filePath) { metadataSource.date = date } + if let date = NCUtilityFileSystem.shared.getFileCreationDate(filePath: filePath) { + metadataSource.creationDate = date + } + if let date = NCUtilityFileSystem.shared.getFileModificationDate(filePath: filePath) { + metadataSource.date = date + } metadataSource.chunk = chunckSize != 0 && metadata.size > chunckSize - metadataSource.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + metadataSource.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) metadataSource.isExtractFile = true if let metadata = NCManageDatabase.shared.addMetadata(metadataSource) { metadatas.append(metadata) @@ -404,7 +409,7 @@ class NCUtility: NSObject { return completition(metadatas) } - extractImageVideoFromAssetLocalIdentifier(metadata: metadataSource, modifyMetadataForUpload: true) { metadata, fileNamePath, returnError in + extractImageVideoFromAssetLocalIdentifier(metadata: metadataSource, modifyMetadataForUpload: true, viewController: viewController, hud: hud) { metadata, fileNamePath, returnError in if let metadata = metadata, let fileNamePath = fileNamePath, !returnError { metadatas.append(metadata) let toPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)! @@ -426,21 +431,21 @@ class NCUtility: NSObject { } } - func extractImageVideoFromAssetLocalIdentifier(metadata: tableMetadata, modifyMetadataForUpload: Bool, completion: @escaping (_ metadata: tableMetadata?, _ fileNamePath: String?, _ error: Bool) -> ()) { + func extractImageVideoFromAssetLocalIdentifier(metadata: tableMetadata, modifyMetadataForUpload: Bool, viewController: UIViewController?, hud: JGProgressHUD, completion: @escaping (_ metadata: tableMetadata?, _ fileNamePath: String?, _ error: Bool) -> ()) { var fileNamePath: String? let metadata = tableMetadata.init(value: metadata) let chunckSize = CCUtility.getChunkSize() * 1000000 var compatibilityFormat: Bool = false - func callCompletion(error: Bool) { + func callCompletionWithError(_ error: Bool = true) { if error { completion(nil, nil, true) } else { var metadataReturn = metadata if modifyMetadataForUpload { metadata.chunk = chunckSize != 0 && metadata.size > chunckSize - metadata.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + metadata.e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) metadata.isExtractFile = true if let metadata = NCManageDatabase.shared.addMetadata(metadata) { metadataReturn = metadata @@ -451,9 +456,10 @@ class NCUtility: NSObject { } let fetchAssets = PHAsset.fetchAssets(withLocalIdentifiers: [metadata.assetLocalIdentifier], options: nil) - guard fetchAssets.count > 0, let asset = fetchAssets.firstObject, let extensionAsset = (asset.value(forKey: "filename") as? NSString)?.pathExtension.uppercased() else { - return callCompletion(error: true) - } + guard fetchAssets.count > 0, let asset = fetchAssets.firstObject, let extensionAsset = (asset.value(forKey: "filename") as? NSString)?.pathExtension.uppercased() else { return callCompletionWithError() } + + let creationDate = asset.creationDate ?? Date() + let modificationDate = asset.modificationDate ?? Date() if asset.mediaType == PHAssetMediaType.image && (extensionAsset == "HEIC" || extensionAsset == "DNG") && CCUtility.getFormatCompatibility() { let fileName = (metadata.fileNameView as NSString).deletingPathExtension + ".jpg" @@ -468,9 +474,8 @@ class NCUtility: NSObject { } else { fileNamePath = NSTemporaryDirectory() + metadata.fileNameView } - guard let fileNamePath = fileNamePath, let creationDate = asset.creationDate, let modificationDate = asset.modificationDate else { - return callCompletion(error: true) - } + + guard let fileNamePath = fileNamePath else { return callCompletionWithError() } if asset.mediaType == PHAssetMediaType.image { @@ -487,25 +492,23 @@ class NCUtility: NSObject { } options.progressHandler = { (progress, error, stop, info) in print(progress) - if error != nil { return callCompletion(error: true) } + if error != nil { return callCompletionWithError() } } PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { data, dataUI, orientation, info in - guard var data = data else { return callCompletion(error: true) } + guard var data = data else { return callCompletionWithError() } if compatibilityFormat { - guard let ciImage = CIImage.init(data: data), let colorSpace = ciImage.colorSpace, let dataJPEG = CIContext().jpegRepresentation(of: ciImage, colorSpace: colorSpace) else { return callCompletion(error: true) } + guard let ciImage = CIImage.init(data: data), let colorSpace = ciImage.colorSpace, let dataJPEG = CIContext().jpegRepresentation(of: ciImage, colorSpace: colorSpace) else { return callCompletionWithError() } data = dataJPEG } NCUtilityFileSystem.shared.deleteFile(filePath: fileNamePath) do { try data.write(to: URL(fileURLWithPath: fileNamePath), options: .atomic) - } catch { - return callCompletion(error: true) - } + } catch { return callCompletionWithError() } metadata.creationDate = creationDate as NSDate metadata.date = modificationDate as NSDate metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: fileNamePath) - return callCompletion(error: false) + return callCompletionWithError(false) } } else if asset.mediaType == PHAssetMediaType.video { @@ -515,24 +518,52 @@ class NCUtility: NSObject { options.version = PHVideoRequestOptionsVersion.current options.progressHandler = { (progress, error, stop, info) in print(progress) - if error != nil { return callCompletion(error: true) } + if error != nil { return callCompletionWithError() } } PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { asset, audioMix, info in - guard let asset = asset as? AVURLAsset else { return callCompletion(error: true) } - NCUtilityFileSystem.shared.deleteFile(filePath: fileNamePath) - do { - try FileManager.default.copyItem(at: asset.url, to: URL(fileURLWithPath: fileNamePath)) - } catch { - return callCompletion(error: true) + if let asset = asset as? AVURLAsset { + NCUtilityFileSystem.shared.deleteFile(filePath: fileNamePath) + do { + try FileManager.default.copyItem(at: asset.url, to: URL(fileURLWithPath: fileNamePath)) + metadata.creationDate = creationDate as NSDate + metadata.date = modificationDate as NSDate + metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: fileNamePath) + return callCompletionWithError(false) + } catch { return callCompletionWithError() } + } else if let asset = asset as? AVComposition, asset.tracks.count > 1, let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality), let viewController = viewController { + DispatchQueue.main.async { + hud.indicatorView = JGProgressHUDRingIndicatorView() + if let indicatorView = hud.indicatorView as? JGProgressHUDRingIndicatorView { + indicatorView.ringWidth = 1.5 + } + hud.textLabel.text = NSLocalizedString("_exporting_video_", comment: "") + hud.show(in: viewController.view) + hud.tapOnHUDViewBlock = { hud in + exporter.cancelExport() + } + } + exporter.outputURL = URL(fileURLWithPath: fileNamePath) + exporter.outputFileType = AVFileType.mp4 + exporter.shouldOptimizeForNetworkUse = true + exporter.exportAsynchronously { + DispatchQueue.main.async { hud.dismiss() } + if exporter.status == .completed { + metadata.creationDate = creationDate as NSDate + metadata.date = modificationDate as NSDate + metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: fileNamePath) + return callCompletionWithError(false) + } else { return callCompletionWithError() } + } + while exporter.status == AVAssetExportSession.Status.exporting || exporter.status == AVAssetExportSession.Status.waiting { + hud.progress = exporter.progress + } + } else { + return callCompletionWithError() } - metadata.creationDate = creationDate as NSDate - metadata.date = modificationDate as NSDate - metadata.size = NCUtilityFileSystem.shared.getFileSize(filePath: fileNamePath) - return callCompletion(error: false) } } else { - return callCompletion(error: true) + return callCompletionWithError() } } @@ -543,7 +574,7 @@ class NCUtility: NSObject { options.deliveryMode = PHImageRequestOptionsDeliveryMode.fastFormat options.isNetworkAccessAllowed = true let chunckSize = CCUtility.getChunkSize() * 1000000 - let e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase) + let e2eEncrypted = CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId) let ocId = NSUUID().uuidString let fileName = (metadata.fileName as NSString).deletingPathExtension + ".mov" let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)! diff --git a/iOSClient/Utility/NCUtilityFileSystem.swift b/iOSClient/Utility/NCUtilityFileSystem.swift index 601370c35..c302bc039 100644 --- a/iOSClient/Utility/NCUtilityFileSystem.swift +++ b/iOSClient/Utility/NCUtilityFileSystem.swift @@ -152,17 +152,8 @@ class NCUtilityFileSystem: NSObject { // MARK: - - @objc func getWebDAV(account: String) -> String { - // return NCManageDatabase.shared.getCapabilitiesServerString(account: account, elements: NCElementsJSON.shared.capabilitiesWebDavRoot) ?? "remote.php/webdav" - return "remote.php/dav" - } - - @objc func getHomeServer(account: String) -> String { - var home = self.getWebDAV(account: account) - if let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) { - home = tableAccount.urlBase + "/" + self.getWebDAV(account: account) + "/files/" + tableAccount.userId - } - return home + @objc func getHomeServer(urlBase: String, userId: String) -> String { + return urlBase + "/remote.php/dav/files/" + userId } @objc func getPath(path: String, user: String, fileName: String? = nil) -> String { diff --git a/iOSClient/Utility/ParallelWorker.swift b/iOSClient/Utility/ParallelWorker.swift index 3fc51c5c7..9787345e8 100644 --- a/iOSClient/Utility/ParallelWorker.swift +++ b/iOSClient/Utility/ParallelWorker.swift @@ -51,9 +51,9 @@ class ParallelWorker { DispatchQueue.main.async { let hud = JGProgressHUD() - hud.show(in: hudView) hud.textLabel.text = NSLocalizedString(self.titleKey, comment: "") hud.detailTextLabel.text = NSLocalizedString("_tap_to_cancel_", comment: "") + hud.show(in: hudView) hud.tapOnHUDViewBlock = { hud in self.isCancelled = true // Cancel all download / upload diff --git a/iOSClient/Viewer/NCViewer.swift b/iOSClient/Viewer/NCViewer.swift index 691c7537b..cdd9808fc 100644 --- a/iOSClient/Viewer/NCViewer.swift +++ b/iOSClient/Viewer/NCViewer.swift @@ -172,7 +172,7 @@ class NCViewer: NSObject { if metadata.url == "" { - 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, userId: metadata.userId, account: metadata.account)! var options = NKRequestOptions() if editor == NCGlobal.shared.editorOnlyoffice { diff --git a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift index fce146909..2a214d50f 100644 --- a/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift +++ b/iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift @@ -428,9 +428,9 @@ class NCPlayer: NSObject { if let indicatorView = hud.indicatorView as? JGProgressHUDRingIndicatorView { indicatorView.ringWidth = 1.5 } - hud.show(in: view) hud.textLabel.text = NSLocalizedString(metadata.fileNameView, comment: "") hud.detailTextLabel.text = NSLocalizedString("_tap_to_cancel_", comment: "") + hud.show(in: view) hud.tapOnHUDViewBlock = { hud in downloadRequest?.cancel() } diff --git a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift index aaa9725f3..2e76d21d6 100644 --- a/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift +++ b/iOSClient/Viewer/NCViewerQuickLook/NCViewerQuickLook.swift @@ -153,7 +153,8 @@ extension NCViewerQuickLook: QLPreviewControllerDataSource, QLPreviewControllerD } metadataForUpload.size = size metadataForUpload.status = NCGlobal.shared.metadataStatusWaitUpload - (UIApplication.shared.delegate as? AppDelegate)?.networkingProcessUpload?.createProcessUploads(metadatas: [metadataForUpload], completion: { _ in }) + + NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: [metadataForUpload]) { _ in } } func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) { diff --git a/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift b/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift index 8842af5ae..22e818863 100644 --- a/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift +++ b/iOSClient/Viewer/NCViewerRichdocument/NCViewerRichdocument.swift @@ -282,7 +282,7 @@ class NCViewerRichdocument: UIViewController, WKNavigationDelegate, WKScriptMess if serverUrl != nil && metadata != nil { - let path = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl!, urlBase: appDelegate.urlBase, account: metadata!.account)! + let path = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl!, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: metadata!.account)! NextcloudKit.shared.createAssetRichdocuments(path: path) { account, url, data, error in if error == .success && account == self.appDelegate.account { @@ -299,7 +299,7 @@ class NCViewerRichdocument: UIViewController, WKNavigationDelegate, WKScriptMess func select(_ metadata: tableMetadata!, serverUrl: String!) { - let path = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl!, urlBase: appDelegate.urlBase, account: metadata!.account)! + let path = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl!, urlBase: appDelegate.urlBase, userId: appDelegate.userId, account: metadata!.account)! NextcloudKit.shared.createAssetRichdocuments(path: path) { account, url, data, error in if error == .success && account == self.appDelegate.account { |