Skip to content

Commit

Permalink
feat: Multiselect behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-coye committed Sep 27, 2024
1 parent 630111f commit 5368da7
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 37 deletions.
17 changes: 16 additions & 1 deletion kDrive/AppRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,27 @@ public struct AppRouter: AppNavigable {
return
}

// TODO: i18n
let configuration = FileListViewModel.Configuration(selectAllSupported: true,
rootTitle: "public share",
emptyViewType: .emptyFolder,
supportsDrop: false,
leftBarButtons: [.cancel],
rightBarButtons: [.downloadAll],
matomoViewPath: [
MatomoUtils.Views.menu.displayName,
"publicShare"
])

let viewModel = PublicShareViewModel(publicShareProxy: publicShareProxy,
sortType: .nameAZ,
driveFileManager: driveFileManager,
currentDirectory: frozenRootFolder,
apiFetcher: apiFetcher)
apiFetcher: apiFetcher,
configuration: configuration)
let viewController = FileListViewController(viewModel: viewModel)
viewModel.viewControllerDismissable = viewController

let publicShareNavigationController = UINavigationController(rootViewController: viewController)
publicShareNavigationController.modalPresentationStyle = .fullScreen
publicShareNavigationController.modalTransitionStyle = .coverVertical
Expand Down
39 changes: 22 additions & 17 deletions kDrive/UI/Controller/Files/File List/FileListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ extension SortType: Selectable {
}

class FileListViewController: UICollectionViewController, SwipeActionCollectionViewDelegate,
SwipeActionCollectionViewDataSource, FilesHeaderViewDelegate, SceneStateRestorable {
SwipeActionCollectionViewDataSource, FilesHeaderViewDelegate, SceneStateRestorable, ViewControllerDismissable {
@LazyInjectService var accountManager: AccountManageable

// MARK: - Constants
Expand All @@ -60,6 +60,7 @@ class FileListViewController: UICollectionViewController, SwipeActionCollectionV
private let leftRightInset = 12.0
private let gridInnerSpacing = 16.0
private let headerViewIdentifier = "FilesHeaderView"
private var addToKDriveButton: IKButton?

// MARK: - Properties

Expand Down Expand Up @@ -257,33 +258,35 @@ class FileListViewController: UICollectionViewController, SwipeActionCollectionV
return
}

let addToKDriveButton = IKButton(type: .custom)
addToKDriveButton.setTitle("Add to My kDrive", for: .normal)
addToKDriveButton.addTarget(self, action: #selector(addToMyDriveButtonTapped(_:)), for: .touchUpInside)
addToKDriveButton.setBackgroundColors(normal: .systemBlue, highlighted: .darkGray)
addToKDriveButton.translatesAutoresizingMaskIntoConstraints = false
addToKDriveButton.cornerRadius = 8.0
addToKDriveButton.clipsToBounds = true
let addToKDrive = IKButton(type: .custom)
addToKDriveButton = addToKDrive

view.addSubview(addToKDriveButton)
view.bringSubviewToFront(addToKDriveButton)
addToKDrive.setTitle("Add to My kDrive", for: .normal)
addToKDrive.addTarget(self, action: #selector(addToMyDriveButtonTapped(_:)), for: .touchUpInside)
addToKDrive.setBackgroundColors(normal: .systemBlue, highlighted: .darkGray)
addToKDrive.translatesAutoresizingMaskIntoConstraints = false
addToKDrive.cornerRadius = 8.0
addToKDrive.clipsToBounds = true

let leadingConstraint = addToKDriveButton.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor,
constant: 16)
view.addSubview(addToKDrive)
view.bringSubviewToFront(addToKDrive)

let leadingConstraint = addToKDrive.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor,
constant: 16)
leadingConstraint.priority = .defaultHigh
let trailingConstraint = addToKDriveButton.trailingAnchor.constraint(
let trailingConstraint = addToKDrive.trailingAnchor.constraint(
greaterThanOrEqualTo: view.trailingAnchor,
constant: -16
)
trailingConstraint.priority = .defaultHigh
let widthConstraint = addToKDriveButton.widthAnchor.constraint(lessThanOrEqualToConstant: 360)
let widthConstraint = addToKDrive.widthAnchor.constraint(lessThanOrEqualToConstant: 360)

NSLayoutConstraint.activate([
addToKDriveButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
addToKDrive.centerXAnchor.constraint(equalTo: view.centerXAnchor),
leadingConstraint,
trailingConstraint,
addToKDriveButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16),
addToKDriveButton.heightAnchor.constraint(equalToConstant: 60),
addToKDrive.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16),
addToKDrive.heightAnchor.constraint(equalToConstant: 60),
widthConstraint
])
}
Expand Down Expand Up @@ -614,6 +617,7 @@ class FileListViewController: UICollectionViewController, SwipeActionCollectionV

func toggleMultipleSelection(_ on: Bool) {
if on {
addToKDriveButton?.isHidden = true
navigationItem.title = nil
headerView?.selectView.isHidden = false
headerView?.selectView.setActions(viewModel.multipleSelectionViewModel?.multipleSelectionActions ?? [])
Expand All @@ -623,6 +627,7 @@ class FileListViewController: UICollectionViewController, SwipeActionCollectionV
generator.prepare()
generator.impactOccurred()
} else {
addToKDriveButton?.isHidden = false
headerView?.selectView.isHidden = true
collectionView.allowsMultipleSelection = false
navigationController?.navigationBar.prefersLargeTitles = true
Expand Down
3 changes: 3 additions & 0 deletions kDrive/UI/Controller/Files/File List/FileListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class FileListViewModel: SelectDelegate {
var matomoViewPath = ["FileList"]
}

/// Tracking a way to dismiss the current stack
weak var viewControllerDismissable: ViewControllerDismissable?

var realmObservationToken: NotificationToken?
var currentDirectoryObservationToken: NotificationToken?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class MultipleSelectionFileListViewModel {
leftBarButtons = [.cancel]
if configuration.selectAllSupported {
rightBarButtons = [.selectAll]
} else {
rightBarButtons = []
}
} else {
leftBarButtons = nil
Expand Down
14 changes: 13 additions & 1 deletion kDrive/UI/Controller/Files/FilePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,23 @@ final class FilePresenter {
if driveFileManager.drive.sharedWithMe {
viewModel = SharedWithMeViewModel(driveFileManager: driveFileManager, currentDirectory: file)
} else if let publicShareProxy = driveFileManager.publicShareProxy {
// TODO: i18n
let configuration = FileListViewModel.Configuration(selectAllSupported: true,
rootTitle: "public share",
emptyViewType: .emptyFolder,
supportsDrop: false,
rightBarButtons: [.downloadAll],
matomoViewPath: [
MatomoUtils.Views.menu.displayName,
"publicShare"
])

viewModel = PublicShareViewModel(publicShareProxy: publicShareProxy,
sortType: .nameAZ,
driveFileManager: driveFileManager,
currentDirectory: file,
apiFetcher: PublicShareApiFetcher())
apiFetcher: PublicShareApiFetcher(),
configuration: configuration)
} else if file.isTrashed || file.deletedAt != nil {
viewModel = TrashListViewModel(driveFileManager: driveFileManager, currentDirectory: file)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ protocol SelectDelegate: AnyObject {
func didSelect(option: Selectable)
}

/// Something that can dismiss the current VC if presented
@MainActor
public protocol ViewControllerDismissable: AnyObject {
func dismiss(animated flag: Bool, completion: (() -> Void)?)
}

class FloatingPanelSelectOptionViewController<T: Selectable & Equatable>: UITableViewController {
var headerTitle = ""
var selectedOption: T?
Expand Down
41 changes: 23 additions & 18 deletions kDrive/UI/Controller/Menu/Share/PublicShareViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,26 @@ final class PublicShareViewModel: InMemoryFileListViewModel {
let rootProxy: ProxyFile
var publicShareApiFetcher: PublicShareApiFetcher?

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

// TODO: i18n
let configuration = Configuration(selectAllSupported: false,
rootTitle: "public share",
emptyViewType: .emptyFolder,
supportsDrop: false,
rightBarButtons: [.downloadAll],
matomoViewPath: [MatomoUtils.Views.menu.displayName, "publicShare"])

override init(configuration: Configuration, driveFileManager: DriveFileManager, currentDirectory: File) {
rootProxy = currentDirectory.proxify()
super.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: currentDirectory)
observedFiles = AnyRealmCollection(currentDirectory.children)
}

required init(driveFileManager: DriveFileManager, currentDirectory: File? = nil) {
fatalError("unsupported initializer")
}

convenience init(
publicShareProxy: PublicShareProxy,
sortType: SortType,
driveFileManager: DriveFileManager,
currentDirectory: File,
apiFetcher: PublicShareApiFetcher
apiFetcher: PublicShareApiFetcher,
configuration: Configuration
) {
self.init(driveFileManager: driveFileManager, currentDirectory: currentDirectory)
self.init(configuration: configuration, driveFileManager: driveFileManager, currentDirectory: currentDirectory)

self.publicShareProxy = publicShareProxy
self.sortType = sortType
publicShareApiFetcher = apiFetcher
Expand Down Expand Up @@ -85,14 +79,25 @@ final class PublicShareViewModel: InMemoryFileListViewModel {
}
}

// TODO: Move away from view model
override func barButtonPressed(sender: Any?, type: FileListBarButtonType) {
guard type == .downloadAll else {
// We try to close the "Public Share screen"
if type == .cancel,
!(multipleSelectionViewModel?.isMultipleSelectionEnabled ?? true),
let viewControllerDismissable = viewControllerDismissable {
viewControllerDismissable.dismiss(animated: true, completion: nil)
return
}

super.barButtonPressed(sender: sender, type: type)
return
}

guard downloadObserver == nil else {
return
}

guard type == .downloadAll,
let publicShareProxy = publicShareProxy else {
guard let publicShareProxy = publicShareProxy else {
return
}

Expand Down

0 comments on commit 5368da7

Please sign in to comment.