diff --git a/Brand/Intro/NCIntro.storyboard b/Brand/Intro/NCIntro.storyboard index 1a4fabd425..c17b6df339 100644 --- a/Brand/Intro/NCIntro.storyboard +++ b/Brand/Intro/NCIntro.storyboard @@ -1,137 +1,123 @@ - + - + - + - - + + - - + + - - - - - + - - + + - - + - - - - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - + - + - + diff --git a/Brand/Intro/NCIntroCollectionViewCell.xib b/Brand/Intro/NCIntroCollectionViewCell.xib index 7eed66d3ba..ab7c53a1de 100644 --- a/Brand/Intro/NCIntroCollectionViewCell.xib +++ b/Brand/Intro/NCIntroCollectionViewCell.xib @@ -1,56 +1,57 @@ - + - + - + - - + - - - - - - + + + + + + + + - - + + - + diff --git a/Brand/Intro/NCIntroViewController.swift b/Brand/Intro/NCIntroViewController.swift index c626a4c557..5ffb2466af 100644 --- a/Brand/Intro/NCIntroViewController.swift +++ b/Brand/Intro/NCIntroViewController.swift @@ -4,6 +4,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import UIKit +import NextcloudKit class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { @IBOutlet weak var buttonLogin: UIButton! @@ -11,23 +12,30 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol @IBOutlet weak var buttonHost: UIButton! @IBOutlet weak var introCollectionView: UICollectionView! @IBOutlet weak var pageControl: UIPageControl! + @IBOutlet weak var contstraintBottomLoginButton: NSLayoutConstraint! weak var delegate: NCIntroViewController? // Controller var controller: NCMainTabBarController? private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! - private let titles = [NSLocalizedString("_intro_1_title_", comment: ""), NSLocalizedString("_intro_2_title_", comment: ""), NSLocalizedString("_intro_3_title_", comment: ""), NSLocalizedString("_intro_4_title_", comment: "")] - private let images = [UIImage(named: "intro1"), UIImage(named: "intro2"), UIImage(named: "intro3"), UIImage(named: "intro4")] + private let titles = [NSLocalizedString("", comment: ""), NSLocalizedString("", comment: ""), NSLocalizedString("", comment: "")] + private var images: [UIImage?] = [] private var timer: Timer? private var textColor: UIColor = .white private var textColorOpponent: UIColor = .black + private let imagesLandscape = [UIImage(named: "introSlideLand1"), UIImage(named: "introSlideLand2"), UIImage(named: "introSlideLand3")] + private let imagesPortrait = [UIImage(named: "introSlide1"), UIImage(named: "introSlide2"), UIImage(named: "introSlide3")] + private let imagesEightPortrait = [UIImage(named: "introSlideEight1"), UIImage(named: "introSlideEight2"), UIImage(named: "introSlideEight3")] // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() + let isEightPlusDevice = UIScreen.main.bounds.height == 736 + images = UIDevice.current.orientation.isLandscape ? imagesLandscape : (isEightPlusDevice ? imagesEightPortrait : imagesPortrait) + let isTooLight = NCBrandColor.shared.customer.isTooLight() let isTooDark = NCBrandColor.shared.customer.isTooDark() @@ -93,17 +101,35 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol } } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if UIDevice.current.userInterfaceIdiom != .pad{ + AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait) + } + navigationController?.setNavigationBarHidden(true, animated: animated) + } + + override func viewDidLayoutSubviews() { + if UIScreen.main.bounds.width < 350 || UIScreen.main.bounds.height > 800 { + contstraintBottomLoginButton.constant = 15 + } + } + override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) timer?.invalidate() timer = nil + AppUtility.lockOrientation(UIInterfaceOrientationMask.all) + navigationController?.setNavigationBarHidden(false, animated: animated) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: nil) { _ in + let isEightPlusDevice = UIScreen.main.bounds.height == 736 + self.images = UIDevice.current.orientation.isLandscape ? self.imagesLandscape : (isEightPlusDevice ? self.imagesEightPortrait : self.imagesPortrait) self.pageControl?.currentPage = 0 self.introCollectionView?.collectionViewLayout.invalidateLayout() } @@ -133,6 +159,7 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol cell.titleLabel.textColor = textColor cell.titleLabel.text = titles[indexPath.row] cell.imageView.image = images[indexPath.row] + cell.imageView.contentMode = .scaleAspectFill return cell } @@ -157,9 +184,17 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol } @IBAction func login(_ sender: Any) { - if let viewController = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin { - viewController.controller = self.controller - self.navigationController?.pushViewController(viewController, animated: true) + if NCBrandOptions.shared.use_AppConfig { + if let viewController = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin { + viewController.controller = self.controller + self.navigationController?.pushViewController(viewController, animated: true) + } + } else { + if NextcloudKit.shared.isNetworkReachable() { + appDelegate.openLogin(viewController: navigationController, selector: NCGlobal.shared.introLogin, openLoginWeb: false) + } else { + showNoInternetAlert() + } } } @@ -175,6 +210,12 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol guard let url = URL(string: NCBrandOptions.shared.linkLoginHost) else { return } UIApplication.shared.open(url) } + + func showNoInternetAlert() { + let alertController = UIAlertController(title: NSLocalizedString("_no_internet_alert_title_", comment: ""), message: NSLocalizedString("_no_internet_alert_message_", comment: ""), preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { action in })) + self.present(alertController, animated: true) + } } extension UINavigationController { diff --git a/Brand/LaunchScreen.storyboard b/Brand/LaunchScreen.storyboard index 26840f6195..59fe1c3dd1 100755 --- a/Brand/LaunchScreen.storyboard +++ b/Brand/LaunchScreen.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,16 +17,37 @@ - + + + + + + + + + + + + - + - - + - + + diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 8dd4c5545f..0fcc867beb 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -85,6 +85,11 @@ AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */; }; AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; }; + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; }; + B54315322DA64BAF00981E7E /* OnboardingTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54315312DA64BAF00981E7E /* OnboardingTestCase.swift */; }; + B54315342DA64D6500981E7E /* AppUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54315332DA64D6500981E7E /* AppUtility.swift */; }; + C04E2F232A17BB4D001BAD85 /* FilesIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04E2F222A17BB4D001BAD85 /* FilesIntegrationTests.swift */; }; + 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 */; }; F321DA8A2B71205A00DDA0E6 /* NCTrashSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */; }; @@ -1221,6 +1226,9 @@ AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extension.swift"; sourceTree = ""; }; AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCells.swift; sourceTree = ""; }; AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = ""; }; + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = ""; }; + B54315312DA64BAF00981E7E /* OnboardingTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTestCase.swift; sourceTree = ""; }; + B54315332DA64D6500981E7E /* AppUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUtility.swift; 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 = ""; }; @@ -2024,6 +2032,8 @@ isa = PBXGroup; children = ( AA52EB452D42AC5A0089C348 /* Placeholder.swift */, + B54315312DA64BAF00981E7E /* OnboardingTestCase.swift */, + AF8ED1FB2757821000B8DBC4 /* NextcloudUnitTests.swift */, ); path = NextcloudUnitTests; sourceTree = ""; @@ -3226,6 +3236,7 @@ isa = PBXGroup; children = ( AA517BB42D66149900F8D37C /* .tx */, + B54315332DA64D6500981E7E /* AppUtility.swift */, F702F2CC25EE5B4F008F8E80 /* AppDelegate.swift */, F794E13E2BBC0F70003693D7 /* SceneDelegate.swift */, F7CF067A2E0FF38F0063AD04 /* NCAppStateManager.swift */, @@ -4590,6 +4601,7 @@ F7FA80002C0F4F3B0072FC60 /* NCUploadAssetsModel.swift in Sources */, F719D9E2288D396100762E33 /* NCColorPicker.swift in Sources */, F73EF7DF2B02266D0087E6E9 /* NCManageDatabase+Trash.swift in Sources */, + B54315342DA64D6500981E7E /* AppUtility.swift in Sources */, F79B646026CA661600838ACA /* UIControl+Extension.swift in Sources */, F768823E2C0DD305001CF441 /* LazyView.swift in Sources */, F3E173B02C9AF637006D177A /* ScreenAwakeManager.swift in Sources */, diff --git a/Tests/NextcloudUnitTests/OnboardingTestCase.swift b/Tests/NextcloudUnitTests/OnboardingTestCase.swift new file mode 100644 index 0000000000..161b3a9258 --- /dev/null +++ b/Tests/NextcloudUnitTests/OnboardingTestCase.swift @@ -0,0 +1,158 @@ +// +// OnboardingTestCase.swift +// NextcloudTests +// +// Created by A200073704 on 21/04/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +@testable import Nextcloud +import XCTest +import NextcloudKit + + class OnboardingTestCase: XCTestCase { + + var viewController = NCIntroViewController() + + + var images:[UIImage?] = [] + let imagesLandscape = [UIImage(named: "introSlideLand1"), UIImage(named: "introSlideLand2"), UIImage(named: "introSlideLand3")] + let imagesPortrait = [UIImage(named: "introSlide1"), UIImage(named: "introSlide2"), UIImage(named: "introSlide3")] + let imagesEightPortrait = [UIImage(named: "introSlideEight1"), UIImage(named: "introSlideEight2"), UIImage(named: "introSlideEight3")] + + + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + + func testValidImage() { + + // onscreen images should not be nill + let image = [UIImage(named: "introSlideLand1"), UIImage(named: "introSlideLand2"), UIImage(named: "introSlideLand3")] + XCTAssertNotNil(image, "Image should not be nil") + + } + + func testImageDimensionsLandscape() { + + // testing height and width of the image + let introCollectionView = UIImage(named: "introSlideLand1") + XCTAssertEqual(introCollectionView?.size.width, 390, "Image width should be 390") + XCTAssertEqual(introCollectionView?.size.height, 844.3333333333334, "Image height should be 844.3333333333334") + } + + func testImageDimensionsPortrait() { + + // testing height and width of the image + let introCollectionView = UIImage(named: "introSlide1") + + XCTAssertEqual(introCollectionView?.size.width, 390, "Image width should be 390") + XCTAssertEqual(introCollectionView?.size.height, 844.3333333333334, "Image height should be 844.3333333333334") + } + + + func testImageDimentionsNotEqual() { + + // testing width and height if not equal + let introCollectionView = UIImage(named: "introSlide2") + + XCTAssertNotEqual(introCollectionView?.size.width, 100, "Image width should be 390") + XCTAssertNotEqual(introCollectionView?.size.height, 820, "Image height should be 844.3333333333334") + + } + + + func testImageContentMode() { + + // imageview content mode should be scaleAspectFill + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFill + imageView.image = UIImage(named: "introSlideLand2") + XCTAssertEqual(imageView.contentMode, .scaleAspectFill, "Image content mode should be scaleAspectFill") + + } + + + // Background color of view should be customer + func testBackgroundcolor() { + + let backgroundColor = NCBrandColor.shared.customer + XCTAssertNotNil(backgroundColor, "NCBrandColor.shared.customer should not be nil") + + } + + + // Button login text color shouyld be white + func testButtonLoginTextColor() { + + let textColor: UIColor = .white + viewController.buttonLogin?.backgroundColor = textColor + + XCTAssertEqual(textColor, textColor) + + } + + // images at loginscreen should not be empty + func testImagesNotEmpty() { + + let isEightPlusDevice = UIScreen.main.bounds.height == 736 + images = UIDevice.current.orientation.isLandscape ? imagesLandscape : (isEightPlusDevice ? imagesEightPortrait : imagesPortrait) + + XCTAssertFalse(images.isEmpty) + } + + + // Status bar and navigation bar color should not be blue color + func testStatueBarColorNotEqualToCustomer() { + + + let view = NCLoginWeb() + var color = view.navigationController?.navigationBar.backgroundColor + let navigationBarColor: UIColor = NCBrandColor.shared.customer + color = .systemBlue + + XCTAssertNotEqual(navigationBarColor, color) + + } + + //NavigationBar and status Bar color should be equal + func testNavigationBarColorEqualToCustomer() { + + let statusBarColor = NCBrandColor.shared.customer + let navigationBarColor: UIColor = NCBrandColor.shared.customer + + XCTAssertEqual(navigationBarColor, statusBarColor) + } + + func testEightPlusDeviceHeight() { + + let eightPlusDevice = UIScreen.main.bounds.height >= 736 + + XCTAssertTrue(eightPlusDevice) + + } + + func testLoginButtonTapped() { + + let viewController = NCIntroViewController() + + let loginButton = UIButton() + loginButton.addTarget(nil, action: #selector(viewController.login(_:)), for: .touchUpInside) + loginButton.sendActions(for: .touchUpInside) + + viewController.login(loginButton) + + XCTAssertNotNil(loginButton) + } + + + + +} diff --git a/iOSClient/AppDelegate.swift b/iOSClient/AppDelegate.swift index 7fcf867ea8..896d761308 100644 --- a/iOSClient/AppDelegate.swift +++ b/iOSClient/AppDelegate.swift @@ -17,6 +17,11 @@ import RealmSwift @UIApplicationMain 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") } @@ -32,6 +37,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD var bgTask: UIBackgroundTaskIdentifier = .invalid var pushSubscriptionTask: Task? + let database = NCManageDatabase.shared + + var window: UIWindow? + @objc var sceneIdentifier: String = "" + @objc var activeViewController: UIViewController? + @objc var account: String = "" + @objc var urlBase: String = "" + @objc var user: String = "" + @objc var userId: String = "" + @objc var password: String = "" + var timerErrorNetworking: Timer? + var tipView: EasyTipView? + + 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 { @@ -45,6 +74,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() @@ -119,6 +151,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 } @@ -200,7 +243,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD task.setTaskCompleted(success: true) } - await backgroundSync(task: task) + 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) } } @@ -281,12 +329,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD guard !expired else { return } let err = await NCNetworking.shared.createFolderForAutoUpload( - serverUrlFileName: metadata.serverUrlFileName, - account: metadata.account + 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 '\(metadata.serverUrlFileName)' failed: \(err.errorCode) – aborting sync") + nkLog(tag: self.global.logTagBgSync, emoji: .error, message: "Create folder '\(meta.serverUrlFileName)' failed: \(err.errorCode) – aborting sync") return } } @@ -437,7 +485,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } } - // MARK: - + // MARK: - Trust Certificate Error func trustCertificateError(host: String) { guard let activeTblAccount = NCManageDatabase.shared.getActiveTableAccount(), @@ -466,11 +514,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let viewController = navigationController.topViewController as? NCViewCertificateDetails { viewController.delegate = self viewController.host = host - UIApplication.shared.mainAppWindow?.rootViewController?.present(navigationController, animated: true) + UIApplication.shared.firstWindow?.rootViewController?.present(navigationController, animated: true) } })) - UIApplication.shared.mainAppWindow?.rootViewController?.present(alertController, animated: true) + UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true) } // MARK: - Reset Application @@ -489,6 +537,239 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD 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) { + guard let activeTableAccount = NCManageDatabase.shared.getActiveTableAccount(), + let currentHost = URL(string: activeTableAccount.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.mainAppWindow?.rootViewController?.present(navigationController, animated: true) + } + })) + + 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 + + @objc func resetApplication() { + let utilityFileSystem = NCUtilityFileSystem() + + NCNetworking.shared.cancelAllTask() + + URLCache.shared.removeAllCachedResponses() + + utilityFileSystem.removeGroupDirectoryProviderStorage() + utilityFileSystem.removeGroupApplicationSupport() + utilityFileSystem.removeDocumentsDirectory() + utilityFileSystem.removeTemporaryDirectory() + + NCKeychain().removeAll() + NCNetworking.shared.removeAllKeyUserDefaultsData(account: nil) + exit(0) } diff --git a/iOSClient/AppUtility.swift b/iOSClient/AppUtility.swift new file mode 100644 index 0000000000..6d940416ca --- /dev/null +++ b/iOSClient/AppUtility.swift @@ -0,0 +1,23 @@ +// +// AppUtility.swift +// Nextcloud +// +// Created by Amrut Waghmare on 17/10/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +import Foundation +import UIKit + +struct AppUtility { + static func lockOrientation(_ orientation: UIInterfaceOrientationMask) { + if let delegate = UIApplication.shared.delegate as? AppDelegate { + delegate.orientationLock = orientation + } + } + + static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) { + self.lockOrientation(orientation) + UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation") + } +}