Skip to content

Commit

Permalink
Merge pull request #1307 from Infomaniak/externalLinks-listFiles
Browse files Browse the repository at this point in the history
feat: External links list files
  • Loading branch information
adrien-coye authored Oct 23, 2024
2 parents 6269b10 + fbf4989 commit 95e4825
Show file tree
Hide file tree
Showing 19 changed files with 337 additions and 131 deletions.
34 changes: 27 additions & 7 deletions kDrive/AppRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ public struct AppRouter: AppNavigable {
// MARK: RouterFileNavigable

@MainActor public func presentPublicShare(
rootFolder: File,
frozenRootFolder: File,
publicShareProxy: PublicShareProxy,
driveFileManager: DriveFileManager,
apiFetcher: PublicShareApiFetcher
Expand All @@ -597,12 +597,32 @@ public struct AppRouter: AppNavigable {
fatalError("TODO: lazy load a rootViewController")
}

let filePresenter = FilePresenter(viewController: rootViewController)
filePresenter.presentPublicShareDirectory(publicShareProxy: publicShareProxy,
rootFolder: rootFolder,
rootViewController: rootViewController,
driveFileManager: driveFileManager,
apiFetcher: apiFetcher)
guard let rootViewController = window.rootViewController as? MainTabViewController else {
fatalError("Root is not a MainTabViewController")
return
}

// TODO: Fix access right
guard !frozenRootFolder.isDisabled else {
fatalError("isDisabled")
return
}

rootViewController.dismiss(animated: false) {
rootViewController.selectedIndex = MainTabBarIndex.files.rawValue

guard let navigationController = rootViewController.selectedViewController as? UINavigationController else {
return
}

let viewModel = PublicShareViewModel(publicShareProxy: publicShareProxy,
sortType: .nameAZ,
driveFileManager: driveFileManager,
currentDirectory: frozenRootFolder,
apiFetcher: apiFetcher)
let viewController = FileListViewController(viewModel: viewModel)
navigationController.pushViewController(viewController, animated: true)
}
}

@MainActor public func present(file: File, driveFileManager: DriveFileManager) {
Expand Down
31 changes: 6 additions & 25 deletions kDrive/UI/Controller/Files/FilePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,31 +132,6 @@ final class FilePresenter {
}
}

public func presentPublicShareDirectory(
publicShareProxy: PublicShareProxy,
rootFolder: File,
rootViewController: UIViewController,
driveFileManager: DriveFileManager,
apiFetcher: PublicShareApiFetcher
) {
let viewModel = PublicShareViewModel(publicShareProxy: publicShareProxy,
sortType: .nameAZ,
driveFileManager: driveFileManager,
currentDirectory: rootFolder,
apiFetcher: apiFetcher)

// TODO: Fix access right
// guard !rootFolder.isDisabled else {
// return
// }

let nextVC = FileListViewController(viewModel: viewModel)
print("nextVC:\(nextVC) viewModel:\(viewModel) navigationController:\(navigationController)")
// navigationController?.pushViewController(nextVC, animated: true)

rootViewController.present(nextVC, animated: true)
}

public func presentDirectory(
for file: File,
driveFileManager: DriveFileManager,
Expand All @@ -170,6 +145,12 @@ final class FilePresenter {
let viewModel: FileListViewModel
if driveFileManager.drive.sharedWithMe {
viewModel = SharedWithMeViewModel(driveFileManager: driveFileManager, currentDirectory: file)
} else if let publicShareProxy = driveFileManager.publicShareProxy {
viewModel = PublicShareViewModel(publicShareProxy: publicShareProxy,
sortType: .nameAZ,
driveFileManager: driveFileManager,
currentDirectory: file,
apiFetcher: PublicShareApiFetcher())
} else if file.isTrashed || file.deletedAt != nil {
viewModel = TrashListViewModel(driveFileManager: driveFileManager, currentDirectory: file)
} else {
Expand Down
10 changes: 7 additions & 3 deletions kDrive/UI/Controller/Files/Preview/PreviewViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@ final class PreviewViewController: UIViewController, PreviewContentCellDelegate,
previewPageViewController.driveFileManager = driveFileManager
previewPageViewController.normalFolderHierarchy = normalFolderHierarchy
previewPageViewController.presentationOrigin = presentationOrigin
// currentIndex should be set at the end of the function as the it takes time and the viewDidLoad() is called before the
// function returns
// currentIndex should be set at the end of the function as the it takes time
// and the viewDidLoad() is called before the function returns
// this should be fixed in the future with the refactor of the init
previewPageViewController.currentIndex = IndexPath(row: index, section: 0)
return previewPageViewController
Expand Down Expand Up @@ -650,7 +650,11 @@ extension PreviewViewController: UICollectionViewDataSource {
) {
let file = previewFiles[indexPath.row]
if let cell = cell as? DownloadingPreviewCollectionViewCell {
cell.progressiveLoadingForFile(file)
if let publicShareProxy = driveFileManager.publicShareProxy {
cell.progressiveLoadingForPublicShareFile(file, publicShareProxy: publicShareProxy)
} else {
cell.progressiveLoadingForFile(file)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Infomaniak kDrive - iOS App
Copyright (C) 2021 Infomaniak Network SA
Copyright (C) 2024 Infomaniak Network SA

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
Expand Down Expand Up @@ -28,19 +28,18 @@ final class PublicShareViewModel: InMemoryFileListViewModel {

required init(driveFileManager: DriveFileManager, currentDirectory: File? = nil) {
guard let currentDirectory else {
fatalError("woops")
fatalError("PublicShareViewModel requires a currentDirectory to work")
}

Check warning on line 33 in kDrive/UI/Controller/Menu/Share/PublicShareViewModel.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Remove trailing space at end of a line. (trailingSpace)

Check failure on line 33 in kDrive/UI/Controller/Menu/Share/PublicShareViewModel.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
let configuration = Configuration(selectAllSupported: false,
rootTitle: "public share",
rootTitle: KDriveCoreStrings.Localizable.sharedWithMeTitle,
emptyViewType: .emptyFolder,
supportsDrop: false,
matomoViewPath: [MatomoUtils.Views.menu.displayName, "publicShare"])

rootProxy = currentDirectory.proxify()
super.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: currentDirectory)
observedFiles = AnyRealmCollection(currentDirectory.children)
print("• observedFiles :\(observedFiles.count)")
}

convenience init(
Expand All @@ -57,7 +56,6 @@ final class PublicShareViewModel: InMemoryFileListViewModel {
}

override func loadFiles(cursor: String? = nil, forceRefresh: Bool = false) async throws {
print("• loadFiles:\(cursor):\(forceRefresh)")
guard !isLoading || cursor != nil,
let publicShareProxy,
let publicShareApiFetcher else {
Expand All @@ -75,39 +73,6 @@ final class PublicShareViewModel: InMemoryFileListViewModel {
let (_, nextCursor) = try await driveFileManager.publicShareFiles(rootProxy: rootProxy,
publicShareProxy: publicShareProxy,
publicShareApiFetcher: publicShareApiFetcher)
print("• nextCursor:\(nextCursor)")
endRefreshing()
if let nextCursor {
try await loadFiles(cursor: nextCursor)
}
}
}

class SharedWithMeViewModel: FileListViewModel {
required init(driveFileManager: DriveFileManager, currentDirectory: File? = nil) {
let sharedWithMeRootFile = driveFileManager.getManagedFile(from: DriveFileManager.sharedWithMeRootFile)
let configuration = Configuration(selectAllSupported: false,
rootTitle: KDriveCoreStrings.Localizable.sharedWithMeTitle,
emptyViewType: .noSharedWithMe,
supportsDrop: false,
matomoViewPath: [MatomoUtils.Views.menu.displayName, "SharedWithMe"])

super.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: sharedWithMeRootFile)
observedFiles = AnyRealmCollection(AnyRealmCollection(sharedWithMeRootFile.children).filesSorted(by: sortType))
}

override func loadFiles(cursor: String? = nil, forceRefresh: Bool = false) async throws {
guard !isLoading || cursor != nil else { return }

// Only show loading indicator if we have nothing in cache
if !currentDirectory.canLoadChildrenFromCache {
startRefreshing(cursor: cursor)
}
defer {
endRefreshing()
}

let (_, nextCursor) = try await driveFileManager.sharedWithMeFiles(cursor: cursor, sortType: sortType, forceRefresh: true)
endRefreshing()
if let nextCursor {
try await loadFiles(cursor: nextCursor)
Expand Down
53 changes: 53 additions & 0 deletions kDrive/UI/Controller/Menu/Share/SharedWithMeViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Infomaniak kDrive - iOS App
Copyright (C) 2021 Infomaniak Network SA

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import kDriveCore
import RealmSwift
import UIKit

class SharedWithMeViewModel: FileListViewModel {
required init(driveFileManager: DriveFileManager, currentDirectory: File? = nil) {
let sharedWithMeRootFile = driveFileManager.getManagedFile(from: DriveFileManager.sharedWithMeRootFile)
let configuration = Configuration(selectAllSupported: false,
rootTitle: KDriveCoreStrings.Localizable.sharedWithMeTitle,
emptyViewType: .noSharedWithMe,
supportsDrop: false,
matomoViewPath: [MatomoUtils.Views.menu.displayName, "SharedWithMe"])

super.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: sharedWithMeRootFile)
observedFiles = AnyRealmCollection(AnyRealmCollection(sharedWithMeRootFile.children).filesSorted(by: sortType))
}

override func loadFiles(cursor: String? = nil, forceRefresh: Bool = false) async throws {
guard !isLoading || cursor != nil else { return }

// Only show loading indicator if we have nothing in cache
if !currentDirectory.canLoadChildrenFromCache {
startRefreshing(cursor: cursor)
}
defer {
endRefreshing()
}

let (_, nextCursor) = try await driveFileManager.sharedWithMeFiles(cursor: cursor, sortType: sortType, forceRefresh: true)
endRefreshing()
if let nextCursor {
try await loadFiles(cursor: nextCursor)
}
}
}
66 changes: 49 additions & 17 deletions kDrive/UI/View/Files/FileCollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ protocol FileCellDelegate: AnyObject {
var file: File
var selectionMode: Bool
var isSelected = false

/// Public share data if file exists within a public share
let publicShareProxy: PublicShareProxy?

private var downloadProgressObserver: ObservationToken?
private var downloadObserver: ObservationToken?
var thumbnailDownloadTask: Kingfisher.DownloadTask?
Expand Down Expand Up @@ -114,6 +118,7 @@ protocol FileCellDelegate: AnyObject {
init(driveFileManager: DriveFileManager, file: File, selectionMode: Bool) {
self.file = file
self.selectionMode = selectionMode
publicShareProxy = driveFileManager.publicShareProxy
categories = driveFileManager.drive.categories(for: file)
}

Expand All @@ -138,30 +143,50 @@ protocol FileCellDelegate: AnyObject {
}

func setThumbnail(on imageView: UIImageView) {
// check if public share / use specific endpoint
guard !file.isInvalidated,
(file.convertedType == .image || file.convertedType == .video) && file.supportedBy.contains(.thumbnail)
else { return }
(file.convertedType == .image || file.convertedType == .video) && file.supportedBy.contains(.thumbnail) else {
return
}

// Configure placeholder
imageView.image = nil
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = UIConstants.imageCornerRadius
imageView.layer.masksToBounds = true
imageView.backgroundColor = KDriveResourcesAsset.loaderDefaultColor.color
// Fetch thumbnail
thumbnailDownloadTask = file.getThumbnail { [requestFileId = file.id, weak self] image, _ in
guard let self,
!self.file.isInvalidated,
!self.isSelected else {
return

if let publicShareProxy {
// Fetch public share thumbnail
thumbnailDownloadTask = file.getPublicShareThumbnail(publicShareId: publicShareProxy.shareLinkUid,
publicDriveId: publicShareProxy.driveId,
publicFileId: file.id) { [
requestFileId = file.id,
weak self
] image, _ in
self?.setImage(image, on: imageView, requestFileId: requestFileId)
}

if file.id == requestFileId {
imageView.image = image
imageView.backgroundColor = nil
} else {
// Fetch thumbnail
thumbnailDownloadTask = file.getThumbnail { [requestFileId = file.id, weak self] image, _ in
self?.setImage(image, on: imageView, requestFileId: requestFileId)
}
}
}

private func setImage(_ image: UIImage, on imageView: UIImageView, requestFileId: Int) {
guard !file.isInvalidated,
!isSelected else {
return
}

if file.id == requestFileId {
imageView.image = image
imageView.backgroundColor = nil
}
}

deinit {
downloadProgressObserver?.cancel()
downloadObserver?.cancel()
Expand Down Expand Up @@ -302,7 +327,7 @@ class FileCollectionViewCell: UICollectionViewCell, SwipableCell {

func configure(with viewModel: FileViewModel) {
self.viewModel = viewModel
configureLogoImage()
configureLogoImage(viewModel: viewModel)
titleLabel.text = viewModel.title
detailLabel?.text = viewModel.subtitle
favoriteImageView?.isHidden = !viewModel.isFavorite
Expand All @@ -321,7 +346,12 @@ class FileCollectionViewCell: UICollectionViewCell, SwipableCell {
}

func configureWith(driveFileManager: DriveFileManager, file: File, selectionMode: Bool = false) {
configure(with: FileViewModel(driveFileManager: driveFileManager, file: file, selectionMode: selectionMode))
let fileViewModel = FileViewModel(
driveFileManager: driveFileManager,
file: file,
selectionMode: selectionMode
)
configure(with: fileViewModel)
}

/// Update the cell selection mode.
Expand All @@ -333,18 +363,20 @@ class FileCollectionViewCell: UICollectionViewCell, SwipableCell {
}

func configureForSelection() {
guard viewModel?.selectionMode == true else { return }
guard let viewModel,
viewModel.selectionMode == true else {
return
}

if isSelected {
configureCheckmarkImage()
configureImport(shouldDisplay: false)
} else {
configureLogoImage()
configureLogoImage(viewModel: viewModel)
}
}

private func configureLogoImage() {
guard let viewModel else { return }
private func configureLogoImage(viewModel: FileViewModel) {
logoImage.isAccessibilityElement = true
logoImage.accessibilityLabel = viewModel.iconAccessibilityLabel
logoImage.image = viewModel.icon
Expand Down
7 changes: 6 additions & 1 deletion kDrive/UI/View/Files/FileGridCollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ class FileGridCollectionViewCell: FileCollectionViewCell {
}

override func configureWith(driveFileManager: DriveFileManager, file: File, selectionMode: Bool = false) {
configure(with: FileGridViewModel(driveFileManager: driveFileManager, file: file, selectionMode: selectionMode))
let viewModel = FileGridViewModel(
driveFileManager: driveFileManager,
file: file,
selectionMode: selectionMode
)
configure(with: viewModel)
}

override func configureLoading() {
Expand Down
Loading

0 comments on commit 95e4825

Please sign in to comment.