diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 7819b8cdfa..bf1c868fb1 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -148,6 +148,13 @@ F37208C62BAB63F0006B5430 /* LRUCache in Frameworks */ = {isa = PBXBuildFile; productRef = F37208C52BAB63F0006B5430 /* LRUCache */; }; F37208C82BAB63F1006B5430 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = F37208C72BAB63F1006B5430 /* KeychainAccess */; }; F38F71252B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */; }; + F39170A92CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AA2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AB2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AC2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AD2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AE2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; + F39170AF2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */; }; F39298972A3B12CB00509762 /* BaseNCMoreCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39298962A3B12CB00509762 /* BaseNCMoreCell.swift */; }; F3953BD72A6E87E000EE03F9 /* BaseIntegrationXCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3953BD62A6E87E000EE03F9 /* BaseIntegrationXCTestCase.swift */; }; F3A047972BD2668800658E7B /* NCAssistantEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A0478F2BD2668800658E7B /* NCAssistantEmptyView.swift */; }; @@ -1204,6 +1211,7 @@ F37208742BAB4AB0006B5430 /* TestConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestConstants.swift; sourceTree = ""; }; F37208772BAB4B5D006B5430 /* BaseXCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseXCTestCase.swift; sourceTree = ""; }; F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCollectionViewCommonSelectTabBar.swift; sourceTree = ""; }; + F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileAutoRenamer+Extensions.swift"; sourceTree = ""; }; F39298962A3B12CB00509762 /* BaseNCMoreCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNCMoreCell.swift; sourceTree = ""; }; F3953BD62A6E87E000EE03F9 /* BaseIntegrationXCTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseIntegrationXCTestCase.swift; sourceTree = ""; }; F3998E192B4879B2007CA5DE /* CoreAudioTypes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioTypes.framework; path = System/Library/Frameworks/CoreAudioTypes.framework; sourceTree = SDKROOT; }; @@ -2849,6 +2857,7 @@ F7245923289BB50B00474787 /* ThreadSafeDictionary.swift */, F33EE6F12BF4C9B200CA1A51 /* PKCS12.swift */, F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */, + F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */, ); path = Utility; sourceTree = ""; @@ -4017,6 +4026,7 @@ files = ( F73EF7BD2B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */, F71433E72C778FFB00E20B5A /* NotificationCenter+MainThread.swift in Sources */, + F39170AA2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F73EF7C52B02250B0087E6E9 /* NCManageDatabase+GPS.swift in Sources */, 2C1D5D7923E2DE9100334ABB /* NCBrand.swift in Sources */, F770768A263A8A2500A1BA94 /* NCUtilityFileSystem.swift in Sources */, @@ -4151,6 +4161,7 @@ F757CC8729E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */, F33EE6F72BF4C9B200CA1A51 /* PKCS12.swift in Sources */, F7B769AD2B7A0B2000C1AAEB /* NCManageDatabase+Metadata+Session.swift in Sources */, + F39170AC2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F73EF7BC2B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */, F724377E2C10B92300C7C68D /* NCPermissions.swift in Sources */, F73EF7B42B0224350087E6E9 /* NCManageDatabase+DirectEditing.swift in Sources */, @@ -4232,6 +4243,7 @@ F7BD71E62636EAFC00643C34 /* NCNetworkingE2EE.swift in Sources */, F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */, F7327E3B2B73B8D600A462C7 /* Array+Extension.swift in Sources */, + F39170AF2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F799DF832C4B7DCC003410B5 /* NCSectionFooter.swift in Sources */, AF22B218277D196700DAB0CC /* NCShareExtension+Files.swift in Sources */, F799DF862C4B7E56003410B5 /* NCSectionHeader.swift in Sources */, @@ -4306,6 +4318,7 @@ F73EF7D02B0225BA0087E6E9 /* NCManageDatabase+Tag.swift in Sources */, F783030228B4C4B800B84583 /* NCUtility.swift in Sources */, F711D63128F44801003F43C8 /* IntentHandler.swift in Sources */, + F39170AE2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F76DEE9728F808AF0041B1C9 /* LockscreenData.swift in Sources */, F72EA95A28B7BD0D00C88F0C /* FilesWidgetView.swift in Sources */, F768823C2C0DD231001CF441 /* NCKeychain.swift in Sources */, @@ -4449,6 +4462,7 @@ F7BFFD2C2C8854690029A201 /* NCHud.swift in Sources */, F771E3F820E239B500AFB62D /* FileProviderExtension+Thumbnail.swift in Sources */, F76882392C0DD230001CF441 /* NCKeychain.swift in Sources */, + F39170AB2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F343A4BF2A1E734600DDA874 /* Optional+Extension.swift in Sources */, AF4BF62027562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */, F73ADD2226554FD10069EA0D /* NCContentPresenter.swift in Sources */, @@ -4467,6 +4481,7 @@ F7E7AEA72BA32D0000512E52 /* NCCollectionViewUnifiedSearch.swift in Sources */, F73EF7A72B0223900087E6E9 /* NCManageDatabase+Comments.swift in Sources */, F33918C42C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift in Sources */, + F39170AD2CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F799DF882C4B83CC003410B5 /* NCCollectionViewCommon+EasyTipView.swift in Sources */, F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */, F77DD6A82C5CC093009448FB /* NCSession.swift in Sources */, @@ -4770,6 +4785,7 @@ F7C9B91F2B582F550064EA91 /* NCManageDatabase+SecurityGuard.swift in Sources */, F75DD767290ABB25002EB562 /* Intent.intentdefinition in Sources */, F72437812C10B92500C7C68D /* NCPermissions.swift in Sources */, + F39170A92CB82024006127BC /* FileAutoRenamer+Extensions.swift in Sources */, F749B64C297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */, F7A8D73F28F181EF008BBE1C /* NCGlobal.swift in Sources */, F74B6D972A7E239A00F03C5F /* NCManageDatabase+Chunk.swift in Sources */, @@ -6046,8 +6062,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/nextcloud/NextcloudKit"; requirement = { - kind = exactVersion; - version = 5.0.0; + branch = "auto-rename"; + kind = branch; }; }; F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = { diff --git a/Share/NCShareCell.swift b/Share/NCShareCell.swift index 047652f93e..ba27c71da8 100644 --- a/Share/NCShareCell.swift +++ b/Share/NCShareCell.swift @@ -27,7 +27,8 @@ import NextcloudKit protocol NCShareCellDelegate: AnyObject { var uploadStarted: Bool { get } func removeFile(named fileName: String) - func renameFile(named fileName: String, account: String) + func showRenameFileDialog(named fileName: String, account: String) + func renameFile(oldName: String, newName: String, account: String) } class NCShareCell: UITableViewCell { @@ -71,7 +72,7 @@ class NCShareCell: UITableViewCell { let alertController = UIAlertController(title: "", message: fileName, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: NSLocalizedString("_rename_file_", comment: ""), style: .default) { _ in - self.delegate?.renameFile(named: self.fileName, account: self.account) + self.delegate?.showRenameFileDialog(named: self.fileName, account: self.account) }) alertController.addAction(UIAlertAction(title: NSLocalizedString("_remove_file_", comment: ""), style: .default) { _ in diff --git a/Share/NCShareExtension+DataSource.swift b/Share/NCShareExtension+DataSource.swift index ae9e84f5bc..c54965087b 100644 --- a/Share/NCShareExtension+DataSource.swift +++ b/Share/NCShareExtension+DataSource.swift @@ -176,7 +176,7 @@ extension NCShareExtension: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard !uploadStarted else { return } let fileName = filesName[indexPath.row] - renameFile(named: fileName, account: session.account) + showRenameFileDialog(named: fileName, account: session.account) } } diff --git a/Share/NCShareExtension+NCAccountRequestDelegate.swift b/Share/NCShareExtension+NCAccountRequestDelegate.swift index a64f425b12..c6633c5df6 100644 --- a/Share/NCShareExtension+NCAccountRequestDelegate.swift +++ b/Share/NCShareExtension+NCAccountRequestDelegate.swift @@ -111,21 +111,25 @@ extension NCShareExtension: NCCreateFormUploadConflictDelegate { } extension NCShareExtension: NCShareCellDelegate { - func renameFile(named fileName: String, account: String) { + func showRenameFileDialog(named fileName: String, account: String) { let alert = UIAlertController.renameFile(fileName: fileName, account: account) { [self] newFileName in - guard let fileIx = self.filesName.firstIndex(of: fileName), - !self.filesName.contains(newFileName), - utilityFileSystem.moveFile(atPath: (NSTemporaryDirectory() + fileName), toPath: (NSTemporaryDirectory() + newFileName)) else { - return showAlert(title: "_single_file_conflict_title_", description: "'\(fileName)' -> '\(newFileName)'") - } - - filesName[fileIx] = newFileName - tableView.reloadData() + renameFile(oldName: fileName, newName: newFileName, account: account) } present(alert, animated: true) } + func renameFile(oldName: String, newName: String, account: String) { + guard let fileIx = self.filesName.firstIndex(of: oldName), + !self.filesName.contains(newName), + utilityFileSystem.moveFile(atPath: (NSTemporaryDirectory() + oldName), toPath: (NSTemporaryDirectory() + newName)) else { + return showAlert(title: "_single_file_conflict_title_", description: "'\(oldName)' -> '\(newName)'") + } + + filesName[fileIx] = newName + tableView.reloadData() + } + func removeFile(named fileName: String) { guard let index = self.filesName.firstIndex(of: fileName) else { return showAlert(title: "_file_not_found_", description: fileName) diff --git a/Share/NCShareExtension.swift b/Share/NCShareExtension.swift index 05ac2e6bb2..a767d97a13 100644 --- a/Share/NCShareExtension.swift +++ b/Share/NCShareExtension.swift @@ -285,17 +285,41 @@ extension NCShareExtension { guard !filesName.isEmpty else { return showAlert(description: "_files_no_files_") } counterUploaded = 0 - uploadStarted = true uploadErrors = [] + var dismissAfterUpload = true var conflicts: [tableMetadata] = [] - for fileName in filesName { - if let fileNameError = FileNameValidator.shared.checkFileName(fileName, account: session.account) { - present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) + var invalidNameIndexes: [Int] = [] + + for (index, fileName) in filesName.enumerated() { + let newFileName = FileAutoRenamer.shared.rename(fileName, account: session.account) + + if fileName != newFileName { + renameFile(oldName: fileName, newName: newFileName, account: session.account) + } + + if let fileNameError = FileNameValidator.shared.checkFileName(newFileName, account: session.account) { + if filesName.count == 1 { + showRenameFileDialog(named: fileName, account: account) + return + } else { + present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))") { + self.extensionContext?.completeRequest(returningItems: self.extensionContext?.inputItems, completionHandler: nil) + }, animated: true) + + invalidNameIndexes.append(index) + dismissAfterUpload = false + continue + } - continue } + } + + for index in invalidNameIndexes.reversed() { + filesName.remove(at: index) + } + for fileName in filesName { let ocId = NSUUID().uuidString let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName) guard utilityFileSystem.copyFile(atPath: (NSTemporaryDirectory() + fileName), toPath: toPath) else { continue } @@ -320,6 +344,8 @@ extension NCShareExtension { } } + tableView.reloadData() + if !conflicts.isEmpty { guard let conflict = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict else { return } @@ -330,13 +356,14 @@ extension NCShareExtension { conflict.delegate = self self.present(conflict, animated: true, completion: nil) } else { - upload() + uploadStarted = true + upload(dismissAfterUpload: dismissAfterUpload) } } - func upload() { + func upload(dismissAfterUpload: Bool = true) { guard uploadStarted else { return } - guard uploadMetadata.count > counterUploaded else { return DispatchQueue.main.async { self.finishedUploading() } } + guard uploadMetadata.count > counterUploaded else { return DispatchQueue.main.async { self.finishedUploading(dismissAfterUpload: dismissAfterUpload) } } let metadata = uploadMetadata[counterUploaded] let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false, account: session.account) @@ -374,7 +401,7 @@ extension NCShareExtension { } } - func finishedUploading() { + func finishedUploading(dismissAfterUpload: Bool = true) { uploadStarted = false if !uploadErrors.isEmpty { let fileList = "- " + uploadErrors.map({ $0.fileName }).joined(separator: "\n - ") diff --git a/iOSClient/Extensions/UIAlertController+Extension.swift b/iOSClient/Extensions/UIAlertController+Extension.swift index 60e2f350bf..f2267d5061 100644 --- a/iOSClient/Extensions/UIAlertController+Extension.swift +++ b/iOSClient/Extensions/UIAlertController+Extension.swift @@ -178,6 +178,10 @@ extension UIAlertController { textField.autocapitalizationType = .words } + let text = alertController.textFields?.first?.text ?? "" + let textCheck = FileNameValidator.shared.checkFileName(text, account: account) + alertController.message = textCheck?.error.localizedDescription + // only allow saving if folder name exists NotificationCenter.default.addObserver( forName: UITextField.textDidBeginEditingNotification, @@ -233,6 +237,10 @@ extension UIAlertController { textField.autocapitalizationType = .words } + let text = alertController.textFields?.first?.text ?? "" + let textCheck = FileNameValidator.shared.checkFileName(text, account: NCManageDatabase.shared.getActiveTableAccount()?.account) + alertController.message = textCheck?.error.localizedDescription + // only allow saving if folder name exists NotificationCenter.default.addObserver( forName: UITextField.textDidBeginEditingNotification, @@ -262,10 +270,10 @@ extension UIAlertController { return alertController } - static func warning(title: String? = nil, message: String? = nil) -> UIAlertController { + static func warning(title: String? = nil, message: String? = nil, completion: @escaping () -> Void = {}) -> UIAlertController { let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) - let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default) + let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default) { _ in completion() } alertController.addAction(okAction) diff --git a/iOSClient/Main/NCDragDrop.swift b/iOSClient/Main/NCDragDrop.swift index 65e0c0e229..a423529575 100644 --- a/iOSClient/Main/NCDragDrop.swift +++ b/iOSClient/Main/NCDragDrop.swift @@ -88,6 +88,32 @@ class NCDragDrop: NSObject { } } + var invalidNameIndexes: [Int] = [] + let session = NCSession.shared.getSession(controller: controller) + + for (index, metadata) in metadatas.enumerated() { + if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileName, account: session.account) { + if metadatas.count == 1 { + let alert = UIAlertController.renameFile(fileName: metadata.fileName, account: session.account) { newFileName in + metadatas[index].fileName = newFileName + metadatas[index].fileNameView = newFileName + +// return metadatas + } + + controller?.present(alert, animated: true) + return nil + } else { + controller?.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) + invalidNameIndexes.append(index) + } + } + } + + for index in invalidNameIndexes.reversed() { + metadatas.remove(at: index) + } + if metadatas.isEmpty { return nil } else { @@ -101,8 +127,15 @@ class NCDragDrop: NSObject { Task { let ocId = NSUUID().uuidString let session = NCSession.shared.getSession(controller: controller) - let fileName = await NCNetworking.shared.createFileName(fileNameBase: url.lastPathComponent, account: session.account, serverUrl: serverUrl) - let fileNamePath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName) + let newFileName = FileAutoRenamer.shared.rename(url.lastPathComponent, account: session.account) + let fileNamePath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: newFileName) + + if let fileNameError = FileNameValidator.shared.checkFileName(newFileName, account: session.account) { + await controller?.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) + return + } + + let fileName = await NCNetworking.shared.createFileName(fileNameBase: newFileName, account: session.account, serverUrl: serverUrl) try data.write(to: URL(fileURLWithPath: fileNamePath)) diff --git a/iOSClient/Main/NCPickerViewController.swift b/iOSClient/Main/NCPickerViewController.swift index 8c413db174..42f806ab28 100644 --- a/iOSClient/Main/NCPickerViewController.swift +++ b/iOSClient/Main/NCPickerViewController.swift @@ -135,9 +135,9 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { let session = NCSession.shared.getSession(controller: self.controller) if isViewerMedia, - let urlIn = urls.first, - let url = self.copySecurityScopedResource(url: urlIn, urlOut: FileManager.default.temporaryDirectory.appendingPathComponent(urlIn.lastPathComponent)), - let viewController = self.viewController { + let urlIn = urls.first, + let url = self.copySecurityScopedResource(url: urlIn, urlOut: FileManager.default.temporaryDirectory.appendingPathComponent(urlIn.lastPathComponent)), + let viewController = self.viewController { let ocId = NSUUID().uuidString let fileName = url.lastPathComponent let metadata = database.createMetadata(fileName: fileName, @@ -154,7 +154,7 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { } if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileNameView, account: self.controller.account) { - controller.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) + self.controller.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) } else { database.addMetadata(metadata) NCViewer().view(viewController: viewController, metadata: metadata) @@ -167,15 +167,16 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { for urlIn in urls { let ocId = NSUUID().uuidString - let fileName = urlIn.lastPathComponent - let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName) + let newFileName = FileAutoRenamer.shared.rename(fileName, account: session.account) + + let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: newFileName) let urlOut = URL(fileURLWithPath: toPath) guard self.copySecurityScopedResource(url: urlIn, urlOut: urlOut) != nil else { continue } - let metadataForUpload = database.createMetadata(fileName: fileName, - fileNameView: fileName, + let metadataForUpload = database.createMetadata(fileName: newFileName, + fileNameView: newFileName, ocId: ocId, serverUrl: serverUrl, url: "", @@ -183,11 +184,6 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { session: session, sceneIdentifier: self.controller.sceneIdentifier) - if let fileNameError = FileNameValidator.shared.checkFileName(metadataForUpload.fileNameView, account: self.controller.account) { - controller.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) - continue - } - metadataForUpload.session = NCNetworking.shared.sessionUploadBackground metadataForUpload.sessionSelector = NCGlobal.shared.selectorUploadFile metadataForUpload.size = utilityFileSystem.getFileSize(filePath: toPath) @@ -201,6 +197,31 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate { } } + var invalidNameIndexes: [Int] = [] + + for (index, metadata) in metadatas.enumerated() { + if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileName, account: session.account) { + if metadatas.count == 1 { + let alert = UIAlertController.renameFile(fileName: metadata.fileName, account: session.account) { newFileName in + metadatas[index].fileName = newFileName + metadatas[index].fileNameView = newFileName + + NCNetworkingProcess.shared.createProcessUploads(metadatas: metadatas) + } + + self.controller.present(alert, animated: true) + return + } else { + self.controller.present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true) + invalidNameIndexes.append(index) + } + } + } + + for index in invalidNameIndexes.reversed() { + metadatas.remove(at: index) + } + NCNetworkingProcess.shared.createProcessUploads(metadatas: metadatas) if !metadatasInConflict.isEmpty { diff --git a/iOSClient/Scan document/NCUploadScanDocument.swift b/iOSClient/Scan document/NCUploadScanDocument.swift index 8ca8d9fa72..450d1e53a1 100644 --- a/iOSClient/Scan document/NCUploadScanDocument.swift +++ b/iOSClient/Scan document/NCUploadScanDocument.swift @@ -382,7 +382,6 @@ struct UploadScanDocumentView: View { footer = fileNameError.errorDescription } else { footer = "" - } } } diff --git a/iOSClient/Utility/FileAutoRenamer+Extensions.swift b/iOSClient/Utility/FileAutoRenamer+Extensions.swift new file mode 100644 index 0000000000..a0c6dc0b70 --- /dev/null +++ b/iOSClient/Utility/FileAutoRenamer+Extensions.swift @@ -0,0 +1,21 @@ +// +// FileAutoRenamer+Extensions.swift +// Nextcloud +// +// Created by Milen Pivchev on 10.10.24. +// Copyright © 2024 Marino Faggiana. All rights reserved. +// + +import NextcloudKit + +extension FileAutoRenamer { + private func setup(account: String?) { + let capabilities = NCCapabilities.shared.getCapabilities(account: account) + FileAutoRenamer.shared.setup(forbiddenFileNameCharacters: capabilities.capabilityForbiddenFileNameCharacters, forbiddenFileNameExtensions: capabilities.capabilityForbiddenFileNameExtensions) + } + + func rename(_ filename: String, isFolderPath: Bool = false, account: String?) -> String { + setup(account: account) + return FileAutoRenamer.shared.rename(filename: filename, isFolderPath: isFolderPath) + } +} diff --git a/iOSClient/Utility/FileNameValidator+Extensions.swift b/iOSClient/Utility/FileNameValidator+Extensions.swift index 0de7a271e7..166bf157b9 100644 --- a/iOSClient/Utility/FileNameValidator+Extensions.swift +++ b/iOSClient/Utility/FileNameValidator+Extensions.swift @@ -6,9 +6,7 @@ // Copyright © 2024 Marino Faggiana. All rights reserved. // -import Foundation import NextcloudKit -import UIKit extension FileNameValidator { private func setup(account: String?) {