Skip to content
Closed
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
228 changes: 177 additions & 51 deletions iOSClient/Menu/NCContextMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ import NextcloudKit
import JGProgressHUD

class NCContextMenu: NSObject {

// swiftlint:disable force_cast
let appDelegate = UIApplication.shared.delegate as! AppDelegate
// swiftlint:enable force_cast

let utilityFileSystem = NCUtilityFileSystem()
let utility = NCUtility()

func viewMenu(ocId: String, viewController: UIViewController, image: UIImage?) -> UIMenu {
func viewMenu(ocId: String, indexPath: IndexPath, viewController: UIViewController, image: UIImage?) -> UIMenu {
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return UIMenu() }

var downloadRequest: DownloadRequest?
Expand All @@ -50,6 +54,17 @@ class NCContextMenu: NSObject {
request.cancel()
}
}

var titleSave: String = NSLocalizedString("_save_selected_files_", comment: "")
if metadataMOV != nil { titleSave = NSLocalizedString("_livephoto_save_", comment: "") }
let serverUrl = metadata.serverUrl + "/" + metadata.fileName
var isOffline: Bool = false

if metadata.directory, let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.account, serverUrl)) {
isOffline = directory.offline
} else if let localFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) {
isOffline = localFile.offline
}

// MENU ITEMS

Expand All @@ -58,17 +73,137 @@ class NCContextMenu: NSObject {
NCActionCenter.shared.openShare(viewController: viewController, metadata: metadata, page: .activity)
}

let titleOffline = isOffline ? NSLocalizedString("_remove_available_offline_", comment: "") : NSLocalizedString("_set_available_offline_", comment: "")

let offline = UIAction(title: titleOffline, image: UIImage(systemName: "tray.and.arrow.down")) { _ in
NCActionCenter.shared.setMetadataAvalableOffline(metadata, isOffline: isOffline)
if let viewController = viewController as? NCCollectionViewCommon {
viewController.reloadDataSource()
}
}

let print = UIAction(title: NSLocalizedString("_print_", comment: ""), image: UIImage(systemName: "printer") ) { _ in
NCNetworking.shared.downloadQueue.addOperation(NCOperationDownload(metadata: metadata, selector: NCGlobal.shared.selectorPrint))
}

let moveCopy = UIAction(title: NSLocalizedString("_move_or_copy_", comment: ""), image: UIImage(systemName: "arrow.up.right.square")) { action in
NCActionCenter.shared.openSelectView(items: [metadata], indexPath: [indexPath])
}

let rename = UIAction(title: NSLocalizedString("_rename_", comment: ""), image: UIImage(systemName: "pencil")) { action in
if let vcRename = UIStoryboard(name: "NCRenameFile", bundle: nil).instantiateInitialViewController() as? NCRenameFile {
vcRename.metadata = metadata
vcRename.imagePreview = image
vcRename.indexPath = indexPath
let popup = NCPopupViewController(contentController: vcRename, popupWidth: vcRename.width, popupHeight: vcRename.height)
viewController.present(popup, animated: true)
}
}

let decrypt = UIAction(title: NSLocalizedString("_e2e_remove_folder_encrypted_", comment: ""), image: UIImage(systemName: "lock") ) { action in
NextcloudKit.shared.markE2EEFolder(fileId: metadata.fileId, delete: true) { _, error in
if error == .success {
NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, serverUrl))
NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: nil, ocId: nil, fileId: nil, encrypted: false, richWorkspace: nil, account: metadata.account)
NCManageDatabase.shared.setMetadataEncrypted(ocId: metadata.ocId, encrypted: false)

NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl": metadata.serverUrl])
} else {
NCContentPresenter().messageNotification(NSLocalizedString("_e2e_error_", comment: ""), error: error, delay: NCGlobal.shared.dismissAfterSecond, type: .error)
}
}
}

let encrypt = UIAction(title: NSLocalizedString("_e2e_set_folder_encrypted_", comment: ""), image: UIImage(systemName: "lock") ) { action in
Task {
let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: metadata.account, fileName: metadata.fileName, serverUrl: metadata.serverUrl, userId: metadata.userId)
if error != .success {
NCContentPresenter().showError(error: error)
}
}
}

let favorite = UIAction(title: metadata.favorite ?
NSLocalizedString("_remove_favorites_", comment: "") :
NSLocalizedString("_add_favorites_", comment: ""),
image: utility.loadImage(named: metadata.favorite ? "star.slash" : "star", color: NCBrandColor.shared.yellowFavorite)) { _ in
image: utility.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite)) { _ in
NCNetworking.shared.favoriteMetadata(metadata) { error in
if error != .success {
NCContentPresenter().showError(error: error)
}
}
}

let openIn = UIAction(title: NSLocalizedString("_open_in_", comment: ""),
image: UIImage(systemName: "square.and.arrow.up") ) { _ in
if self.utilityFileSystem.fileProviderStorageExists(metadata) {
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDownloadedFile, userInfo: ["ocId": metadata.ocId, "selector": NCGlobal.shared.selectorOpenIn, "error": NKError(), "account": metadata.account])
} else {
guard let metadata = NCManageDatabase.shared.setMetadatasSessionInWaitDownload(metadatas: [metadata],
session: NextcloudKit.shared.nkCommonInstance.sessionIdentifierDownload,
selector: NCGlobal.shared.selectorOpenIn) else { return }
hud.show(in: viewController.view)
NCNetworking.shared.download(metadata: metadata, withNotificationProgressTask: false) {
} requestHandler: { request in
downloadRequest = request
} progressHandler: { progress in
hud.progress = Float(progress.fractionCompleted)
} completion: { afError, error in
DispatchQueue.main.async {
if error == .success || afError?.isExplicitlyCancelledError ?? false {
hud.dismiss()
} else {
hud.indicatorView = JGProgressHUDErrorIndicatorView()
hud.textLabel.text = error.description
hud.dismiss(afterDelay: NCGlobal.shared.dismissAfterSecond)
}
}
}
}
}

let viewInFolder = UIAction(title: NSLocalizedString("_view_in_folder_", comment: ""),
image: UIImage(systemName: "arrow.forward.square")) { _ in
NCActionCenter.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileNameBlink: metadata.fileName, fileNameOpen: nil)
}

let save = UIAction(title: titleSave,
image: UIImage(systemName: "square.and.arrow.down")) { _ in
if let metadataMOV = metadataMOV {
NCNetworking.shared.saveLivePhotoQueue.addOperation(NCOperationSaveLivePhoto(metadata: metadata, metadataMOV: metadataMOV))
} else {
if self.utilityFileSystem.fileProviderStorageExists(metadata) {
NCActionCenter.shared.saveAlbum(metadata: metadata)
} else {
guard let metadata = NCManageDatabase.shared.setMetadatasSessionInWaitDownload(metadatas: [metadata],
session: NextcloudKit.shared.nkCommonInstance.sessionIdentifierDownload,
selector: NCGlobal.shared.selectorSaveAlbum) else { return }
hud.show(in: viewController.view)
NCNetworking.shared.download(metadata: metadata, withNotificationProgressTask: false) {
} requestHandler: { request in
downloadRequest = request
} progressHandler: { progress in
hud.progress = Float(progress.fractionCompleted)
} completion: { afError, error in
DispatchQueue.main.async {
if error == .success || afError?.isExplicitlyCancelledError ?? false {
hud.dismiss()
} else {
hud.indicatorView = JGProgressHUDErrorIndicatorView()
hud.textLabel.text = error.description
hud.dismiss(afterDelay: NCGlobal.shared.dismissAfterSecond)
}
}
}
}
}
}

let copy = UIAction(title: NSLocalizedString("_copy_file_", comment: ""),
image: UIImage(systemName: "doc.on.doc")) { _ in
NCActionCenter.shared.copyPasteboard(pasteboardOcIds: [metadata.ocId])
}

let share = UIAction(title: NSLocalizedString("_share_", comment: ""),
image: UIImage(systemName: "square.and.arrow.up") ) { _ in
if self.utilityFileSystem.fileProviderStorageExists(metadata) {
Expand Down Expand Up @@ -103,10 +238,6 @@ class NCContextMenu: NSObject {
}
}

let viewInFolder = UIAction(title: NSLocalizedString("_view_in_folder_", comment: ""),
image: UIImage(systemName: "questionmark.folder")) { _ in
NCActionCenter.shared.openFileViewInFolder(serverUrl: metadata.serverUrl, fileNameBlink: metadata.fileName, fileNameOpen: nil)
}

let livePhotoSave = UIAction(title: NSLocalizedString("_livephoto_save_", comment: ""),
image: UIImage(systemName: "livephoto")) { _ in
Expand Down Expand Up @@ -166,7 +297,7 @@ class NCContextMenu: NSObject {
} else {
NCContentPresenter().showError(error: error)
}
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "onlyLocalCache": false, "error": error])
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": [indexPath], "onlyLocalCache": false, "error": error])
}
})
alertController.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel) { _ in })
Expand All @@ -183,7 +314,7 @@ class NCContextMenu: NSObject {
} else {
NCContentPresenter().showError(error: error)
}
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "onlyLocalCache": true, "error": error])
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "indexPath": [indexPath], "onlyLocalCache": true, "error": error])
}
}

Expand All @@ -194,58 +325,53 @@ class NCContextMenu: NSObject {

// ------ MENU -----

var menu: [UIMenuElement] = []

if metadata.directory {

if metadata.isDirectoryE2EE || metadata.e2eEncrypted {
menu.append(favorite)
} else {
menu.append(favorite)
menu.append(deleteConfirmFile)
}
return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])
let serverUrlHome = utilityFileSystem.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId)
let isEncryptionDisabled = metadata.canUnsetDirectoryAsE2EE
let isEncrytptionEnabled = metadata.serverUrl == serverUrlHome && metadata.canSetDirectoryAsE2EE
let submenu = UIMenu(title: "", options: .displayInline, children: isEncrytptionEnabled ? [favorite, offline, rename, moveCopy, encrypt, deleteSubMenu] : [favorite, offline, rename, moveCopy, deleteSubMenu])
let childrenArray = metadata.e2eEncrypted ? ( isEncryptionDisabled ? [offline, decrypt] : (metadata.serverUrl == serverUrlHome) ? [offline] : [offline, deleteSubMenu]) : [detail,submenu]
return UIMenu(title: "", children: childrenArray)

} else {

if metadata.lock {
menu.append(favorite)
if metadata.isDocumentViewableOnly {
//
} else {
menu.append(share)
if NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) != nil {
menu.append(livePhotoSave)
}
}
} else {
menu.append(favorite)
if metadata.isDocumentViewableOnly {
if viewController is NCMedia {
menu.append(viewInFolder)
}
} else {
menu.append(share)
if NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) != nil {
menu.append(livePhotoSave)
}
var children: [UIMenuElement] = metadata.e2eEncrypted ? [openIn, copy, deleteSubMenu] : [offline, openIn, deleteSubMenu]

if viewController is NCMedia {
menu.append(viewInFolder)
}

// MODIFY WITH QUICK LOOK
if metadata.isModifiableWithQuickLook {
menu.append(modify)
}
if !metadata.lock {
// Workaround: PROPPATCH doesn't work (favorite)
// https://github.com/nextcloud/files_lock/issues/68
if !metadata.isDirectoryE2EE {
children.insert(favorite, at: 0)
children.insert(moveCopy, at: 2)
children.insert(rename, at: 3)
children.insert(copy, at: 3)
}
}

children.append(deleteSubMenu)

if (metadata.contentType != "image/svg+xml") && (metadata.classFile == NKCommon.TypeClassFile.image.rawValue || metadata.classFile == NKCommon.TypeClassFile.video.rawValue) {
children.insert(save, at: 2)
}

if !metadata.e2eEncrypted, (metadata.contentType != "image/svg+xml") && (metadata.classFile == NKCommon.TypeClassFile.image.rawValue || metadata.contentType == "application/pdf" || metadata.contentType == "com.adobe.pdf") {
children.insert(print, at: 2)
}

if !metadata.e2eEncrypted {
if viewController is NCMedia {
menu.append(deleteConfirmFile)
} else {
menu.append(deleteSubMenu)
children.insert(viewInFolder, at: children.count - 1)
}
}
return UIMenu(title: "", children: [detail, UIMenu(title: "", options: .displayInline, children: menu)])

if (!metadata.isDirectoryE2EE && metadata.contentType != "image/gif" && metadata.contentType != "image/svg+xml") && (metadata.contentType == "com.adobe.pdf" || metadata.contentType == "application/pdf" || metadata.classFile == NKCommon.TypeClassFile.image.rawValue) {
children.insert(modify, at: children.count - 1)
}

let submenu = UIMenu(title: "", options: .displayInline, children: children)
guard appDelegate.disableSharesView == false else { return submenu }
let childrenArray = metadata.isDirectoryE2EE ? [submenu] : [detail, submenu]
return UIMenu(title: "", children: childrenArray)
}
}
}
Loading