diff --git a/kDrive/AppDelegate.swift b/kDrive/AppDelegate.swift index cb3c0a5ca..66cfcb463 100644 --- a/kDrive/AppDelegate.swift +++ b/kDrive/AppDelegate.swift @@ -384,14 +384,17 @@ final class AppDelegate: UIResponder, UIApplicationDelegate, AccountManagerDeleg func setRootViewController(_ vc: UIViewController, animated: Bool = true) { - guard animated, let window else { - self.window?.rootViewController = vc - self.window?.makeKeyAndVisible() + guard let window else { return } window.rootViewController = vc window.makeKeyAndVisible() + + guard animated else { + return + } + UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: nil, @@ -424,9 +427,9 @@ final class AppDelegate: UIResponder, UIApplicationDelegate, AccountManagerDeleg viewController: fileListViewController) } else { let filePresenter = FilePresenter(viewController: fileListViewController) - filePresenter.present(driveFileManager: driveFileManager, - file: file, + filePresenter.present(for: file, files: [file], + driveFileManager: driveFileManager, normalFolderHierarchy: false) } } diff --git a/kDrive/UI/Controller/Files/File List/FileListViewController.swift b/kDrive/UI/Controller/Files/File List/FileListViewController.swift index aeaf3bceb..d2c7679fb 100644 --- a/kDrive/UI/Controller/Files/File List/FileListViewController.swift +++ b/kDrive/UI/Controller/Files/File List/FileListViewController.swift @@ -582,9 +582,9 @@ class FileListViewController: UIViewController, UICollectionViewDataSource, Swip func onFilePresented(_ file: File) { #if !ISEXTENSION - filePresenter.present(driveFileManager: viewModel.driveFileManager, - file: file, + filePresenter.present(for: file, files: viewModel.getAllFiles(), + driveFileManager: viewModel.driveFileManager, normalFolderHierarchy: viewModel.configuration.normalFolderHierarchy, fromActivities: viewModel.configuration.fromActivities) #endif diff --git a/kDrive/UI/Controller/Files/File List/InMemoryFileListViewModel.swift b/kDrive/UI/Controller/Files/File List/InMemoryFileListViewModel.swift index 27877bdc2..e82163d25 100644 --- a/kDrive/UI/Controller/Files/File List/InMemoryFileListViewModel.swift +++ b/kDrive/UI/Controller/Files/File List/InMemoryFileListViewModel.swift @@ -25,7 +25,14 @@ class InMemoryFileListViewModel: FileListViewModel { private let realm: Realm override init(configuration: Configuration, driveFileManager: DriveFileManager, currentDirectory: File) { - if let realm = currentDirectory.realm { + // TODO: Refactor to explicit realm state + /// We expect the object to be live in this view controller, if not detached. + var currentDirectory = currentDirectory + if currentDirectory.isFrozen, let liveDirectory = currentDirectory.thaw() { + currentDirectory = liveDirectory + } + + if let realm = currentDirectory.realm, !currentDirectory.isFrozen { self.realm = realm } else { let unCachedRealmConfiguration = Realm.Configuration( @@ -40,6 +47,7 @@ class InMemoryFileListViewModel: FileListViewModel { } super.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: currentDirectory) + try? realm.write { realm.add(currentDirectory) } diff --git a/kDrive/UI/Controller/Files/FilePresenter.swift b/kDrive/UI/Controller/Files/FilePresenter.swift index 5b647da48..bd7a46aa1 100644 --- a/kDrive/UI/Controller/Files/FilePresenter.swift +++ b/kDrive/UI/Controller/Files/FilePresenter.swift @@ -63,18 +63,16 @@ final class FilePresenter { func presentParent(of file: File, driveFileManager: DriveFileManager, animated: Bool = true) { if let parent = file.parent { - present(driveFileManager: driveFileManager, file: parent, files: [], normalFolderHierarchy: true, animated: animated) + present(for: parent, files: [], driveFileManager: driveFileManager, normalFolderHierarchy: true, animated: animated) } else if file.parentId != 0 { Task { do { let parent = try await driveFileManager.file(id: file.parentId) - present( - driveFileManager: driveFileManager, - file: parent, - files: [], - normalFolderHierarchy: true, - animated: animated - ) + present(for: parent, + files: [], + driveFileManager: driveFileManager, + normalFolderHierarchy: true, + animated: animated) } catch { UIConstants.showSnackBarIfNeeded(error: error) } @@ -84,93 +82,124 @@ final class FilePresenter { } } - func present(driveFileManager: DriveFileManager, - file: File, + func present(for file: File, files: [File], + driveFileManager: DriveFileManager, normalFolderHierarchy: Bool, fromActivities: Bool = false, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { if file.isDirectory { - // Show files list - let viewModel: FileListViewModel - if driveFileManager.drive.sharedWithMe { - viewModel = SharedWithMeViewModel(driveFileManager: driveFileManager, currentDirectory: file) - } else if file.isTrashed || file.deletedAt != nil { - viewModel = TrashListViewModel(driveFileManager: driveFileManager, currentDirectory: file) - } else { - viewModel = ConcreteFileListViewModel(driveFileManager: driveFileManager, currentDirectory: file) - } - let nextVC = FileListViewController.instantiate(viewModel: viewModel) - if file.isDisabled { - if driveFileManager.drive.isUserAdmin { - let accessFileDriveFloatingPanelController = AccessFileFloatingPanelViewController.instantiatePanel() - let floatingPanelViewController = accessFileDriveFloatingPanelController - .contentViewController as? AccessFileFloatingPanelViewController - floatingPanelViewController?.actionHandler = { [weak self] _ in - guard let self else { return } - floatingPanelViewController?.rightButton.setLoading(true) - Task { [proxyFile = file.proxify()] in - do { - let response = try await driveFileManager.apiFetcher.forceAccess(to: proxyFile) - if response { - accessFileDriveFloatingPanelController.dismiss(animated: true) - self.navigationController?.pushViewController(nextVC, animated: true) - } else { - UIConstants.showSnackBar(message: KDriveResourcesStrings.Localizable.errorRightModification) - } - } catch { - UIConstants.showSnackBarIfNeeded(error: error) + presentDirectory(for: file, driveFileManager: driveFileManager, animated: animated, completion: completion) + } else if file.isBookmark { + downloadAndPresentBookmark(for: file, completion: completion) + } else { + presentFile( + for: file, + files: files, + driveFileManager: driveFileManager, + normalFolderHierarchy: normalFolderHierarchy, + fromActivities: fromActivities, + animated: animated, + completion: completion + ) + } + } + + private func presentFile(for file: File, + files: [File], + driveFileManager: DriveFileManager, + normalFolderHierarchy: Bool, + fromActivities: Bool, + animated: Bool, + completion: ((Bool) -> Void)?) { + // Show file preview + let files = files.filter { !$0.isDirectory && !$0.isTrashed } + if let index = files.firstIndex(where: { $0.id == file.id }) { + let previewViewController = PreviewViewController.instantiate( + files: files, + index: Int(index), + driveFileManager: driveFileManager, + normalFolderHierarchy: normalFolderHierarchy, + fromActivities: fromActivities + ) + navigationController?.pushViewController(previewViewController, animated: animated) + completion?(true) + } + if file.isTrashed { + UIConstants.showSnackBar(message: KDriveResourcesStrings.Localizable.errorPreviewTrash) + completion?(false) + } + } + + private func presentDirectory( + for file: File, + driveFileManager: DriveFileManager, + animated: Bool, + completion: ((Bool) -> Void)? + ) { + // Show files list + let viewModel: FileListViewModel + if driveFileManager.drive.sharedWithMe { + viewModel = SharedWithMeViewModel(driveFileManager: driveFileManager, currentDirectory: file) + } else if file.isTrashed || file.deletedAt != nil { + viewModel = TrashListViewModel(driveFileManager: driveFileManager, currentDirectory: file) + } else { + viewModel = ConcreteFileListViewModel(driveFileManager: driveFileManager, currentDirectory: file) + } + let nextVC = FileListViewController.instantiate(viewModel: viewModel) + if file.isDisabled { + if driveFileManager.drive.isUserAdmin { + let accessFileDriveFloatingPanelController = AccessFileFloatingPanelViewController.instantiatePanel() + let floatingPanelViewController = accessFileDriveFloatingPanelController + .contentViewController as? AccessFileFloatingPanelViewController + floatingPanelViewController?.actionHandler = { [weak self] _ in + guard let self else { return } + floatingPanelViewController?.rightButton.setLoading(true) + Task { [proxyFile = file.proxify()] in + do { + let response = try await driveFileManager.apiFetcher.forceAccess(to: proxyFile) + if response { + accessFileDriveFloatingPanelController.dismiss(animated: true) + self.navigationController?.pushViewController(nextVC, animated: true) + } else { + UIConstants.showSnackBar(message: KDriveResourcesStrings.Localizable.errorRightModification) } + } catch { + UIConstants.showSnackBarIfNeeded(error: error) } } - viewController?.present(accessFileDriveFloatingPanelController, animated: true) - } else { - viewController?.present(NoAccessFloatingPanelViewController.instantiatePanel(), animated: true) } + viewController?.present(accessFileDriveFloatingPanelController, animated: true) } else { - navigationController?.pushViewController(nextVC, animated: animated) + viewController?.present(NoAccessFloatingPanelViewController.instantiatePanel(), animated: true) } - completion?(true) - } else if file.isBookmark { - // Open bookmark URL - if file.isMostRecentDownloaded { - presentBookmark(for: file, completion: completion) - } else { - // Download file - DownloadQueue.instance.temporaryDownload(file: file, userId: accountManager.currentUserId) { error in - Task { - if let error { - UIConstants.showSnackBarIfNeeded(error: error) - completion?(false) - } else { - self.presentBookmark(for: file, completion: completion) - } + } else { + navigationController?.pushViewController(nextVC, animated: animated) + } + completion?(true) + } + + private func downloadAndPresentBookmark(for file: File, completion: ((Bool) -> Void)?) { + // Open bookmark URL + if file.isMostRecentDownloaded { + presentBookmark(for: file, completion: completion) + } else { + // Download file + DownloadQueue.instance.temporaryDownload(file: file, userId: accountManager.currentUserId) { error in + Task { + if let error { + UIConstants.showSnackBarIfNeeded(error: error) + completion?(false) + } else { + self.presentBookmark(for: file, completion: completion) } } } - } else { - // Show file preview - let files = files.filter { !$0.isDirectory && !$0.isTrashed } - if let index = files.firstIndex(where: { $0.id == file.id }) { - let previewViewController = PreviewViewController.instantiate( - files: files, - index: Int(index), - driveFileManager: driveFileManager, - normalFolderHierarchy: normalFolderHierarchy, - fromActivities: fromActivities - ) - navigationController?.pushViewController(previewViewController, animated: animated) - completion?(true) - } - if file.isTrashed { - UIConstants.showSnackBar(message: KDriveResourcesStrings.Localizable.errorPreviewTrash) - completion?(false) - } } } - private func presentBookmark(for file: File, animated: Bool = true, completion: ((Bool) -> Void)? = nil) { + private func presentBookmark(for file: File, animated: Bool = true, completion: ((Bool) -> Void)?) { if let url = file.getBookmarkURL() { if url.scheme == "http" || url.scheme == "https" { let safariViewController = SFSafariViewController(url: url) diff --git a/kDrive/UI/Controller/Files/Preview/PreviewViewController.swift b/kDrive/UI/Controller/Files/Preview/PreviewViewController.swift index 90e52243d..500b0c28b 100644 --- a/kDrive/UI/Controller/Files/Preview/PreviewViewController.swift +++ b/kDrive/UI/Controller/Files/Preview/PreviewViewController.swift @@ -402,9 +402,9 @@ class PreviewViewController: UIViewController, PreviewContentCellDelegate { if currentFile.isBookmark { floatingPanelViewController.dismiss(animated: false) FilePresenter(viewController: self).present( - driveFileManager: driveFileManager, - file: currentFile, + for: currentFile, files: [], + driveFileManager: driveFileManager, normalFolderHierarchy: true ) { success in if !success { diff --git a/kDrive/UI/Controller/Files/RecentActivityFilesViewController.swift b/kDrive/UI/Controller/Files/RecentActivityFilesViewController.swift index ec7ad9407..f0b7c648e 100644 --- a/kDrive/UI/Controller/Files/RecentActivityFilesViewController.swift +++ b/kDrive/UI/Controller/Files/RecentActivityFilesViewController.swift @@ -113,9 +113,9 @@ class RecentActivityFilesViewController: FileListViewController { #if !ISEXTENSION if file.isDirectory { let managedFile = driveFileManager.getManagedFile(from: file.detached()) - filePresenter.present(driveFileManager: viewModel.driveFileManager, - file: managedFile, + filePresenter.present(for: managedFile, files: viewModel.getAllFiles(), + driveFileManager: viewModel.driveFileManager, normalFolderHierarchy: viewModel.configuration.normalFolderHierarchy, fromActivities: viewModel.configuration.fromActivities) } else { diff --git a/kDrive/UI/Controller/Home/HomeViewController.swift b/kDrive/UI/Controller/Home/HomeViewController.swift index eec71e634..edab7ecef 100644 --- a/kDrive/UI/Controller/Home/HomeViewController.swift +++ b/kDrive/UI/Controller/Home/HomeViewController.swift @@ -712,9 +712,9 @@ extension HomeViewController { switch viewModel.recentFiles { case .file(let files): filePresenter.present( - driveFileManager: driveFileManager, - file: files[indexPath.row], + for: files[indexPath.row], files: files, + driveFileManager: driveFileManager, normalFolderHierarchy: false ) case .fileActivity: @@ -788,9 +788,9 @@ extension HomeViewController: RecentActivityDelegate { filePresenter.navigationController?.pushViewController(nextVC, animated: true) } else { filePresenter.present( - driveFileManager: driveFileManager, - file: driveFileManager.getManagedFile(from: file), + for: driveFileManager.getManagedFile(from: file), files: activities.compactMap(\.file), + driveFileManager: driveFileManager, normalFolderHierarchy: false ) }