diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index da11cd9ed5..43b49f8608 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -85,6 +85,12 @@ AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; }; CB3666201AF7550816B5CD6A /* NCContextMenuComment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */; }; + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; }; + B5D45E5F2DA50C8500773929 /* TealiumHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D45E5D2DA50C8500773929 /* TealiumHelper.swift */; }; + B5D45E602DA50C8500773929 /* AdjustHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D45E5C2DA50C8500773929 /* AdjustHelper.m */; }; + B5D45E632DA50D6A00773929 /* CCManageAutoUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D45E622DA50D6A00773929 /* CCManageAutoUpload.m */; }; + B5D45E642DA50D6A00773929 /* CCAdvanced.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D45E612DA50D6A00773929 /* CCAdvanced.m */; }; + D575039F27146F93008DC9DC /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; }; D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; }; F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; }; F31165022F9674A1009A1E37 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = F31165012F9674A1009A1E37 /* AppIcon.icon */; }; @@ -1263,6 +1269,12 @@ AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = ""; }; B4C7A5B36D1ED178FB6B76CB /* NCContextMenuPlayerTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuPlayerTracks.swift; sourceTree = ""; }; BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuProfile.swift; sourceTree = ""; }; + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = ""; }; + B5D45E5B2DA50C8500773929 /* AdjustHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AdjustHelper.h; sourceTree = ""; }; + B5D45E5C2DA50C8500773929 /* AdjustHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AdjustHelper.m; sourceTree = ""; }; + B5D45E5D2DA50C8500773929 /* TealiumHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TealiumHelper.swift; sourceTree = ""; }; + B5D45E612DA50D6A00773929 /* CCAdvanced.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CCAdvanced.m; sourceTree = ""; }; + B5D45E622DA50D6A00773929 /* CCManageAutoUpload.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CCManageAutoUpload.m; sourceTree = ""; }; C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = ""; }; @@ -2125,6 +2137,16 @@ path = Advanced; sourceTree = ""; }; + B5D45E5E2DA50C8500773929 /* Helper */ = { + isa = PBXGroup; + children = ( + B5D45E5B2DA50C8500773929 /* AdjustHelper.h */, + B5D45E5C2DA50C8500773929 /* AdjustHelper.m */, + B5D45E5D2DA50C8500773929 /* TealiumHelper.swift */, + ); + path = Helper; + sourceTree = ""; + }; C0046CDB2A17B98400D87C9D /* NextcloudUITests */ = { isa = PBXGroup; children = ( @@ -2405,7 +2427,7 @@ AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */, AF93471727E2361E002537EE /* NCShareHeader.xib */, AF93471527E2361E002537EE /* NCShareHeader.swift */, - AFCE353827E5DE0400FEA6C2 /* Shareable.swift */, + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */, AA8E03D92D2ED83300E7E89C /* TransientShare.swift */, ); path = Share; @@ -2604,6 +2626,8 @@ F76882042C0DD1E7001CF441 /* Settings */ = { isa = PBXGroup; children = ( + B5D45E612DA50D6A00773929 /* CCAdvanced.m */, + B5D45E622DA50D6A00773929 /* CCManageAutoUpload.m */, F768820B2C0DD1E7001CF441 /* Settings */, F76882162C0DD1E7001CF441 /* AutoUpload */, F389C9F32CEE381E00049762 /* SelectAlbum */, @@ -3321,6 +3345,7 @@ isa = PBXGroup; children = ( AA517BB42D66149900F8D37C /* .tx */, + B5D45E5E2DA50C8500773929 /* Helper */, F702F2CC25EE5B4F008F8E80 /* AppDelegate.swift */, F7110ADF2F9773210095AA5C /* AppDelegate+AppRefresh.swift */, F7110AE32F9774130095AA5C /* AppDelegate+AppProcessing.swift */, @@ -4641,6 +4666,8 @@ F704B5E92430C0B800632F5F /* NCCreateFormUploadConflictCell.swift in Sources */, F72D404923D2082500A97FD0 /* NCViewerDirectEditing.swift in Sources */, AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */, + F72D404923D2082500A97FD0 /* NCViewerNextcloudText.swift in Sources */, + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */, F77BB746289984CA0090FC19 /* UIViewController+Extension.swift in Sources */, F700510522DF6A89003A3356 /* NCShare.swift in Sources */, F72D1007210B6882009C96B7 /* NCPushNotificationEncryption.m in Sources */, @@ -4708,6 +4735,8 @@ F75DD765290ABB25002EB562 /* Intent.intentdefinition in Sources */, F7D4BF012CA1831900A5E746 /* NCCollectionViewCommonPinchGesture.swift in Sources */, F74B6D952A7E239A00F03C5F /* NCManageDatabase+Chunk.swift in Sources */, + B5D45E632DA50D6A00773929 /* CCManageAutoUpload.m in Sources */, + B5D45E642DA50D6A00773929 /* CCAdvanced.m in Sources */, F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */, F702F2F725EE5CED008F8E80 /* NCLogin.swift in Sources */, F75D90212D2BE26F003E740B /* NCRecommendationsCell.swift in Sources */, @@ -4721,6 +4750,8 @@ F710D1F52405770F00A6033D /* NCViewerPDF.swift in Sources */, F72EC7242F45C81600A2135C /* NotificationCenter+Extension.swift in Sources */, F389C9F52CEE383300049762 /* SelectAlbumView.swift in Sources */, + B5D45E5F2DA50C8500773929 /* TealiumHelper.swift in Sources */, + B5D45E602DA50C8500773929 /* AdjustHelper.m in Sources */, F7B6B70427C4E7FA00A7F6EB /* NCScan+CollectionView.swift in Sources */, F7816EF22C2C3E1F00A52517 /* NCPushNotification.swift in Sources */, F76882342C0DD1E7001CF441 /* NCDisplayView.swift in Sources */, diff --git a/iOSClient/AppDelegate.swift b/iOSClient/AppDelegate.swift index e37f4f8cc2..4d2c3fe67b 100644 --- a/iOSClient/AppDelegate.swift +++ b/iOSClient/AppDelegate.swift @@ -16,6 +16,11 @@ import RealmSwift class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var backgroundSessionCompletionHandler: (() -> Void)? + var activeLogin: NCLogin? + var activeLoginWeb: NCLoginWeb? + var taskAutoUploadDate: Date = Date() + var orientationLock = UIInterfaceOrientationMask.all + @objc let adjust = AdjustHelper() var isUiTestingEnabled: Bool { return ProcessInfo.processInfo.arguments.contains("UI_TESTING") } @@ -30,7 +35,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD var bgTask: UIBackgroundTaskIdentifier = .invalid var pushSubscriptionTask: Task? - + var window: UIWindow? + var sceneIdentifier: String = "" + var activeViewController: UIViewController? + var account: String = "" + var urlBase: String = "" + var user: String = "" + var userId: String = "" + var password: String = "" + var timerErrorNetworking: Timer? + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { if isUiTestingEnabled { Task { @@ -44,6 +58,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD utilityFileSystem.emptyTemporaryDirectory() utilityFileSystem.clearCacheDirectory("com.limit-point.LivePhoto") + UINavigationBar.appearance().tintColor = NCBrandColor.shared.brand + UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = NCBrandColor.shared.brand + let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, utility.getVersionBuild()) NCAppVersionManager.shared.checkAndUpdateInstallState() @@ -114,6 +131,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD if NCBrandOptions.shared.enforce_passcode_lock { NCPreferences().requestPasscodeAtStart = true } + +// if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { +// for window in windowScene.windows { +// let imageViews = window.allImageViews() +// // Do something with the imageViews +// for imageView in imageViews { +// print("Found image view: \(imageView)") +// imageView.tintColor = UITraitCollection.current.userInterfaceStyle == .dark ? .white : .black +// } +// } +// } return true } @@ -145,6 +173,203 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } + // MARK: - Background Task + + /* + @discussion Schedule a refresh task request to ask that the system launch your app briefly so that you can download data and keep your app's contents up-to-date. The system will fulfill this request intelligently based on system conditions and app usage. + */ + func scheduleAppRefresh() { + let request = BGAppRefreshTaskRequest(identifier: global.refreshTask) + + request.earliestBeginDate = Date(timeIntervalSinceNow: 60) // Refresh after 60 seconds. + + do { + try BGTaskScheduler.shared.submit(request) + } catch { + nkLog(tag: self.global.logTagTask, emoji: .error, message: "Refresh task failed to submit request: \(error)") + } + } + + /* + @discussion Schedule a processing task request to ask that the system launch your app when conditions are favorable for battery life to handle deferrable, longer-running processing, such as syncing, database maintenance, or similar tasks. The system will attempt to fulfill this request to the best of its ability within the next two days as long as the user has used your app within the past week. + */ + func scheduleAppProcessing() { + let request = BGProcessingTaskRequest(identifier: global.processingTask) + + request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60) // Refresh after 5 minutes. + request.requiresNetworkConnectivity = false + request.requiresExternalPower = false + + do { + try BGTaskScheduler.shared.submit(request) + } catch { + nkLog(tag: self.global.logTagTask, emoji: .error, message: "Processing task failed to submit request: \(error)") + } + } + + func handleAppRefresh(_ task: BGAppRefreshTask) { + nkLog(tag: self.global.logTagTask, emoji: .start, message: "Start refresh task") + guard NCManageDatabase.shared.openRealmBackground() else { + nkLog(tag: self.global.logTagTask, emoji: .error, message: "Failed to open Realm in background") + task.setTaskCompleted(success: false) + return + } + + // Schedule next refresh + scheduleAppRefresh() + + Task { + defer { + task.setTaskCompleted(success: true) + } + + guard let tblAccount = await NCManageDatabase.shared.getActiveTableAccountAsync() else { + nkLog(tag: self.global.logTagTask, emoji: .info, message: "No active account or background task already running") + return + } + + await backgroundSync(tblAccount: tblAccount, task: task) + } + } + + func handleProcessingTask(_ task: BGProcessingTask) { + nkLog(tag: self.global.logTagTask, emoji: .start, message: "Start processing task") + guard NCManageDatabase.shared.openRealmBackground() else { + nkLog(tag: self.global.logTagTask, emoji: .error, message: "Failed to open Realm in background") + task.setTaskCompleted(success: false) + return + } + var expired = false + task.expirationHandler = { + expired = true + } + + // Schedule next processing task + scheduleAppProcessing() + + Task { + defer { + task.setTaskCompleted(success: true) + } + + // If possible, cleaning every week + if NCPreferences().cleaningWeek() { + // BGTask expiration flag + nkLog(tag: self.global.logTagBgSync, emoji: .start, message: "Start cleaning week") + let tblAccounts = await NCManageDatabase.shared.getAllTableAccountAsync() + for tblAccount in tblAccounts { + await NCManageDatabase.shared.cleanTablesOcIds(account: tblAccount.account, userId: tblAccount.userId, urlBase: tblAccount.urlBase) + guard !expired else { return } + } + await NCUtilityFileSystem().cleanUpAsync() + + NCPreferences().setDoneCleaningWeek() + nkLog(tag: self.global.logTagBgSync, emoji: .stop, message: "Stop cleaning week") + } else { + await backgroundSync(task: task) + } + } + } + + func backgroundSync(task: BGTask? = nil) async { + defer { + // Update badge safely at the end of the background sync + Task { @MainActor in + do { + let count = await NCManageDatabase.shared.getMetadatasInWaitingCountAsync() + try await UNUserNotificationCenter.current().setBadgeCount(count) + } catch { } + } + } + + // BGTask expiration flag + var expired = false + task?.expirationHandler = { + expired = true + } + + // Discover new items for Auto Upload + let numAutoUpload = await NCAutoUpload.shared.initAutoUpload() + nkLog(tag: self.global.logTagBgSync, emoji: .start, message: "Auto upload found \(numAutoUpload) new items") + guard !expired else { return } + + // Fetch METADATAS + let metadatas = await NCManageDatabase.shared.getMetadataProcess() + guard !metadatas.isEmpty, !expired else { + return + } + + // Create all pending Auto Upload folders (fail-fast) + let pendingCreateFolders = metadatas.lazy.filter { + $0.status == self.global.metadataStatusWaitCreateFolder && + $0.sessionSelector == self.global.selectorUploadAutoUpload + } + + for metadata in pendingCreateFolders { + guard !expired else { return } + + let err = await NCNetworking.shared.createFolderForAutoUpload( + serverUrlFileName: meta.serverUrlFileName, + account: meta.account + ) + // Fail-fast: abort the whole sync on first failure + if err != .success { + nkLog(tag: self.global.logTagBgSync, emoji: .error, message: "Create folder '\(meta.serverUrlFileName)' failed: \(err.errorCode) – aborting sync") + return + } + } + + // Capacity computation + let downloading = metadatas.lazy.filter { $0.status == self.global.metadataStatusDownloading }.count + let uploading = metadatas.lazy.filter { $0.status == self.global.metadataStatusUploading }.count + let availableProcess = max(0, NCBrandOptions.shared.numMaximumProcess - (downloading + uploading)) + + // Start Auto Uploads + let metadatasToUpload = Array( + metadatas.lazy.filter { + $0.status == self.global.metadataStatusWaitUpload && + $0.sessionSelector == self.global.selectorUploadAutoUpload && + $0.chunk == 0 + } + .prefix(availableProcess) + ) + + let cameraRoll = NCCameraRoll() + + for metadata in metadatasToUpload { + guard !expired else { return } + + // File exists? skip it + let existsResult = await NCNetworking.shared.fileExists(serverUrlFileName: metadata.serverUrlFileName, account: metadata.account) + if existsResult == .success { + // File exists → delete from local metadata and skip + await NCManageDatabase.shared.deleteMetadataAsync(id: metadata.ocId) + continue + } else if existsResult.errorCode == 404 { + // 404 Not Found → directory does not exist + // Proceed + } else { + // Any other error (423 locked, 401 auth, 403 forbidden, 5xx, etc.) + continue + } + + // Expand seed into concrete metadatas (e.g., Live Photo pair) + let extracted = await cameraRoll.extractCameraRoll(from: metadata) + guard !expired else { return } + + for metadata in extracted { + // Sequential await keeps ordering and simplifies backpressure + let err = await NCNetworking.shared.uploadFileInBackground(metadata: metadata.detachedCopy()) + if err == .success { + nkLog(tag: self.global.logTagBgSync, message: "In queued upload \(metadata.fileName) -> \(metadata.serverUrl)") + } else { + nkLog(tag: self.global.logTagBgSync, emoji: .error, message: "Upload failed \(metadata.fileName) -> \(metadata.serverUrl) [\(err.errorDescription)]") + } + guard !expired else { return } + } + } + } + // MARK: - Background Networking Session func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { @@ -245,6 +470,217 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } } + // MARK: - Trust Certificate Error + + func trustCertificateError(host: String) { + guard let activeTblAccount = NCManageDatabase.shared.getActiveTableAccount(), + let currentHost = URL(string: activeTblAccount.urlBase)?.host, + let pushNotificationServerProxyHost = URL(string: NCBrandOptions.shared.pushNotificationServerProxy)?.host, + host != pushNotificationServerProxyHost, + host == currentHost + else { return } + let certificateHostSavedPath = NCUtilityFileSystem().directoryCertificates + "/" + host + ".der" + var title = NSLocalizedString("_ssl_certificate_changed_", comment: "") + + if !FileManager.default.fileExists(atPath: certificateHostSavedPath) { + title = NSLocalizedString("_connect_server_anyway_", comment: "") + } + + let alertController = UIAlertController(title: title, message: NSLocalizedString("_server_is_trusted_", comment: ""), preferredStyle: .alert) + + alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", comment: ""), style: .default, handler: { _ in + NCNetworking.shared.writeCertificate(host: host) + })) + + alertController.addAction(UIAlertAction(title: NSLocalizedString("_no_", comment: ""), style: .default, handler: { _ in })) + + alertController.addAction(UIAlertAction(title: NSLocalizedString("_certificate_details_", comment: ""), style: .default, handler: { _ in + if let navigationController = UIStoryboard(name: "NCViewCertificateDetails", bundle: nil).instantiateInitialViewController() as? UINavigationController, + let viewController = navigationController.topViewController as? NCViewCertificateDetails { + viewController.delegate = self + viewController.host = host + UIApplication.shared.firstWindow?.rootViewController?.present(navigationController, animated: true) + } + })) + + UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true) + } + + // MARK: - Reset Application + + func resetApplication() { + let utilityFileSystem = NCUtilityFileSystem() + + NCNetworking.shared.cancelAllTask() + + URLCache.shared.removeAllCachedResponses() + + utilityFileSystem.removeGroupDirectoryProviderStorage() + utilityFileSystem.removeGroupApplicationSupport() + utilityFileSystem.removeDocumentsDirectory() + utilityFileSystem.removeTemporaryDirectory() + + NCPreferences().removeAll() + + // Reset App Icon badge / File Icon badge + if #available(iOS 17.0, *) { + UNUserNotificationCenter.current().setBadgeCount(0) + } + exit(0) + } + + // MARK: - Universal Links + + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { + let applicationHandle = NCApplicationHandle() + return applicationHandle.applicationOpenUserActivity(userActivity) + } + + // MARK: - Login + + func openLogin(selector: Int, window: UIWindow? = nil) { + UIApplication.shared.allSceneSessionDestructionExceptFirst() + + // Nextcloud standard login + if selector == NCGlobal.shared.introSignup { + if activeLogin?.view.window == nil { + if selector == NCGlobal.shared.introSignup { + let web = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginProvider") as? NCLoginProvider + web?.initialURLString = NCBrandOptions.shared.linkloginPreferredProviders + showLoginViewController(web) + } else { + activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin + if let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController, !controller.account.isEmpty { + let session = NCSession.shared.getSession(account: controller.account) + activeLogin?.urlBase = session.urlBase + } + showLoginViewController(activeLogin) + } + } + } else { + if activeLogin?.view.window == nil { + activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin + activeLogin?.urlBase = NCBrandOptions.shared.disable_request_login_url ? NCBrandOptions.shared.loginBaseUrl : "" + showLoginViewController(activeLogin) + } + } + } + + func openLogin(viewController: UIViewController?, selector: Int, openLoginWeb: Bool) { +// openLogin(selector: NCGlobal.shared.introLogin) + // [WEBPersonalized] [AppConfig] + if NCBrandOptions.shared.use_login_web_personalized || NCBrandOptions.shared.use_AppConfig { + + if activeLoginWeb?.view.window == nil { + activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb + activeLoginWeb?.urlBase = NCBrandOptions.shared.loginBaseUrl + showLoginViewController(activeLoginWeb, contextViewController: viewController) + } + return + } + + // Nextcloud standard login + if selector == NCGlobal.shared.introSignup { + + if activeLoginWeb?.view.window == nil { + activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb + if selector == NCGlobal.shared.introSignup { + activeLoginWeb?.urlBase = NCBrandOptions.shared.linkloginPreferredProviders + } else { + activeLoginWeb?.urlBase = self.urlBase + } + showLoginViewController(activeLoginWeb, contextViewController: viewController) + } + + } else if NCBrandOptions.shared.disable_intro && NCBrandOptions.shared.disable_request_login_url { + + if activeLoginWeb?.view.window == nil { + activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb + activeLoginWeb?.urlBase = NCBrandOptions.shared.loginBaseUrl + showLoginViewController(activeLoginWeb, contextViewController: viewController) + } + + } else if openLoginWeb { + + // Used also for reinsert the account (change passwd) + if activeLoginWeb?.view.window == nil { + activeLoginWeb = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginWeb") as? NCLoginWeb + activeLoginWeb?.urlBase = urlBase + activeLoginWeb?.user = user + showLoginViewController(activeLoginWeb, contextViewController: viewController) + } + + } else { + + if activeLogin?.view.window == nil { + activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin + showLoginViewController(activeLogin, contextViewController: viewController) + } + } + } + + func showLoginViewController(_ viewController: UIViewController?) { + guard let viewController else { return } + let navigationController = UINavigationController(rootViewController: viewController) + + navigationController.modalPresentationStyle = .fullScreen + navigationController.navigationBar.barStyle = .black + navigationController.navigationBar.tintColor = NCBrandColor.shared.customerText + navigationController.navigationBar.barTintColor = NCBrandColor.shared.customer + navigationController.navigationBar.isTranslucent = false + + if let controller = UIApplication.shared.firstWindow?.rootViewController { + if let presentedVC = controller.presentedViewController, !(presentedVC is UINavigationController) { + presentedVC.dismiss(animated: false) { + controller.present(navigationController, animated: true) + } + } else { + controller.present(navigationController, animated: true) + } + } else { + window?.rootViewController = navigationController + window?.makeKeyAndVisible() + } + } + + func showLoginViewController(_ viewController: UIViewController?, contextViewController: UIViewController?) { + + if contextViewController == nil { + if let viewController = viewController { + let navigationController = UINavigationController(rootViewController: viewController) + navigationController.navigationBar.barStyle = .black + navigationController.navigationBar.tintColor = NCBrandColor.shared.customerText + navigationController.navigationBar.barTintColor = NCBrandColor.shared.customer + navigationController.navigationBar.isTranslucent = false + window?.rootViewController = navigationController + window?.makeKeyAndVisible() + } + } else if contextViewController is UINavigationController { + if let contextViewController = contextViewController, let viewController = viewController { + (contextViewController as? UINavigationController)?.pushViewController(viewController, animated: true) + } + } else { + if let viewController = viewController, let contextViewController = contextViewController { + let navigationController = UINavigationController(rootViewController: viewController) + navigationController.modalPresentationStyle = .fullScreen + navigationController.navigationBar.barStyle = .black + navigationController.navigationBar.tintColor = NCBrandColor.shared.customerText + navigationController.navigationBar.barTintColor = NCBrandColor.shared.customer + navigationController.navigationBar.isTranslucent = false + contextViewController.present(navigationController, animated: true) { } + } + } + } + + @objc func startTimerErrorNetworking() { + timerErrorNetworking = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(checkErrorNetworking), userInfo: nil, repeats: true) + } + + @objc private func checkErrorNetworking() { + guard !account.isEmpty, NCKeychain().getPassword(account: account).isEmpty else { return } + openLogin(viewController: window?.rootViewController, selector: NCGlobal.shared.introLogin, openLoginWeb: true) + } + // MARK: - func trustCertificateError(host: String) { @@ -280,10 +716,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD UIApplication.shared.mainAppWindow?.rootViewController?.present(alertController, animated: true) } + + // MARK: - Account + + @objc func changeAccount(_ account: String, userProfile: NKUserProfile?) { +// NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeUser) + } + + @objc func deleteAccount(_ account: String, wipe: Bool) { + NCAccount().deleteAccount(account, wipe: wipe) + } + + func deleteAllAccounts() { + let accounts = NCManageDatabase.shared.getAccounts() + accounts?.forEach({ account in + deleteAccount(account, wipe: true) + }) + } + + func updateShareAccounts() -> Error? { + return NCAccount().updateAppsShareAccounts() + } // MARK: - Reset Application - func resetApplication() { + @objc func resetApplication() { let utilityFileSystem = NCUtilityFileSystem() NCNetworking.shared.cancelAllTask() @@ -296,6 +753,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD utilityFileSystem.removeTemporaryDirectory() NCPreferences().removeAll() +// NCKeychain().removeAll() +// NCNetworking.shared.removeAllKeyUserDefaultsData(account: nil) exit(0) } diff --git a/iOSClient/Helper/AdjustHelper.h b/iOSClient/Helper/AdjustHelper.h new file mode 100644 index 0000000000..9b63269a17 --- /dev/null +++ b/iOSClient/Helper/AdjustHelper.h @@ -0,0 +1,48 @@ +// +// AdjustHelper.h +// Nextcloud +// +// Created by A200073704 on 17/05/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// +#import +//#import +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef enum : NSUInteger { + Login, + LoginSuccessful, + Sharing, + CreateLink, + DocumentScan, + CameraUpload, + FileUpload, + UseCamera, + Logout, + ResetsApp, + AutomaticUploadPhotosOn, + AutomaticUploadPhotosOff, + ManualBackup, + AutomaticBackup +} TriggerEvent; + +@interface AdjustHelper : NSObject + +@property (nonatomic, strong) NSString *yourAppToken; +@property (nonatomic, strong) NSString *environment; +@property (nonatomic, strong) ADJConfig *adjustConfig; +@property (nonatomic, strong) ADJEvent *eventLogin; +@property (nonatomic, strong) ADJEvent *event; +@property (nonatomic, assign) TriggerEvent triggerEvent; + +-(void)configAdjust; +-(void)subsessionEnd; +-(void)subsessionStart; +-(void)trackLogin; +-(void)trackEvent:(TriggerEvent)event; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOSClient/Helper/AdjustHelper.m b/iOSClient/Helper/AdjustHelper.m new file mode 100644 index 0000000000..5556a35d13 --- /dev/null +++ b/iOSClient/Helper/AdjustHelper.m @@ -0,0 +1,153 @@ +// +// AdjustHelper.m +// Nextcloud +// +// Created by A200073704 on 17/05/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +#import "AdjustHelper.h" +//#import + +@implementation AdjustHelper + +-(void)configAdjust { + self.yourAppToken = @"1zfaxn19pd7k"; + self.environment = ADJEnvironmentProduction; + self.adjustConfig = [[ADJConfig alloc] initWithAppToken:self.yourAppToken + environment:self.environment]; + [self.adjustConfig setLogLevel:ADJLogLevelVerbose]; + [Adjust initSdk:self.adjustConfig]; +} + +-(void)subsessionEnd { + [Adjust trackSubsessionEnd]; +} + +-(void)subsessionStart { + [Adjust trackSubsessionStart]; +} + +- (void)trackLogin { + self.eventLogin = [[ADJEvent alloc] initWithEventToken:@"p8hl78"]; +// self.eventLogin = [ADJEvent eventWithEventToken:@"p8hl78"]; + [Adjust trackEvent: self.eventLogin]; +} + +-(void)trackEvent:(TriggerEvent)event { +// self.event = [ADJEvent eventWithEventToken:@"gb97gb"]; + BOOL track = [[NSUserDefaults standardUserDefaults] valueForKey:@"isAnalysisDataCollectionSwitchOn"]; + if (!track) { + return; + } + + switch(event){ + case Login: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"p8hl78"]; +// event = [ADJEvent eventWithEventToken:@"gb97gb"]; +// self.event = [ADJEvent eventWithEventToken:@"gb97gb"]; + [Adjust trackEvent:event]; + } + break; + case LoginSuccessful: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"dowf81"]; + // event = [ADJEvent eventWithEventToken:@"gb97gb"]; + // self.event = [ADJEvent eventWithEventToken:@"gb97gb"]; + [Adjust trackEvent:event]; + } + break; + case Sharing: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"mbeoyd"]; + [Adjust trackEvent:event]; + NSLog(@"%@", [event debugDescription]); + } +// self.event = [ADJEvent eventWithEventToken:@"fqtiu7"]; + break; + case CreateLink: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"29b333"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"qeyql3"]; + break; + case DocumentScan: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"im963g"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"7fec8n"]; + break; + case CameraUpload: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"hf9paq"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"v1g6ly"]; + break; + case FileUpload: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"hsbk2m"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"4rd8r4"]; + break; + case UseCamera: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"3czack"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"3czack"]; + break; + case Logout: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"n5q2qu"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"g6mj9y"]; + break; + case ResetsApp: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"3sj1xp"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"zi18r0"]; + break; + case AutomaticUploadPhotosOn: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"5lxz6h"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"vwd9yk"]; + break; + case AutomaticUploadPhotosOff: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"176496"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"e95w5t"]; + break; + case ManualBackup: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"oojr4y"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"oojr4y"]; + break; + case AutomaticBackup: + { + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:@"7dkhkx"]; + [Adjust trackEvent:event]; + } +// self.event = [ADJEvent eventWithEventToken:@"7dkhkx"]; + break; + + default : + break; + } +// [Adjust trackEvent: self.event]; +} + +@end diff --git a/iOSClient/Helper/TealiumHelper.swift b/iOSClient/Helper/TealiumHelper.swift new file mode 100644 index 0000000000..6d4065b5ea --- /dev/null +++ b/iOSClient/Helper/TealiumHelper.swift @@ -0,0 +1,55 @@ +// +// TealiumHelper.swift +// Nextcloud +// +// Created by A200073704 on 17/05/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// +import TealiumCore +import TealiumLifecycle +import TealiumAutotracking +import TealiumLocation +import TealiumRemoteCommands +import TealiumTagManagement +import TealiumVisitorService +import Foundation + +class TealiumHelper: NSObject { + static let shared = TealiumHelper() + let config = TealiumConfig(account: "telekom", + profile: "magentacloud-app", + environment: "dev") + var tealium: Tealium? + + @objc override init() { + + config.batchingEnabled = true + config.logLevel = .debug + + config.collectors = [Collectors.Lifecycle, + Collectors.Location, + Collectors.VisitorService] + + config.dispatchers = [Dispatchers.TagManagement, + Dispatchers.RemoteCommands] + + tealium = Tealium(config: config, enableCompletion: {value in + print(value) + } + ) + } + + func start() { + _ = TealiumHelper.shared + } + + @objc func trackView(title: String, data: [String: Any]?) { + let tealView = TealiumView(title, dataLayer: data) + TealiumHelper.shared.tealium?.track(tealView) + } + + @objc func trackEvent(title: String, data: [String: Any]?) { + let tealEvent = TealiumEvent(title, dataLayer: data) + TealiumHelper.shared.tealium?.track(tealEvent) + } +} diff --git a/iOSClient/Nextcloud-Bridging-Header.h b/iOSClient/Nextcloud-Bridging-Header.h index 465ea9cd9a..dba1c10ea4 100644 --- a/iOSClient/Nextcloud-Bridging-Header.h +++ b/iOSClient/Nextcloud-Bridging-Header.h @@ -7,3 +7,4 @@ #import "UIImage+animatedGIF.h" #import "NCPushNotificationEncryption.h" #import "TOPasscodeViewController.h" +#import "AdjustHelper.h" diff --git a/iOSClient/Settings/CCAdvanced.h b/iOSClient/Settings/CCAdvanced.h new file mode 100755 index 0000000000..7f9845888f --- /dev/null +++ b/iOSClient/Settings/CCAdvanced.h @@ -0,0 +1,29 @@ +// +// CCAdvanced.h +// Nextcloud +// +// Created by Marino Faggiana on 12/04/17. +// Copyright (c) 2017 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#import +#import + +@interface CCAdvanced : XLFormViewController + +@end diff --git a/iOSClient/Settings/CCAdvanced.m b/iOSClient/Settings/CCAdvanced.m new file mode 100755 index 0000000000..4ab8e5a55f --- /dev/null +++ b/iOSClient/Settings/CCAdvanced.m @@ -0,0 +1,601 @@ +// +// CCManageHelp.m +// Nextcloud +// +// Created by Marino Faggiana on 06/11/15. +// Copyright (c) 2015 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#import "CCAdvanced.h" +#import "CCUtility.h" +#import "NCBridgeSwift.h" +#import "AdjustHelper.h" +//#import + +@interface CCAdvanced () +{ + AppDelegate *appDelegate; + XLFormSectionDescriptor *sectionSize; + TealiumHelper *tealium; + AdjustHelper *adjust; +} +@end + +@implementation CCAdvanced + +- (void)initializeForm +{ + XLFormDescriptor *form = [XLFormDescriptor formDescriptor]; + XLFormSectionDescriptor *section; + XLFormRowDescriptor *row; + + // Section HIDDEN FILES ------------------------------------------------- + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"showHiddenFiles" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_show_hidden_files_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if ([[[NCKeychain alloc] init] showHiddenFiles]) row.value = @"1"; + else row.value = @"0"; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Format Compatibility + Live Photo + Delete asset + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + section.footerTitle = [NSString stringWithFormat:@"%@\n%@\n%@", NSLocalizedString(@"_format_compatibility_footer_", nil), NSLocalizedString(@"_upload_mov_livephoto_footer_", nil), NSLocalizedString(@"_remove_photo_CameraRoll_desc_", nil)]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"formatCompatibility" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_format_compatibility_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if ([[[NCKeychain alloc] init] formatCompatibility]) row.value = @"1"; + else row.value = @"0"; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"livePhoto" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_upload_mov_livephoto_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if ([[[NCKeychain alloc] init] livePhoto]) row.value = @"1"; + else row.value = @"0"; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"removePhotoCameraRoll" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_remove_photo_CameraRoll_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if ([[[NCKeychain alloc] init] removePhotoCameraRoll]) row.value = @"1"; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [section addFormRow:row]; + + // Section : Files App -------------------------------------------------------------- + + if (![NCBrandOptions shared].disable_openin_file) { + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + section.footerTitle = NSLocalizedString(@"_disable_files_app_footer_", nil); + + // Disable Files App + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"disablefilesapp" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_disable_files_app_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if ([[NCKeychain alloc] init].disableFilesApp) row.value = @"1"; + else row.value = @"0"; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + } + + // Section : Privacy -------------------------------------------------------------- + + if (!NCBrandOptions.shared.disable_crash_service) { + + section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_privacy_", nil)]; + [form addFormSection:section]; + section.footerTitle = NSLocalizedString(@"_privacy_footer_", nil); + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"crashservice" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_crashservice_title_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"crashservice"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + if ([[[NCKeychain alloc] init] disableCrashservice]) row.value = @"1"; + else row.value = @"0"; + [section addFormRow:row]; + } + +//#ifdef DEBUG + // Section DIAGNOSTICS ------------------------------------------------- + + section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_diagnostics_", nil)]; + [form addFormSection:section]; + + if ([[NSFileManager defaultManager] fileExistsAtPath:NextcloudKit.shared.nkCommonInstance.filenamePathLog] && NCBrandOptions.shared.disable_log == false) { + // with Nextcloudkit latest version will uncomment below line once updated to latest Nextcloudkit version +// if ([[NSFileManager defaultManager] fileExistsAtPath:NKLogFileManager.shared.logDirectory.path] && NCBrandOptions.shared.disable_log == false) { +// if (NCBrandOptions.shared.disable_log) { + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"log" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_view_log_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"log"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + row.action.formBlock = ^(XLFormRowDescriptor * sender) { + + [self deselectFormRow:sender]; + +// NSURL *logFilePath = [self getLogFilePath]; +// if (logFilePath) { +// // Use the log file path (e.g., to write logs) +// NSLog(@"Log file path: %@", logFilePath.path); +// NCViewerQuickLook *viewerQuickLook = [[NCViewerQuickLook alloc] initWith:logFilePath fileNameSource:@"" isEditingEnabled:false metadata:nil]; +// [self presentViewController:viewerQuickLook animated:YES completion:nil]; +// } else { +// // Handle error (logs folder could not be created) +// NSLog(@"Failed to get log file path."); +// } + + NCViewerQuickLook *viewerQuickLook = [[NCViewerQuickLook alloc] initWith:[NSURL fileURLWithPath:NextcloudKit.shared.nkCommonInstance.filenamePathLog] fileNameSource:@"" isEditingEnabled:false metadata:nil]; + // with Nextcloudkit latest version will uncomment below line once updated to latest Nextcloudkit version +// NCViewerQuickLook *viewerQuickLook = [[NCViewerQuickLook alloc] initWith:[NSURL fileURLWithPath:NKLogFileManager.shared.logDirectory.path] fileNameSource:NKLogFileManager.shared.logFileName isEditingEnabled:false metadata:nil]; +// NCViewerQuickLook *viewerQuickLook = [[NCViewerQuickLook alloc] initWith:[NSURL fileURLWithPath:@""] fileNameSource:@"" isEditingEnabled:false metadata:nil]; + [self presentViewController:viewerQuickLook animated:YES completion:nil]; + }; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"logLevel" rowType:XLFormRowDescriptorTypeSelectorPush title:NSLocalizedString(@"_set_log_level_", nil)]; + NSInteger logLevel = [[NCKeychain alloc] init].logLevel; + row.value = @(logLevel); + switch ([[NCKeychain alloc] init].logLevel) { + case 0: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(0) displayText:NSLocalizedString(@"_disabled_", nil)]; + break; + case 1: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(1) displayText:NSLocalizedString(@"_standard_", nil)]; + break; + case 2: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(2) displayText:NSLocalizedString(@"_maximum_", nil)]; + break; + default: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(1) displayText:NSLocalizedString(@"_standard_", nil)]; + break; + } + + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.cellConfigForSelector[@"tintColor"] = NCBrandColor.shared.customer; + row.selectorTitle = NSLocalizedString(@"_set_log_level_", nil); + row.selectorOptions = @[[XLFormOptionsObject formOptionsObjectWithValue:@(0) displayText:NSLocalizedString(@"_disabled_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(1) displayText:NSLocalizedString(@"_standard_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(2) displayText:NSLocalizedString(@"_maximum_", nil)], + ]; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"clearlog" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_clear_log_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"clear"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + row.action.formBlock = ^(XLFormRowDescriptor * sender) { + + [self deselectFormRow:sender]; + + [[[NextcloudKit shared] nkCommonInstance] clearFileLog]; + // with Nextcloudkit latest version will uncomment below line once updated to latest Nextcloudkit version +// [[NKLogFileManager shared] clearLogFiles]; +// [self createLogFiles]; + + NSInteger logLevel = [[NCKeychain alloc] init].logLevel; + BOOL isSimulatorOrTestFlight = [[[NCUtility alloc] init] isSimulatorOrTestFlight]; + NSString *versionNextcloudiOS = [NSString stringWithFormat:[NCBrandOptions shared].textCopyrightNextcloudiOS, [[[NCUtility alloc] init] getVersionAppWithBuild:true]]; + if (isSimulatorOrTestFlight) { + [[[NextcloudKit shared] nkCommonInstance] writeLog:[NSString stringWithFormat:@"[INFO] Clear log with level %lu %@ (Simulator / TestFlight)", (unsigned long)logLevel, versionNextcloudiOS]]; + } else { + [[[NextcloudKit shared] nkCommonInstance] writeLog:[NSString stringWithFormat:@"[INFO] Clear log with level %lu %@", (unsigned long)logLevel, versionNextcloudiOS]]; + } + // with Nextcloudkit latest version will uncomment below line once updated to latest Nextcloudkit version +// if (isSimulatorOrTestFlight) { +// [[NKLogFileManager shared] writeLogWithInfo:[NSString stringWithFormat:@"[INFO] Clear log with level %lu %@ (Simulator / TestFlight)", (unsigned long)logLevel, versionNextcloudiOS]]; +// } else { +// [[NKLogFileManager shared] writeLogWithInfo:[NSString stringWithFormat:@"[INFO] Clear log with level %lu %@", (unsigned long)logLevel, versionNextcloudiOS]]; +// } + }; + [section addFormRow:row]; + + } + +#ifdef DEBUG + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"capabilities" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_capabilities_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"capabilities"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + row.action.formBlock = ^(XLFormRowDescriptor * sender) { + + [self deselectFormRow:sender]; + + UIViewController *vc = [[NCHostingCapabilitiesView alloc] makeShipDetailsUI]; + [self.navigationController pushViewController:vc animated:YES]; + }; + [section addFormRow:row]; +#endif + + // Section : Delete files / Clear cache -------------------------------------------------------------- + + sectionSize = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_delete_files_desc_", nil)]; + [form addFormSection:sectionSize]; + sectionSize.footerTitle = NSLocalizedString(@"_clear_cache_footer_", nil); + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"deleteoldfiles" rowType:XLFormRowDescriptorTypeSelectorPush title:NSLocalizedString(@"_delete_old_files_", nil)]; + + switch ([[NCKeychain alloc] init].cleanUpDay) { + case 0: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(0) displayText:NSLocalizedString(@"_never_", nil)]; + break; + case 365: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(365) displayText:NSLocalizedString(@"_1_year_", nil)]; + break; + case 180: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(180) displayText:NSLocalizedString(@"_6_months_", nil)]; + break; + case 90: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(90) displayText:NSLocalizedString(@"_3_months_", nil)]; + break; + case 30: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(30) displayText:NSLocalizedString(@"_1_month_", nil)]; + break; + case 7: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(7) displayText:NSLocalizedString(@"_1_week_", nil)]; + break; + case 1: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(1) displayText:NSLocalizedString(@"_1_day_", nil)]; + break; + default: + row.value = [XLFormOptionsObject formOptionsObjectWithValue:@(0) displayText:NSLocalizedString(@"_never_", nil)]; + break; + } + + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.cellConfigForSelector[@"tintColor"] = NCBrandColor.shared.customer; + row.selectorTitle = NSLocalizedString(@"_delete_old_files_", nil); + row.selectorOptions = @[[XLFormOptionsObject formOptionsObjectWithValue:@(0) displayText:NSLocalizedString(@"_never_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(365) displayText:NSLocalizedString(@"_1_year_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(180) displayText:NSLocalizedString(@"_6_months_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(90) displayText:NSLocalizedString(@"_3_months_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(30) displayText:NSLocalizedString(@"_1_month_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(7) displayText:NSLocalizedString(@"_1_week_", nil)], + ]; + [sectionSize addFormRow:row]; + + // Clear cache + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"azzeracache" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_clear_cache_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"trash"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + row.action.formSelector = @selector(clearCacheRequest:); + [sectionSize addFormRow:row]; + + // Section EXIT -------------------------------------------------------- + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + section.footerTitle = NSLocalizedString(@"_exit_footer_", nil); + + // Exit + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"esci" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_exit_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:[UIColor redColor] forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"xmark"] imageWithColor:[UIColor redColor] size:25] forKey:@"imageView.image"]; + row.action.formSelector = @selector(exitNextcloud:); + [section addFormRow:row]; + + self.tableView.showsVerticalScrollIndicator = NO; + self.form = form; +} + +// MARK: - View Life Cycle + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = NSLocalizedString(@"_advanced_", nil); + appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + self.view.backgroundColor = UIColor.systemGroupedBackgroundColor; + + adjust = [[AdjustHelper alloc] init]; + self.tableView.backgroundColor = UIColor.systemGroupedBackgroundColor; + + [self initializeForm]; + [self calculateSize]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + appDelegate.activeViewController = self; +} + +#pragma mark - + +- (void)formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)rowDescriptor oldValue:(id)oldValue newValue:(id)newValue +{ + [super formRowDescriptorValueHasChanged:rowDescriptor oldValue:oldValue newValue:newValue]; + + if ([rowDescriptor.tag isEqualToString:@"showHiddenFiles"]) { + + [[NCKeychain alloc] init].showHiddenFiles = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"formatCompatibility"]) { + + [[NCKeychain alloc] init].formatCompatibility = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"livePhoto"]) { + + [[NCKeychain alloc] init].livePhoto = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"removePhotoCameraRoll"]) { + + [[NCKeychain alloc] init].removePhotoCameraRoll = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"disablefilesapp"]) { + + [[NCKeychain alloc] init].disableFilesApp = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"crashservice"]) { + + [[NCKeychain alloc] init].disableCrashservice = [[rowDescriptor.value valueData] boolValue]; + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_crashservice_title_", nil) message:NSLocalizedString(@"_crashservice_alert_", nil) preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + exit(0); + }]; + + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; + } + + if ([rowDescriptor.tag isEqualToString:@"logLevel"]) { + + NSInteger levelLog = [[rowDescriptor.value valueData] intValue]; + [[NCKeychain alloc] init].logLevel = levelLog; + [[[NextcloudKit shared] nkCommonInstance] setLevelLog:levelLog]; + } + + if ([rowDescriptor.tag isEqualToString:@"deleteoldfiles"]) { + + NSInteger days = [[rowDescriptor.value valueData] intValue]; + [[NCKeychain alloc] init].cleanUpDay = days; + } +} + +#pragma mark - Log files + +- (NSURL *)getLogFilePath { + // Define the log file name + NSString *logFileName = @"log.txt"; + + // Get the documents directory URL + NSArray *documentURLs = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; + NSURL *documentsDirectory = [documentURLs firstObject]; + + // Define the logs folder URL + NSURL *logsFolder = [documentsDirectory URLByAppendingPathComponent:@"Logs" isDirectory:YES]; + + // Check if the "Logs" folder exists + if (![[NSFileManager defaultManager] fileExistsAtPath:logsFolder.path]) { + NSError *error = nil; + // Create the "Logs" folder if it doesn't exist + BOOL success = [[NSFileManager defaultManager] createDirectoryAtURL:logsFolder withIntermediateDirectories:YES attributes:nil error:&error]; + if (!success) { + NSLog(@"Failed to create Logs folder: %@", error.localizedDescription); + return nil; // Return nil in case of error + } + } + + // Create the full log file path + NSURL *logPath = [logsFolder URLByAppendingPathComponent:logFileName]; + + // Return the log file path + return logPath; +} + +// Method to create log files +- (void)createLogFiles { + + // Property to control whether to copy log to the Documents directory + BOOL copyLogToDocumentDirectory; + + copyLogToDocumentDirectory = (!NCBrandOptions.shared.disable_log) ? YES : NO; + + // Define log file paths + NSString *filenamePathLog = @"/log.txt"; // Set your desired path for the log file + NSString *filenameLog = @"log.txt"; // This will be the filename to copy + + // Create the log file at the given path + BOOL success = [[NSFileManager defaultManager] createFileAtPath:filenamePathLog contents:nil attributes:nil]; + if (!success) { + NSLog(@"Failed to create file at path: %@", filenamePathLog); + } + + // If we want to copy the log file to the Documents directory + if (copyLogToDocumentDirectory) { // Check the property value + NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentDirectory = [documentPaths firstObject]; + + // Create the path to copy the log file in Documents directory + NSString *filenameCopyToDocumentDirectory = [documentDirectory stringByAppendingPathComponent:filenameLog]; + + // Create the log file at the new path in the Documents directory + success = [[NSFileManager defaultManager] createFileAtPath:filenameCopyToDocumentDirectory contents:nil attributes:nil]; + if (!success) { + NSLog(@"Failed to create file at Documents path: %@", filenameCopyToDocumentDirectory); + } + } +} + + +#pragma mark - Clear Cache + +- (void)clearCache:(NSString *)account +{ + [[NCNetworking shared] cancelAllTask]; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) { + + NCUtilityFileSystem *ufs = [[NCUtilityFileSystem alloc] init]; + + [[NSURLCache sharedURLCache] setMemoryCapacity:0]; + [[NSURLCache sharedURLCache] setDiskCapacity:0]; + + [[NCManageDatabase shared] clearDatabaseWithAccount:account removeAccount:false removeAutoUpload:false]; +// [[NCManageDatabase shared] clearDatabaseWithAccount:account removeAccount:false]; + + [ufs removeGroupDirectoryProviderStorage]; + [ufs removeGroupLibraryDirectory]; + + [ufs removeDocumentsDirectory]; + [ufs removeTemporaryDirectory]; + + [ufs createDirectoryStandard]; + + [[NCAutoUpload shared] alignPhotoLibraryWithController:self account:appDelegate.account]; +// [[NCAutoUpload shared] alignPhotoLibraryWithViewController:self]; + + [[NCImageCache shared] createMediaCacheWithAccount:appDelegate.account withCacheSize:true]; + + [[NCActivityIndicator shared] stop]; + tealium = [[TealiumHelper alloc] init]; + [tealium trackEventWithTitle:@"magentacloud-app.settings.reset" data:nil]; + [adjust trackEvent:ResetsApp]; + [self calculateSize]; + }); +} + +- (void)clearCacheRequest:(XLFormRowDescriptor *)sender +{ + [self deselectFormRow:sender]; + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:NSLocalizedString(@"_want_delete_cache_", nil) preferredStyle:UIAlertControllerStyleActionSheet]; + + [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_yes_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + [[NCActivityIndicator shared] startActivityWithBackgroundView:nil style: UIActivityIndicatorViewStyleLarge blurEffect:true]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) { + [self clearCache:appDelegate.account]; + }); + }]]; + + [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { + }]]; + + alertController.popoverPresentationController.sourceView = self.view; + NSIndexPath *indexPath = [self.form indexPathOfFormRow:sender]; + CGRect cellRect = [self.tableView rectForRowAtIndexPath:indexPath]; + alertController.popoverPresentationController.sourceRect = CGRectOffset(cellRect, -self.tableView.contentOffset.x, -self.tableView.contentOffset.y); + + [self presentViewController:alertController animated:YES completion:nil]; +} + + +- (void)clearAllCacheRequest:(XLFormRowDescriptor *)sender +{ + [self deselectFormRow:sender]; + + [[NCActivityIndicator shared] startActivityWithBackgroundView:nil style: UIActivityIndicatorViewStyleLarge blurEffect:true]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) { + [self clearCache:nil]; + }); +} + +- (void)calculateSize +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NCUtilityFileSystem *ufs = [[NCUtilityFileSystem alloc] init]; + NSString *directory = [ufs directoryProviderStorage]; + int64_t totalSize = [ufs getDirectorySizeWithDirectory:directory]; + sectionSize.footerTitle = [NSString stringWithFormat:@"%@. (%@ %@)", NSLocalizedString(@"_clear_cache_footer_", nil), NSLocalizedString(@"_used_space_", nil), [ufs transformedSize:totalSize]]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self.tableView reloadData]; + }); + }); +} + +#pragma mark - Exit Nextcloud + +- (void)exitNextcloud:(XLFormRowDescriptor *)sender +{ + [self deselectFormRow:sender]; + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:NSLocalizedString(@"_want_exit_", nil) preferredStyle:UIAlertControllerStyleActionSheet]; + + [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { + tealium = [[TealiumHelper alloc] init]; + [tealium trackEventWithTitle:@"magentacloud-app.settings.logout" data:nil]; + [adjust trackEvent:Logout]; + [appDelegate resetApplication]; + }]]; + + [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { + }]]; + + alertController.popoverPresentationController.sourceView = self.view; + NSIndexPath *indexPath = [self.form indexPathOfFormRow:sender]; + CGRect cellRect = [self.tableView rectForRowAtIndexPath:indexPath]; + alertController.popoverPresentationController.sourceRect = CGRectOffset(cellRect, -self.tableView.contentOffset.x, -self.tableView.contentOffset.y); + + [self presentViewController:alertController animated:YES completion:nil]; +} + +#pragma mark - + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + + if (indexPath.section == 4 && indexPath.row == 2) { + return 80; + } else { + return NCGlobal.shared.heightCellSettings; + } +} + +@end diff --git a/iOSClient/Settings/CCManageAutoUpload.h b/iOSClient/Settings/CCManageAutoUpload.h new file mode 100644 index 0000000000..1e6b701cfc --- /dev/null +++ b/iOSClient/Settings/CCManageAutoUpload.h @@ -0,0 +1,28 @@ +// +// CCManageAutoUpload.h +// Nextcloud +// +// Created by Marino Faggiana on 01/09/15. +// Copyright (c) 2015 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#import + +@interface CCManageAutoUpload : XLFormViewController + +@end diff --git a/iOSClient/Settings/CCManageAutoUpload.m b/iOSClient/Settings/CCManageAutoUpload.m new file mode 100644 index 0000000000..7c444121d5 --- /dev/null +++ b/iOSClient/Settings/CCManageAutoUpload.m @@ -0,0 +1,512 @@ +// +// CCManageAutoUpload.m +// Nextcloud +// +// Created by Marino Faggiana on 01/09/15. +// Copyright (c) 2015 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#import +#import "CCManageAutoUpload.h" +#import "CCUtility.h" +#import "NCBridgeSwift.h" +#import "AdjustHelper.h" + +@interface CCManageAutoUpload () +{ + AppDelegate *appDelegate; + AdjustHelper *adjust; + TealiumHelper *tealium; +} +@end + +@implementation CCManageAutoUpload + +- (void)initializeForm +{ + XLFormDescriptor *form = [XLFormDescriptor formDescriptor]; + XLFormSectionDescriptor *section; + XLFormRowDescriptor *row; + + tableAccount *activeAccount = [[NCManageDatabase shared] getActiveTableAccount]; + + // Auto Upload + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + section.footerTitle = NSLocalizedString(@"_autoupload_description_", nil); + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUpload" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_autoupload_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + if (activeAccount.autoUpload) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Auto Upload Directory + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadDirectory" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_autoupload_select_folder_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"foldersOnTop"] imageWithColor:NCBrandColor.shared.iconColor size:25] forKey:@"imageView.image"]; + [row.cellConfig setObject:[[UIImage imageNamed:@"foldersOnTop"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + //[row.cellConfig setObject:@(UITableViewCellAccessoryDisclosureIndicator) forKey:@"accessoryType"]; + row.action.formSelector = @selector(selectAutomaticUploadFolder); + [section addFormRow:row]; + + // Auto Upload Photo + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadImage" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_autoupload_photos_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if (activeAccount.autoUploadImage) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadWWAnPhoto" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_wifi_only_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if (activeAccount.autoUploadWWAnPhoto) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Auto Upload Video + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadVideo" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_autoupload_videos_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if (activeAccount.autoUploadVideo) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadWWAnVideo" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_wifi_only_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if (activeAccount.autoUploadWWAnVideo) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Delete asset remove photo camera roll + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"removePhotoCameraRoll" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_remove_photo_CameraRoll_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if ([[[NCKeychain alloc] init] removePhotoCameraRoll]) row.value = @"1"; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Auto Upload Full + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + NSString *title = NSLocalizedString(@"_autoupload_fullphotos_", nil); + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadStart" rowType:XLFormRowDescriptorTypeBooleanSwitch title:title]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + row.value = 0; + if (activeAccount.autoUploadStart) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + // Auto Upload create subfolder + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadCreateSubfolder" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_autoupload_create_subfolder_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + if (activeAccount.autoUploadCreateSubfolder) row.value = @1; + else row.value = @0; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.cellConfig[@"switchControl.onTintColor"] = NCBrandColor.shared.brand; + [section addFormRow:row]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadSubfolderGranularity" rowType:XLFormRowDescriptorTypeSelectorPush title:NSLocalizedString(@"_autoupload_subfolder_granularity_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + row.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + row.cellConfigForSelector[@"tintColor"] = NCBrandColor.shared.customer; + row.selectorOptions = @[ + [XLFormOptionsObject formOptionsObjectWithValue:@(NCGlobal.shared.subfolderGranularityYearly) displayText:NSLocalizedString(@"_yearly_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(NCGlobal.shared.subfolderGranularityMonthly) displayText:NSLocalizedString(@"_monthly_", nil)], + [XLFormOptionsObject formOptionsObjectWithValue:@(NCGlobal.shared.subfolderGranularityDaily) displayText:NSLocalizedString(@"_daily_", nil)] + ]; + row.value = row.selectorOptions[activeAccount.autoUploadSubfolderGranularity]; + row.required = true; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + [section addFormRow:row]; + + // Auto Upload file name + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadFileName" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_autoupload_filenamemask_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"]; + row.action.viewControllerClass = [NCManageAutoUploadFileName class]; + [section addFormRow:row]; + + // end + + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + + self.tableView.showsVerticalScrollIndicator = NO; + self.form = form; +} + +// MARK: - View Life Cycle + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = NSLocalizedString(@"_settings_autoupload_", nil); + appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; + self.view.backgroundColor = UIColor.systemGroupedBackgroundColor; + + adjust = [[AdjustHelper alloc] init]; + [adjust configAdjust]; + tealium = [[TealiumHelper alloc] init]; + self.tableView.backgroundColor = UIColor.systemGroupedBackgroundColor; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeUser) name:NCGlobal.shared.notificationCenterChangeUser object:nil]; + + [self initializeForm]; + [self reloadForm]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + appDelegate.activeViewController = self; + appDelegate.account = [[[NCKeychain alloc] init] getAccountName] ; + [[[NCAskAuthorization alloc] init] askAuthorizationPhotoLibraryWithController:self completion:^(BOOL status) { }]; +} + +- (void)changeUser +{ + // [[self navigationController] popViewControllerAnimated:YES]; + [self initializeForm]; + [self reloadForm]; +} + +#pragma mark - NotificationCenter + + +#pragma mark - + +-(void)formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)rowDescriptor oldValue:(id)oldValue newValue:(id)newValue +{ + [super formRowDescriptorValueHasChanged:rowDescriptor oldValue:oldValue newValue:newValue]; + + tableAccount *activeAccount = [[NCManageDatabase shared] getActiveTableAccount]; + + if ([rowDescriptor.tag isEqualToString:@"autoUpload"]) { + + if ([[rowDescriptor.value valueData] boolValue] == YES) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUpload" state:YES]; + + // Default + [[NCManageDatabase shared] setAccountAutoUploadFileName:nil]; + [[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) { + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadImage" state:YES]; + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadVideo" state:YES]; + } + + [[NCAutoUpload shared] alignPhotoLibraryWithController:self account:appDelegate.account]; + +// [[NCAutoUpload shared] alignPhotoLibraryWithViewController:self]; + + } else { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUpload" state:NO]; + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadStart" state:NO]; + + // remove + [[NCManageDatabase shared] clearMetadatasUploadWithAccount:appDelegate.account]; + } + + [self reloadForm]; + } + + if ([rowDescriptor.tag isEqualToString:@"removePhotoCameraRoll"]) { + + [[NCKeychain alloc] init].removePhotoCameraRoll = [[rowDescriptor.value valueData] boolValue]; + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadStart"]) { + + if ([[rowDescriptor.value valueData] boolValue] == YES) { + + [[NCAutoUpload shared] autoUploadFullPhotosWithController:self log:@"Auto upload full" account:appDelegate.account]; +// [[NCAutoUpload shared] autoUploadFullPhotosWithViewController:self log:@"Auto upload full"]; + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadStart" state:YES]; + + } else { + + [[NCManageDatabase shared] clearMetadatasUploadWithAccount:appDelegate.account]; + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadStart" state:NO]; + } + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadImage"]) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadImage" state:[[rowDescriptor.value valueData] boolValue]]; + + if ([[rowDescriptor.value valueData] boolValue] == YES) { + [[NCAutoUpload shared] alignPhotoLibraryWithController:self account:appDelegate.account]; +// [[NCAutoUpload shared] alignPhotoLibraryWithViewController:self]; + } + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadWWAnPhoto"]) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadWWAnPhoto" state:[[rowDescriptor.value valueData] boolValue]]; + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadVideo"]) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadVideo" state:[[rowDescriptor.value valueData] boolValue]]; + + if ([[rowDescriptor.value valueData] boolValue] == YES){ + [[NCAutoUpload shared] alignPhotoLibraryWithController:self account:appDelegate.account]; +// [[NCAutoUpload shared] alignPhotoLibraryWithViewController:self]; + } + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadWWAnVideo"]) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadWWAnVideo" state:[[rowDescriptor.value valueData] boolValue]]; + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadCreateSubfolder"]) { + + [[NCManageDatabase shared] setAccountAutoUploadProperty:@"autoUploadCreateSubfolder" state:[[rowDescriptor.value valueData] boolValue]]; + } + + if ([rowDescriptor.tag isEqualToString:@"autoUploadSubfolderGranularity"]) { + + [[NCManageDatabase shared] setAccountAutoUploadGranularity:@"autoUploadSubfolderGranularity" state:[[rowDescriptor.value valueData] integerValue]]; + } +} + +- (void)done:(XLFormRowDescriptor *)sender +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)reloadForm +{ + self.form.delegate = nil; + + XLFormRowDescriptor *rowAutoUpload = [self.form formRowWithTag:@"autoUpload"]; + + XLFormRowDescriptor *rowAutoUploadImage = [self.form formRowWithTag:@"autoUploadImage"]; + XLFormRowDescriptor *rowAutoUploadWWAnPhoto = [self.form formRowWithTag:@"autoUploadWWAnPhoto"]; + + XLFormRowDescriptor *rowAutoUploadVideo = [self.form formRowWithTag:@"autoUploadVideo"]; + XLFormRowDescriptor *rowAutoUploadWWAnVideo = [self.form formRowWithTag:@"autoUploadWWAnVideo"]; + XLFormRowDescriptor *rowRemovePhotoCameraRoll = [self.form formRowWithTag:@"removePhotoCameraRoll"]; + + XLFormRowDescriptor *rowAutoUploadFull = [self.form formRowWithTag:@"autoUploadStart"]; + + XLFormRowDescriptor *rowAutoUploadCreateSubfolder = [self.form formRowWithTag:@"autoUploadCreateSubfolder"]; + + XLFormRowDescriptor *rowAutoUploadSubfolderGranularity = [self.form formRowWithTag:@"autoUploadSubfolderGranularity"]; + + XLFormRowDescriptor *rowAutoUploadFileName = [self.form formRowWithTag:@"autoUploadFileName"]; + + // - STATUS --------------------- + tableAccount *activeAccount = [[NCManageDatabase shared] getActiveTableAccount]; + + if (activeAccount.autoUpload) + [rowAutoUpload setValue:@1]; else [rowAutoUpload setValue:@0]; + + if (activeAccount.autoUploadImage) + [rowAutoUploadImage setValue:@1]; else [rowAutoUploadImage setValue:@0]; + + if (activeAccount.autoUploadWWAnPhoto) + [rowAutoUploadWWAnPhoto setValue:@1]; else [rowAutoUploadWWAnPhoto setValue:@0]; + + if ([[[NCKeychain alloc] init] removePhotoCameraRoll]) + [rowRemovePhotoCameraRoll setValue:@1]; else [rowRemovePhotoCameraRoll setValue:@0]; + + if (activeAccount.autoUploadVideo) + [rowAutoUploadVideo setValue:@1]; else [rowAutoUploadVideo setValue:@0]; + + if (activeAccount.autoUploadWWAnVideo) + [rowAutoUploadWWAnVideo setValue:@1]; else [rowAutoUploadWWAnVideo setValue:@0]; + + if (activeAccount.autoUploadStart) + [rowAutoUploadFull setValue:@1]; else [rowAutoUploadFull setValue:@0]; + + if (activeAccount.autoUploadCreateSubfolder) + [rowAutoUploadCreateSubfolder setValue:@1]; else [rowAutoUploadCreateSubfolder setValue:@0]; + + [rowAutoUploadSubfolderGranularity setValue:rowAutoUploadSubfolderGranularity.selectorOptions[activeAccount.autoUploadSubfolderGranularity]]; + + // - HIDDEN -------------------------------------------------------------------------- + + rowAutoUploadImage.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + rowAutoUploadWWAnPhoto.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + rowAutoUploadVideo.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + rowAutoUploadWWAnVideo.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + rowRemovePhotoCameraRoll.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + rowAutoUploadFull.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + rowAutoUploadCreateSubfolder.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + rowAutoUploadSubfolderGranularity.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + rowAutoUploadFileName.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"]; + + // ----------------------------------------------------------------------------------- + + [self.tableView reloadData]; + + self.form.delegate = self; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return NCGlobal.shared.heightCellSettings; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + tableAccount *activeAccount = [[NCManageDatabase shared] getActiveTableAccount]; + NSString *sectionName; + NSString *autoUploadPath = [NSString stringWithFormat:@"%@/%@", [[NCManageDatabase shared] getAccountAutoUploadDirectoryWithUrlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account], [[NCManageDatabase shared] getAccountAutoUploadFileName]]; + + switch (section) + { + case 0: + sectionName = NSLocalizedString(@"_autoupload_description_", nil); + break; + case 1: + if (activeAccount.autoUpload) sectionName = [NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"_autoupload_current_folder_", nil), [self returnPathfromServerUrl:autoUploadPath urlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account]]; + else sectionName = @""; + break; + case 4: + if (activeAccount.autoUpload) sectionName = NSLocalizedString(@"_remove_photo_CameraRoll_desc_", nil); + else sectionName = @""; + break; + case 5: + if (activeAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_description_background_", nil); + else sectionName = @""; + break; + case 6: + if (activeAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_create_subfolder_footer_", nil); + else sectionName = @""; + break; + case 7: + if (activeAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_fullphotos_footer_", nil); + else sectionName = @""; + break; + } + return sectionName; +} + +- (void)dismissSelectWithServerUrl:(NSString * _Nullable)serverUrl metadata:(tableMetadata * _Nullable)metadata type:(NSString * _Nonnull)type items:(NSArray * _Nonnull)items overwrite:(BOOL)overwrite copy:(BOOL)copy move:(BOOL)move +{ + if (serverUrl != nil) { + + NSString* home = [[[NCUtilityFileSystem alloc] init] getHomeServerWithUrlBase:appDelegate.urlBase userId:appDelegate.userId]; + if ([serverUrl isEqualToString:home]) { +// NKError *error = [[NKError alloc] initWithErrorCode:NCGlobal.shared.errorInternalError errorDescription:@"_autoupload_error_select_folder_"];// responseData:nil]; +// [[[NCContentPresenter alloc] init] messageNotification:@"_error_" error:error delay:[[NCGlobal shared] dismissAfterSecond] type:messageTypeError afterDelay:0]; + return; + } + + // Settings new folder Automatatic upload + [[NCManageDatabase shared] setAccountAutoUploadFileName:serverUrl.lastPathComponent]; + NSString *path = [[[NCUtilityFileSystem alloc] init] deleteLastPathWithServerUrlPath:serverUrl home:home]; + if (path != nil) { + [[NCManageDatabase shared] setAccountAutoUploadDirectory:path urlBase:appDelegate.urlBase userId:appDelegate.userId account:appDelegate.account]; + } + // Reload + [self.tableView reloadData]; + } +} + +- (void)selectAutomaticUploadFolder + { + UINavigationController *navigationController = [[UIStoryboard storyboardWithName:@"NCSelect" bundle:nil] instantiateInitialViewController]; + NCSelect *viewController = (NCSelect *)navigationController.topViewController; + + viewController.delegate = self; + viewController.typeOfCommandView = 1; + + [self presentViewController:navigationController animated:YES completion:^{ + [self.tableView reloadData]; + }]; + } + +- (NSString *)returnPathfromServerUrl:(NSString *)serverUrl urlBase:(NSString *)urlBase userId:(NSString *)userId account:(NSString *)account +{ + NSString *homeServer = [[[NCUtilityFileSystem alloc] init] getHomeServerWithUrlBase:urlBase userId:userId]; + NSString *path = [serverUrl stringByReplacingOccurrencesOfString:homeServer withString:@""]; + return path; +} + +@end