Created
October 31, 2018 16:04
-
-
Save pablocarmu/65c2d9f7c8af5391687f2ce09dfaf0c4 to your computer and use it in GitHub Desktop.
Actions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Action.swift | |
// ownCloud | |
// | |
// Created by Pablo Carrascal on 30/10/2018. | |
// Copyright © 2018 ownCloud GmbH. All rights reserved. | |
// | |
import UIKit | |
import ownCloudSDK | |
typealias ActionCompletion = ((_ item: OCItem, _ core: OCCore, _ vcToPresent: UIViewController) -> Void)? | |
enum ActionType { | |
case destructive | |
case regular | |
} | |
struct Action { | |
var name: String | |
var type: ActionType | |
var completion: ActionCompletion | |
init(with name: String, completion: ActionCompletion, type: ActionType) { | |
self.name = name | |
self.completion = completion | |
self.type = type | |
} | |
} | |
class ActionsMoreViewController: NSObject { | |
weak var vcToPresentIn: UIViewController? | |
var moreViewController: UIViewController? | |
var core: OCCore | |
var item: OCItem | |
var interactionController: UIDocumentInteractionController? | |
init (item: OCItem, core: OCCore, into viewController: UIViewController) { | |
self.vcToPresentIn = viewController | |
self.core = core | |
self.item = item | |
super.init() | |
} | |
func presentActionsCard(with actions: [Action], completion: () -> Void) { | |
self.moreViewController = actionsViewController(with: actions, for: item, core: core) | |
vcToPresentIn?.present(asCard: moreViewController!, animated: true) | |
} | |
func actionsViewController(with actions: [Action], for item: OCItem, core: OCCore) -> MoreViewController { | |
let header = MoreViewHeader(for: item, with: core) | |
let tableViewController = MoreStaticTableViewController(style: .grouped) | |
let moreViewController: MoreViewController = MoreViewController(item: item, core: core, header: header, viewController: tableViewController) | |
var rows: [StaticTableViewRow] = [] | |
for action in actions { | |
var style: StaticTableViewRowButtonStyle | |
switch action.type { | |
case .destructive: | |
style = .destructive | |
default: | |
style = .plainNonOpaque | |
} | |
let row: StaticTableViewRow = StaticTableViewRow(buttonWithAction: { (_, _) in | |
moreViewController.dismiss(animated: true, completion: { | |
action.completion?(item, core, self.vcToPresentIn!) | |
}) | |
}, title: action.name, style: style) | |
rows.append(row) | |
} | |
let title = NSAttributedString(string: "Actions".localized, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 20, weight: .heavy)]) | |
let section = MoreStaticTableViewSection(headerAttributedTitle: title, identifier: "actions-section", rows: rows) | |
tableViewController.addSection(section) | |
return moreViewController | |
} | |
func openIn(completion: (() -> Void)? = nil) -> Action { | |
let action = Action(with: "Open in".localized, completion: { (item, core, vcToPresentIn) in | |
let controller = DownloadFileProgressHUDViewController() | |
controller.present(on: vcToPresentIn) | |
if let downloadProgress = core.downloadItem(item, options: nil, resultHandler: { (error, _, _, file) in | |
if error != nil { | |
Log.log("Error \(String(describing: error)) downloading \(String(describing: item.path)) in openIn function") | |
} else { | |
controller.dismiss(animated: true, completion: { | |
self.interactionController = UIDocumentInteractionController(url: file!.url) | |
self.interactionController?.presentOptionsMenu(from: .zero, in: vcToPresentIn.view, animated: true) | |
}) | |
} | |
completion?() | |
}) { | |
controller.attach(progress: downloadProgress) | |
} else { | |
let alert = UIAlertController(with: "No Network connection", message: "No network connection") | |
vcToPresentIn.present(alert, animated: true) | |
} | |
}, type: .regular) | |
return action | |
} | |
func duplicate(completion: (() -> Void)? = nil) -> Action { | |
let action = Action(with: "Duplicate", completion: { (item, core, viewcontroller) in | |
guard let viewController = viewcontroller as? ClientQueryViewController else { | |
return | |
} | |
var name: String = "\(item.name!) copy" | |
if item.type != .collection { | |
let itemName = item.nameWithoutExtension() | |
var fileExtension = item.fileExtension() | |
if fileExtension != "" { | |
fileExtension = ".\(fileExtension)" | |
} | |
name = "\(itemName) copy\(fileExtension)" | |
} | |
if let progress = core.copy(item, to: viewController.query?.rootItem, withName: name, options: nil, resultHandler: { (error, _, item, _) in | |
if error != nil { | |
Log.log("Error \(String(describing: error)) deleting \(String(describing: item?.path))") | |
} | |
completion?() | |
}) { | |
viewController.progressSummarizer?.startTracking(progress: progress) | |
} | |
}, type: .regular) | |
return action | |
} | |
func move(completion: (() -> Void)? = nil) -> Action { | |
let action = Action(with: "Move".localized, completion: { (item, core, viewController) in | |
guard let viewController = viewController as? ClientQueryViewController else { | |
return | |
} | |
let directoryPickerVC = ClientDirectoryPickerViewController(core: core, path: "/", completion: { (selectedDirectory) in | |
if let progress = core.move(item, to: selectedDirectory, withName: item.name, options: nil, resultHandler: { (error, _, _, _) in | |
if error != nil { | |
Log.log("Error \(String(describing: error)) moving \(String(describing: item.path))") | |
} | |
completion?() | |
}) { | |
viewController.progressSummarizer?.startTracking(progress: progress) | |
} | |
}) | |
let pickerNavigationController = ThemeNavigationController(rootViewController: directoryPickerVC) | |
viewController.navigationController?.present(pickerNavigationController, animated: true) | |
}, type: .regular) | |
return action | |
} | |
func delete(completion: (() -> Void)? = nil) -> Action { | |
let action = Action(with: "Delete".localized, completion: { (item, core, viewController) in | |
let alertController = UIAlertController( | |
with: item.name!, | |
message: "Are you sure you want to delete this item from the server?".localized, | |
destructiveLabel: "Delete".localized, | |
preferredStyle: UIDevice.current.isIpad() ? UIAlertControllerStyle.alert : UIAlertControllerStyle.actionSheet, | |
destructiveAction: { | |
if let progress = core.delete(item, requireMatch: true, resultHandler: { (error, _, _, _) in | |
if error != nil { | |
Log.log("Error \(String(describing: error)) deleting \(String(describing: item.path))") | |
} | |
completion?() | |
}) { | |
if let viewController = viewController as? ClientQueryViewController { | |
viewController.progressSummarizer?.startTracking(progress: progress) | |
} | |
} | |
}) | |
viewController.present(alertController, animated: true) | |
}, type: .destructive) | |
return action | |
} | |
func rename(completion: (() -> Void)? = nil) -> Action { | |
let action = Action(with: "Rename".localized, completion: { (item, core, viewController) in | |
guard let viewController = viewController as? ClientQueryViewController else { | |
return | |
} | |
let renameViewController = NamingViewController(with: item, core: self.core, stringValidator: { name in | |
if name.contains("/") || name.contains("\\") { | |
return (false, "File name cannot contain / or \\") | |
} else { | |
return (true, nil) | |
} | |
}, completion: { newName, _ in | |
guard newName != nil else { | |
return | |
} | |
if let progress = core.move(item, to: viewController.query?.rootItem, withName: newName, options: nil, resultHandler: { (error, _, _, _) in | |
if error != nil { | |
Log.log("Error \(String(describing: error)) renaming \(String(describing: item.path))") | |
} | |
completion?() | |
}) { | |
viewController.progressSummarizer?.startTracking(progress: progress) | |
} | |
}) | |
renameViewController.navigationItem.title = "Rename".localized | |
let navigationController = ThemeNavigationController(rootViewController: renameViewController) | |
navigationController.modalPresentationStyle = .overFullScreen | |
viewController.present(navigationController, animated: true) | |
}, type: .regular) | |
return action | |
} | |
} | |
extension ActionsMoreViewController: UIDocumentInteractionControllerDelegate { | |
func documentInteractionControllerDidDismissOpenInMenu(_ controller: UIDocumentInteractionController) { | |
self.interactionController = nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment