Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions FileExplorer/FileExplorer/ActionsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// SOFTWARE.

import UIKit
import GoogleMobileAds

protocol ActionsViewControllerDelegate: class {
func actionsViewControllerDidRequestRemoval(_ controller: ActionsViewController)
Expand All @@ -33,7 +34,7 @@ protocol ActionsViewControllerDelegate: class {
final class ActionsViewController: UIViewController {
weak var delegate: ActionsViewControllerDelegate?

private let toolbar = UIToolbar()
let toolbar = UIToolbar()
private let contentViewController: UIViewController

init(contentViewController: UIViewController) {
Expand All @@ -48,7 +49,7 @@ final class ActionsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = UIColor.white
view.backgroundColor = UIColor.dynamicColor(light: .white, dark: .black)//UIColor.white

extendedLayoutIncludesOpaqueBars = false
edgesForExtendedLayout = []
Expand All @@ -63,10 +64,23 @@ final class ActionsViewController: UIViewController {
UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap))
]

addContentChildViewController(contentViewController, insets: UIEdgeInsets(top: 0, left: 0, bottom: toolbar.bounds.height, right: 0))
addContentChildViewController(contentViewController, insets: UIEdgeInsets(top: 0, left: 0, bottom: toolbar.bounds.height+30, right: 0))
navigationItem.title = contentViewController.navigationItem.title
contentViewController.view.bottomAnchor.constraint(equalTo: toolbar.topAnchor, constant: 0).isActive = true
interstitial = createAndLoadInterstitial()
}

var interstitial: GADInterstitial!
func callAds(){
if interstitial != nil {
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
} else {
print("Ad wasn't ready")
}
}
}

// MARK: Actions

@objc
Expand All @@ -76,6 +90,25 @@ final class ActionsViewController: UIViewController {

@objc
private func handleTrashButtonTap() {
callAds()
delegate?.actionsViewControllerDidRequestRemoval(self)
}
}


extension ActionsViewController: GADInterstitialDelegate{
public func interstitialDidReceiveAd(_ ad: GADInterstitial) {
//self.interstitial.present(fromRootViewController: self)
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: )
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}

public func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
//navigationController?.popViewController(animated: true)
}
}
2 changes: 1 addition & 1 deletion FileExplorer/FileExplorer/Array+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Foundation
extension Array where Element: Equatable {
@discardableResult
mutating func remove(_ item: Element) -> Bool {
let index = self.index() { $0 == item }
let index = self.firstIndex() { $0 == item }
if let index = index {
remove(at: index)
return true
Expand Down
107 changes: 98 additions & 9 deletions FileExplorer/FileExplorer/DirectoryContentViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
// SOFTWARE.

import Foundation

protocol DirectoryContentViewControllerDelegate: class {
protocol DirectoryContentViewControllerDelegate: AnyObject {
func directoryContentViewController(_ controller: DirectoryContentViewController, didChangeEditingStatus isEditing: Bool)
func directoryContentViewController(_ controller: DirectoryContentViewController, didSelectItem item: Item<Any>)
func directoryContentViewController(_ controller: DirectoryContentViewController, didSelectItemDetails item: Item<Any>)
Expand All @@ -47,6 +46,13 @@ final class DirectoryContentViewController: UICollectionViewController {
}
}

//SWIPE
var defaultOptions = SwipeOptions()
var isSwipeRightEnabled = true
var buttonDisplayMode: ButtonDisplayMode = .titleAndImage
var buttonStyle: ButtonStyle = .backgroundColor
var usesTallCells = false
//SWIPE
init(viewModel: DirectoryContentViewModel) {
self.viewModel = viewModel
self.toolbar = UIToolbar.makeToolbar()
Expand All @@ -57,6 +63,7 @@ final class DirectoryContentViewController: UICollectionViewController {

super.init(collectionViewLayout: layout)
viewModel.delegate = self
navigationItem.title = ""
}

required init?(coder aDecoder: NSCoder) {
Expand All @@ -83,7 +90,7 @@ final class DirectoryContentViewController: UICollectionViewController {
extendedLayoutIncludesOpaqueBars = false
edgesForExtendedLayout = []

collectionView.backgroundColor = UIColor.white
collectionView.backgroundColor = UIColor.dynamicColor(light: .white, dark: .black)
collectionView.registerCell(ofClass: ItemCell.self)
collectionView.registerHeader(ofClass: CollectionViewHeader.self)
collectionView.registerFooter(ofClass: CollectionViewFooter.self)
Expand All @@ -94,9 +101,16 @@ final class DirectoryContentViewController: UICollectionViewController {
self.toolbarBottomConstraint = toolbar.pinToBottom(of: view)
self.toolbarBottomConstraint?.constant = toolbar.bounds.height

self.toolbar.isHidden = true

syncWithViewModel(false)
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = ""
}

func syncWithViewModel(_ animated: Bool) {
if let items = toolbar.items {
for barButtonItem in items {
Expand Down Expand Up @@ -127,6 +141,7 @@ final class DirectoryContentViewController: UICollectionViewController {

collectionView.setEditing(editing, animated: animated)
UIView.animate(withDuration: 0.2) {
self.toolbar.isHidden.toggle()
self.toolbarBottomConstraint?.constant = editing ? 0.0 : self.toolbar.bounds.height
collectionView.contentInset.bottom = editing ? self.toolbar.bounds.height : 0.0
collectionView.scrollIndicatorInsets = collectionView.contentInset
Expand All @@ -145,18 +160,18 @@ final class DirectoryContentViewController: UICollectionViewController {
selectActionButton,
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
deleteActionButton
].flatMap { $0 }
].compactMap { $0 }
}

// MARK: Actions

func handleSelectButtonTap() {
@objc func handleSelectButtonTap() {
viewModel.chooseItems { selectedItems in
delegate?.directoryContentViewController(self, didChooseItems: selectedItems)
}
}

func handleDeleteButtonTap() {
@objc func handleDeleteButtonTap() {
showLoadingIndicator()
viewModel.deleteItems(at: viewModel.indexPathsOfSelectedCells) { [weak self] result in
guard let strongSelf = self else { return }
Expand All @@ -171,7 +186,7 @@ final class DirectoryContentViewController: UICollectionViewController {
}
}

func handleEditButtonTap() {
@objc func handleEditButtonTap() {
viewModel.isEditing = !viewModel.isEditing
delegate?.directoryContentViewController(self, didChangeEditingStatus: viewModel.isEditing)
}
Expand Down Expand Up @@ -214,19 +229,20 @@ extension DirectoryContentViewController {
cell.subtitle = itemViewModel.subtitle
cell.accessoryType = itemViewModel.accessoryType
cell.iconImage = itemViewModel.thumbnailImage(with: cell.maximumIconSize)
cell.delegate = self
return cell
}

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionElementKindSectionHeader {
if kind == UICollectionView.elementKindSectionHeader {
let header = collectionView.dequeueReusableHeader(ofClass: CollectionViewHeader.self, for: indexPath) as CollectionViewHeader
header.sortModeChangeAction = viewModel.sortModeChangeAction
header.sortMode = viewModel.sortMode
UIView.performWithoutAnimation {
header.layoutIfNeeded()
}
return header
} else if kind == UICollectionElementKindSectionFooter {
} else if kind == UICollectionView.elementKindSectionFooter {
return collectionView.dequeueReusableFooter(ofClass: CollectionViewFooter.self, for: indexPath) as CollectionViewFooter
} else {
fatalError()
Expand All @@ -252,3 +268,76 @@ extension DirectoryContentViewController: UISearchResultsUpdating {
viewModel.searchQuery = searchController.searchBar.text
}
}

extension DirectoryContentViewController: SwipeCollectionViewCellDelegate {

func collectionView(_ collectionView: UICollectionView, editActionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {

let flag = SwipeAction(style: .default, title: nil, handler: nil)
flag.hidesWhenSelected = true
configure(action: flag, with: .flag)

let delete = SwipeAction(style: .destructive, title: nil) { [self] action, indexPath in
viewModel.deleteItems(at: [indexPath]) { [weak self] result in
guard let strongSelf = self else { return }
delegate?.directoryContentViewController(strongSelf, didChangeEditingStatus: strongSelf.viewModel.isEditing)
}
}
configure(action: delete, with: .trash)

return [delete]
}

func collectionView(_ collectionView: UICollectionView, editActionsOptionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = orientation == .left ? .selection : .destructive
options.transitionStyle = defaultOptions.transitionStyle

switch buttonStyle {
case .backgroundColor:
options.buttonSpacing = 11
case .circular:
options.buttonSpacing = 4
#if canImport(Combine)
if #available(iOS 13.0, *) {
options.backgroundColor = UIColor.systemGray6
} else {
options.backgroundColor = #colorLiteral(red: 0.9467939734, green: 0.9468161464, blue: 0.9468042254, alpha: 1)
}
#else
options.backgroundColor = #colorLiteral(red: 0.9467939734, green: 0.9468161464, blue: 0.9468042254, alpha: 1)
#endif
}

return options
}

func visibleRect(for collectionView: UICollectionView) -> CGRect? {
if usesTallCells == false { return nil }

if #available(iOS 11.0, *) {
return collectionView.safeAreaLayoutGuide.layoutFrame
} else {
let topInset = navigationController?.navigationBar.frame.height ?? 0
let bottomInset = navigationController?.toolbar?.frame.height ?? 0
let bounds = collectionView.bounds

return CGRect(x: bounds.origin.x, y: bounds.origin.y + topInset, width: bounds.width, height: bounds.height - bottomInset)
}
}

func configure(action: SwipeAction, with descriptor: ActionDescriptor) {
action.title = descriptor.title(forDisplayMode: buttonDisplayMode)
action.image = descriptor.image(forStyle: buttonStyle, displayMode: buttonDisplayMode)

switch buttonStyle {
case .backgroundColor:
action.backgroundColor = descriptor.color(forStyle: buttonStyle)
case .circular:
action.backgroundColor = .clear
action.textColor = descriptor.color(forStyle: buttonStyle)
action.font = .systemFont(ofSize: 13)
action.transitionDelegate = ScaleTransition.default
}
}
}
4 changes: 2 additions & 2 deletions FileExplorer/FileExplorer/DirectoryContentViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ final class DirectoryContentViewModel {
func deselect(at indexPath: IndexPath) {
let item = self.item(for: indexPath)
if isEditing {
if let index = selectedItems.index(where: { $0 == item }) {
if let index = selectedItems.firstIndex(where: { $0 == item }) {
selectedItems.remove(at: index)
}
} else {
Expand All @@ -201,7 +201,7 @@ final class DirectoryContentViewModel {
}

func deleteItems(at indexPaths: [IndexPath], completionBlock: @escaping (Result<Void>) -> Void) {
let items = indexPaths.flatMap { item(for: $0) }
let items = indexPaths.compactMap { item(for: $0) }
fileService.delete(items: items) { result, removedItems, itemsNotRemovedDueToFailure in
completionBlock(result)
self.delegate?.directoryViewModelDidChange(self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ final class DirectoryItemPresentationCoordinator {
return directoryViewController
}
navigationController?.pushViewController(viewController, animated: animated)

} else {
let viewController = ErrorViewController(errorDescription: "URL is incorrect.", finishButtonHidden: finishButtonHidden)
viewController.delegate = self
Expand Down
12 changes: 9 additions & 3 deletions FileExplorer/FileExplorer/DirectoryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,14 @@ final class DirectoryViewController: UIViewController {
addContentChildViewController(directoryContentViewController, insets: UIEdgeInsets(top: searchController.searchBar.bounds.height, left: 0.0, bottom: 0.0, right: 0.0))
navigationItem.rightBarButtonItem = directoryContentViewController.navigationItem.rightBarButtonItem
navigationItem.title = directoryContentViewController.navigationItem.title
view.sendSubview(toBack: directoryContentViewController.view)
view.sendSubviewToBack(directoryContentViewController.view)
setUpLeftBarButtonItem()
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = ""
}

func setUpSearchBarController() {
let searchBar = searchController.searchBar
Expand All @@ -131,10 +136,9 @@ final class DirectoryViewController: UIViewController {
searchController.isActive = newValue
}
}

// MARK: Actions

func handleFinishButtonTap() {
@objc func handleFinishButtonTap() {
delegate?.directoryViewControllerDidFinish(self)
}
}
Expand All @@ -149,9 +153,11 @@ extension DirectoryViewController: UISearchBarDelegate {
extension DirectoryViewController: DirectoryContentViewControllerDelegate {
func directoryContentViewController(_ controller: DirectoryContentViewController, didChangeEditingStatus isEditing: Bool) {
searchController.searchBar.isEnabled = !isEditing
navigationItem.title = ""
}

func directoryContentViewController(_ controller: DirectoryContentViewController, didSelectItem item: Item<Any>) {

delegate?.directoryViewController(self, didSelectItem: item)
}

Expand Down
2 changes: 1 addition & 1 deletion FileExplorer/FileExplorer/ErrorViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ final class ErrorViewController: UIViewController {

// MARK: Actions

func handleFinishButtonTap() {
@objc func handleFinishButtonTap() {
delegate?.errorViewControllerDidFinish(self)
}
}
12 changes: 11 additions & 1 deletion FileExplorer/FileExplorer/FileExplorerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public final class FileExplorerViewController: UIViewController {
override public func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = UIColor.white
view.backgroundColor = UIColor.dynamicColor(light: .white, dark: .black)

let navigationController = UINavigationController()
addContentChildViewController(navigationController)
Expand All @@ -126,6 +126,16 @@ public final class FileExplorerViewController: UIViewController {
} else {
precondition(false, "Passed URL is incorrect.")
}
navigationItem.title = ""
}

override public var prefersStatusBarHidden: Bool {
return true
}

public override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationItem.title = ""
}

override public func viewDidDisappear(_ animated: Bool) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ final class FileItemPresentationCoordinator {

extension FileItemPresentationCoordinator: ActionsViewControllerDelegate {
func actionsViewControllerDidRequestShare(_ controller: ActionsViewController) {
let activityItem = UIActivityItemProvider(placeholderItem: item.url)
let activityViewController = UIActivityViewController(activityItems: [activityItem], applicationActivities: nil)
let activityViewController = UIActivityViewController(activityItems: [item.url], applicationActivities: nil)
activityViewController.popoverPresentationController?.barButtonItem = controller.toolbar.items?[0]
navigationController?.present(activityViewController, animated: true, completion: nil)
}

Expand Down
Loading