Skip to content

Commit

Permalink
Auto rename (#3118)
Browse files Browse the repository at this point in the history
* WIP

Signed-off-by: Milen Pivchev <[email protected]>

* WIP

Signed-off-by: Milen Pivchev <[email protected]>

* Add files implementation

Signed-off-by: Milen Pivchev <[email protected]>

* WIP

Signed-off-by: Milen Pivchev <[email protected]>

* Finish drag and drop

Signed-off-by: Milen Pivchev <[email protected]>

---------

Signed-off-by: Milen Pivchev <[email protected]>
  • Loading branch information
mpivchev authored Nov 4, 2024
1 parent 5ca90c7 commit 6e67bbd
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 43 deletions.
20 changes: 18 additions & 2 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -1204,6 +1211,7 @@
F37208742BAB4AB0006B5430 /* TestConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestConstants.swift; sourceTree = "<group>"; };
F37208772BAB4B5D006B5430 /* BaseXCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseXCTestCase.swift; sourceTree = "<group>"; };
F38F71242B6BBDC300473CDC /* NCCollectionViewCommonSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCollectionViewCommonSelectTabBar.swift; sourceTree = "<group>"; };
F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileAutoRenamer+Extensions.swift"; sourceTree = "<group>"; };
F39298962A3B12CB00509762 /* BaseNCMoreCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseNCMoreCell.swift; sourceTree = "<group>"; };
F3953BD62A6E87E000EE03F9 /* BaseIntegrationXCTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseIntegrationXCTestCase.swift; sourceTree = "<group>"; };
F3998E192B4879B2007CA5DE /* CoreAudioTypes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioTypes.framework; path = System/Library/Frameworks/CoreAudioTypes.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -2849,6 +2857,7 @@
F7245923289BB50B00474787 /* ThreadSafeDictionary.swift */,
F33EE6F12BF4C9B200CA1A51 /* PKCS12.swift */,
F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */,
F39170A82CB8201B006127BC /* FileAutoRenamer+Extensions.swift */,
);
path = Utility;
sourceTree = "<group>";
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand All @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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" */ = {
Expand Down
5 changes: 3 additions & 2 deletions Share/NCShareCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Share/NCShareExtension+DataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
22 changes: 13 additions & 9 deletions Share/NCShareExtension+NCAccountRequestDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
45 changes: 36 additions & 9 deletions Share/NCShareExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -320,6 +344,8 @@ extension NCShareExtension {
}
}

tableView.reloadData()

if !conflicts.isEmpty {
guard let conflict = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict
else { return }
Expand All @@ -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)

Expand Down Expand Up @@ -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 - ")
Expand Down
12 changes: 10 additions & 2 deletions iOSClient/Extensions/UIAlertController+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)

Expand Down
37 changes: 35 additions & 2 deletions iOSClient/Main/NCDragDrop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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))

Expand Down
Loading

0 comments on commit 6e67bbd

Please sign in to comment.