From c2069c5910d2c007dee0e5c4e35c8215817ff00c Mon Sep 17 00:00:00 2001 From: TSI-amrutwaghmare <96108296+TSI-amrutwaghmare@users.noreply.github.com> Date: Mon, 23 Oct 2023 16:49:46 +0530 Subject: [PATCH] NMC 2261 - Audio record and upload customisation --- .../NextcloudUnitTests/AudioUploadTests.swift | 52 ++++++++++ .../NCAudioRecorderViewController.swift | 4 +- .../Create cloud/FolderPathCustomCell.swift | 33 +++++++ .../Create cloud/FolderPathCustomCell.xib | 74 ++++++++++++++ .../NCCreateFormUploadVoiceNote.storyboard | 98 +++++++++---------- .../NCCreateFormUploadVoiceNote.swift | 68 +++++++------ .../Main/Create cloud/TextTableViewCell.swift | 94 ++++++++++++++++++ .../Main/Create cloud/TextTableViewCell.xib | 82 ++++++++++++++++ 8 files changed, 426 insertions(+), 79 deletions(-) create mode 100644 Tests/NextcloudUnitTests/AudioUploadTests.swift create mode 100644 iOSClient/Main/Create cloud/FolderPathCustomCell.swift create mode 100644 iOSClient/Main/Create cloud/FolderPathCustomCell.xib create mode 100644 iOSClient/Main/Create cloud/TextTableViewCell.swift create mode 100644 iOSClient/Main/Create cloud/TextTableViewCell.xib diff --git a/Tests/NextcloudUnitTests/AudioUploadTests.swift b/Tests/NextcloudUnitTests/AudioUploadTests.swift new file mode 100644 index 0000000000..2ea01a8085 --- /dev/null +++ b/Tests/NextcloudUnitTests/AudioUploadTests.swift @@ -0,0 +1,52 @@ +// +// AudioUploadTests.swift +// NextcloudTests +// +// Created by A200020526 on 13/06/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +import XCTest +@testable import Nextcloud + +final class AudioUploadTests: XCTestCase { + var viewController:NCAudioRecorderViewController? + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + // Step 1. Create an instance of UIStoryboard + let viewController = UIStoryboard(name: "NCAudioRecorderViewController", bundle: nil).instantiateInitialViewController() as? NCAudioRecorderViewController + // Step 3. Make the viewDidLoad() execute. + viewController?.loadViewIfNeeded() + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + viewController = nil + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + + func testAudioMeterUpdateAfterDb(){ + viewController?.audioMeterDidUpdate(0.5) + XCTAssertNotNil(!(viewController?.durationLabel.text?.isEmpty ?? false)) + } + + func testStartRecorder(){ + viewController?.startStop() + XCTAssertEqual(viewController?.recording.state, nil, "Test start audio recorder") + } +} diff --git a/iOSClient/Main/AudioRecorder/NCAudioRecorderViewController.swift b/iOSClient/Main/AudioRecorder/NCAudioRecorderViewController.swift index bdd2b9e393..2051875d56 100644 --- a/iOSClient/Main/AudioRecorder/NCAudioRecorderViewController.swift +++ b/iOSClient/Main/AudioRecorder/NCAudioRecorderViewController.swift @@ -56,7 +56,7 @@ class NCAudioRecorderViewController: UIViewController, NCAudioRecorderDelegate { view.backgroundColor = .clear contentContainerView.backgroundColor = UIColor.lightGray - voiceRecordHUD.fillColor = UIColor.green + voiceRecordHUD.fillColor = NCBrandColor.shared.progressColorGreen60 } override func viewWillAppear(_ animated: Bool) { @@ -142,7 +142,7 @@ class NCAudioRecorderViewController: UIViewController, NCAudioRecorderDelegate { } voiceRecordHUD.update(CGFloat(rate)) - voiceRecordHUD.fillColor = UIColor.green + voiceRecordHUD.fillColor = NCBrandColor.shared.progressColorGreen60 let formatter = DateComponentsFormatter() formatter.allowedUnits = [.second] diff --git a/iOSClient/Main/Create cloud/FolderPathCustomCell.swift b/iOSClient/Main/Create cloud/FolderPathCustomCell.swift new file mode 100644 index 0000000000..b7ba63f9ef --- /dev/null +++ b/iOSClient/Main/Create cloud/FolderPathCustomCell.swift @@ -0,0 +1,33 @@ +// +// FolderPathCustomCell.swift +// Nextcloud +// +// Created by Sumit on 28/04/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import Foundation + +class FolderPathCustomCell: XLFormButtonCell{ + + @IBOutlet weak var photoLabel: UILabel! + @IBOutlet weak var folderImage: UIImageView! + @IBOutlet weak var bottomLineView: UIView! + + override func awakeFromNib() { + super.awakeFromNib() + } + + override func configure() { + super.configure() + } + + override func update() { + super.update() + if (rowDescriptor.tag == "PhotoButtonDestinationFolder"){ + bottomLineView.isHidden = true + }else{ + bottomLineView.isHidden = false + } + } +} diff --git a/iOSClient/Main/Create cloud/FolderPathCustomCell.xib b/iOSClient/Main/Create cloud/FolderPathCustomCell.xib new file mode 100644 index 0000000000..a231ae7c72 --- /dev/null +++ b/iOSClient/Main/Create cloud/FolderPathCustomCell.xib @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.storyboard b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.storyboard index 477b8d940c..1b5344ccee 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.storyboard +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.storyboard @@ -1,107 +1,107 @@ - + - + - + - - + + - - + + - - + + - - - + - - - - - - - - - - - - - + + + + + + + + + + + + + - + - - - - - + + + + + - + - + - + - - + + - + - + diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift index 716c903714..a4bfae419e 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift @@ -54,6 +54,8 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_cancel_", comment: ""), style: UIBarButtonItem.Style.plain, target: self, action: #selector(cancel)) self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_save_", comment: ""), style: UIBarButtonItem.Style.plain, target: self, action: #selector(save)) + self.navigationItem.leftBarButtonItem?.tintColor = NCBrandColor.shared.brand + self.navigationItem.rightBarButtonItem?.tintColor = NCBrandColor.shared.brand self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none @@ -64,12 +66,15 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud self.title = NSLocalizedString("_voice_memo_title_", comment: "") // Button Play Stop - buttonPlayStop.setImage(UIImage(named: "audioPlay")!.image(color: UIColor.systemGray, size: 100), for: .normal) + buttonPlayStop.setImage(UIImage(named: "audioPlay")!.image(color: NCBrandColor.shared.iconColor, size: 100), for: .normal) // Progress view progressView.progress = 0 - progressView.progressTintColor = .green - progressView.trackTintColor = UIColor(red: 247.0 / 255.0, green: 247.0 / 255.0, blue: 247.0 / 255.0, alpha: 1.0) + progressView.progressTintColor = NCBrandColor.shared.customer + progressView.trackTintColor = .white + progressView.layer.borderWidth = 1 + progressView.layer.cornerRadius = 5.0 + progressView.layer.borderColor = NCBrandColor.shared.customer.cgColor labelTimer.textColor = .label labelDuration.textColor = .label @@ -127,36 +132,40 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud // Section: Destination Folder section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_save_path_", comment: "").uppercased()) + section.footerTitle = "" form.addFormSection(section) - row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: XLFormRowDescriptorTypeButton, title: self.titleServerUrl) - row.action.formSelector = #selector(changeDestinationFolder(_:)) - row.cellConfig["backgroundColor"] = cellBackgoundColor - - row.cellConfig["imageView.image"] = UIImage(named: "folder")!.image(color: NCBrandColor.shared.brandElement, size: 25) - - row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.right.rawValue - row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0) - row.cellConfig["textLabel.textColor"] = UIColor.label + XLFormViewController.cellClassesForRowDescriptorTypes()["kNMCFolderCustomCellType"] = FolderPathCustomCell.self + row = XLFormRowDescriptor(tag: "ButtonDestinationFolder", rowType: "kNMCFolderCustomCellType", title: self.titleServerUrl) + row.cellConfig["backgroundColor"] = UIColor.secondarySystemGroupedBackground + row.action.formSelector = #selector(changeDestinationFolder(_:)) + row.cellConfig["folderImage.image"] = UIImage(named: "folder_nmcloud")?.image(color: NCBrandColor.shared.brandElement, size: 25) + row.cellConfig["photoLabel.textAlignment"] = NSTextAlignment.right.rawValue + row.cellConfig["photoLabel.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["photoLabel.textColor"] = UIColor.label //photos + if(self.titleServerUrl == "/"){ + row.cellConfig["photoLabel.text"] = NSLocalizedString("_prefix_upload_path_", comment: "") + }else{ + row.cellConfig["photoLabel.text"] = self.titleServerUrl + } + row.cellConfig["textLabel.text"] = "" section.addFormRow(row) // Section: File Name + XLFormViewController.cellClassesForRowDescriptorTypes()["kMyAppCustomCellType"] = TextTableViewCell.self + section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_filename_", comment: "").uppercased()) form.addFormSection(section) - row = XLFormRowDescriptor(tag: "fileName", rowType: XLFormRowDescriptorTypeText, title: NSLocalizedString("_filename_", comment: "")) - row.value = self.fileName - row.cellConfig["backgroundColor"] = cellBackgoundColor - - row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0) - row.cellConfig["textLabel.textColor"] = UIColor.label - - row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue - row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 15.0) - row.cellConfig["textField.textColor"] = UIColor.label - + row = XLFormRowDescriptor(tag: "fileName", rowType: "kMyAppCustomCellType", title: NSLocalizedString("_filename_", comment: "")) + row.cellClass = TextTableViewCell.self + row.cellConfigAtConfigure["backgroundColor"] = UIColor.secondarySystemGroupedBackground; + row.cellConfig["fileNameTextField.textAlignment"] = NSTextAlignment.left.rawValue + row.cellConfig["fileNameTextField.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["fileNameTextField.textColor"] = UIColor.label + row.cellConfig["fileNameTextField.text"] = self.fileName section.addFormRow(row) self.form = form @@ -174,8 +183,6 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud self.fileName = CCUtility.removeForbiddenCharactersServer(fileNameNew as? String) } - formRow.value = self.fileName - self.updateFormRow(formRow) self.form.delegate = self } @@ -206,7 +213,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud // Update let row: XLFormRowDescriptor = self.form.formRow(withTag: "ButtonDestinationFolder")! - row.title = self.titleServerUrl + row.cellConfig["photoLabel.text"] = self.titleServerUrl self.updateFormRow(row) } } @@ -214,7 +221,12 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud @objc func save() { let rowFileName: XLFormRowDescriptor = self.form.formRow(withTag: "fileName")! - guard let name = rowFileName.value as? String else { return } + guard let name = (rowFileName.value as? String)?.trimmingCharacters(in: .whitespaces) else { + let alert = UIAlertController(title: "", message: NSLocalizedString("_prompt_insert_file_name", comment: ""), preferredStyle: .alert) + alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .cancel, handler: nil)) + self.present(alert, animated: true) + return + } let ext = (name as NSString).pathExtension.uppercased() var fileNameSave = "" @@ -250,7 +262,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) { - if let metadatas { + if let metadatas, metadatas.count > 0 { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.dismissAndUpload(metadatas[0]) } diff --git a/iOSClient/Main/Create cloud/TextTableViewCell.swift b/iOSClient/Main/Create cloud/TextTableViewCell.swift new file mode 100644 index 0000000000..11116a2ff5 --- /dev/null +++ b/iOSClient/Main/Create cloud/TextTableViewCell.swift @@ -0,0 +1,94 @@ +// +// TextTableViewCell.swift +// Nextcloud +// +// Created by Ashu on 23/04/21. +// Copyright © 2021 Marino Faggiana. All rights reserved. +// + +import UIKit + +class TextTableViewCell: XLFormBaseCell, UITextFieldDelegate { + + @IBOutlet weak var fileNameTextField: UITextField! + @IBOutlet weak var topLineView: UIView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + + fileNameTextField.delegate = self + topLineView.backgroundColor = UIColor.secondarySystemBackground + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + override func configure() { + super.configure() + } + + override func update() { + super.update() + if (rowDescriptor.tag == "maskFileName"){ + topLineView.isHidden = true + }else{ + topLineView.isHidden = false + } + + fileNameTextField.tintColor = UIColor.systemGray + fileNameTextField.selectedTextRange = fileNameTextField.textRange(from: fileNameTextField.beginningOfDocument, to: fileNameTextField.endOfDocument) + } + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + + if fileNameTextField == textField { + if let rowDescriptor = rowDescriptor, let text = self.fileNameTextField.text { + + if (text + " ").isEmpty == false { + rowDescriptor.value = self.fileNameTextField.text! + string + } else { + rowDescriptor.value = nil + } + } + } + + self.formViewController().textField(textField, shouldChangeCharactersIn: range, replacementString: string) + + return true + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldReturn(fileNameTextField) + return true + } + + func textFieldShouldClear(_ textField: UITextField) -> Bool { + self.formViewController()?.textFieldShouldClear(fileNameTextField) + rowDescriptor.value = nil + + self.formViewController().textField(textField, shouldChangeCharactersIn: NSRange.init().self, replacementString: "") + return true + } + + override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat { + return 45 + } +} + +extension UITextField { + @IBInspectable var placeholderColor: UIColor { + get { + return attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? .clear + } + set { + guard let attributedPlaceholder = attributedPlaceholder else { return } + let attributes: [NSAttributedString.Key: UIColor] = [.foregroundColor: newValue] + self.attributedPlaceholder = NSAttributedString(string: attributedPlaceholder.string, attributes: attributes) + } + } +} diff --git a/iOSClient/Main/Create cloud/TextTableViewCell.xib b/iOSClient/Main/Create cloud/TextTableViewCell.xib new file mode 100644 index 0000000000..e4be37d230 --- /dev/null +++ b/iOSClient/Main/Create cloud/TextTableViewCell.xib @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +