// // NCCollectionViewCommon+DragDrop.swift // Nextcloud // // Created by Marino Faggiana on 19/04/24. // Copyright © 2024 Marino Faggiana. All rights reserved. // // Author Marino Faggiana // // 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 . // import Foundation import UIKit import NextcloudKit // MARK: - Drag extension NCCollectionViewCommon: UICollectionViewDragDelegate { func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { if isEditMode { return NCDragDrop().performDrag(fileSelect: fileSelect) } else if let metadata = self.dataSource.getMetadata(indexPath: indexPath) { return NCDragDrop().performDrag(metadata: metadata) } return [] } func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters? { let previewParameters = UIDragPreviewParameters() if isLayoutList, let cell = collectionView.cellForItem(at: indexPath) as? NCListCell { let width = (collectionView.frame.width / 3) * 2 previewParameters.visiblePath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: width, height: cell.frame.height), cornerRadius: 10) return previewParameters } else if let cell = collectionView.cellForItem(at: indexPath) as? NCGridCell { previewParameters.visiblePath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height - 40), cornerRadius: 10) return previewParameters } else if let cell = collectionView.cellForItem(at: indexPath) as? NCPhotoCell { previewParameters.visiblePath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height), cornerRadius: 10) return previewParameters } return nil } } // MARK: - Drop extension NCCollectionViewCommon: UICollectionViewDropDelegate { func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool { return true } func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal { var destinationMetadata: tableMetadata? if let destinationIndexPath, let metadata = self.dataSource.getMetadata(indexPath: destinationIndexPath) { destinationMetadata = metadata } DragDropHover.shared.destinationMetadata = destinationMetadata if let destinationMetadata { if destinationMetadata.e2eEncrypted || destinationMetadata.isDirectoryE2EE { DragDropHover.shared.cleanPushDragDropHover() return UICollectionViewDropProposal(operation: .forbidden) } if !destinationMetadata.directory && serverUrl.isEmpty { DragDropHover.shared.cleanPushDragDropHover() return UICollectionViewDropProposal(operation: .forbidden) } } else { if serverUrl.isEmpty || NCUtilityFileSystem().isDirectoryE2EE(serverUrl: serverUrl, account: self.session.account) { DragDropHover.shared.cleanPushDragDropHover() return UICollectionViewDropProposal(operation: .forbidden) } } // DIRECTORY - Push Metadata if DragDropHover.shared.pushIndexPath != destinationIndexPath || DragDropHover.shared.pushCollectionView != collectionView { DragDropHover.shared.pushIndexPath = destinationIndexPath DragDropHover.shared.pushCollectionView = collectionView DragDropHover.shared.pushTimerIndexPath?.invalidate() DragDropHover.shared.pushTimerIndexPath = Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { [weak self] _ in guard let self else { return } if let destinationIndexPath, DragDropHover.shared.pushIndexPath == destinationIndexPath, DragDropHover.shared.pushCollectionView == collectionView, let metadata = self.dataSource.getMetadata(indexPath: destinationIndexPath), metadata.directory { DragDropHover.shared.cleanPushDragDropHover() self.pushMetadata(metadata) } } } return UICollectionViewDropProposal(operation: .copy) } func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { DragDropHover.shared.cleanPushDragDropHover() DragDropHover.shared.sourceMetadatas = nil if let metadatas = NCDragDrop().performDrop(collectionView, performDropWith: coordinator, serverUrl: self.serverUrl, isImageVideo: false, controller: self.controller) { // TODO: NOT POSSIBLE DRAG DROP DIFFERENT ACCOUNT if let metadata = metadatas.first, metadata.account != self.session.account { return } DragDropHover.shared.sourceMetadatas = metadatas openMenu(collectionView: collectionView, location: coordinator.session.location(in: collectionView)) } } func collectionView(_ collectionView: UICollectionView, dropSessionDidExit session: UIDropSession) { DragDropHover.shared.cleanPushDragDropHover() } func collectionView(_ collectionView: UICollectionView, dropSessionDidEnd session: UIDropSession) { DragDropHover.shared.cleanPushDragDropHover() } // MARK: - private func openMenu(collectionView: UICollectionView, location: CGPoint) { var listMenuItems: [UIMenuItem] = [] listMenuItems.append(UIMenuItem(title: NSLocalizedString("_copy_", comment: ""), action: #selector(copyMenuFile))) listMenuItems.append(UIMenuItem(title: NSLocalizedString("_move_", comment: ""), action: #selector(moveMenuFile))) UIMenuController.shared.menuItems = listMenuItems UIMenuController.shared.showMenu(from: collectionView, rect: CGRect(x: location.x, y: location.y, width: 0, height: 0)) } @objc func copyMenuFile() { guard let sourceMetadatas = DragDropHover.shared.sourceMetadatas else { return } var serverUrl: String = self.serverUrl if let destinationMetadata = DragDropHover.shared.destinationMetadata, destinationMetadata.directory { serverUrl = destinationMetadata.serverUrl + "/" + destinationMetadata.fileName } NCDragDrop().copyFile(metadatas: sourceMetadatas, serverUrl: serverUrl) } @objc func moveMenuFile() { guard let sourceMetadatas = DragDropHover.shared.sourceMetadatas else { return } var serverUrl: String = self.serverUrl if let destinationMetadata = DragDropHover.shared.destinationMetadata, destinationMetadata.directory { serverUrl = destinationMetadata.serverUrl + "/" + destinationMetadata.fileName } NCDragDrop().moveFile(metadatas: sourceMetadatas, serverUrl: serverUrl) } } // MARK: - Drop Interaction Delegate extension NCCollectionViewCommon: UIDropInteractionDelegate { }