diff --git a/Package.swift b/Package.swift index 2b920178afe74017dacd2c1029d75211267f7ea7..3bc8363f52ec3a8a43c913ae95e0a02a3bad3d55 100644 --- a/Package.swift +++ b/Package.swift @@ -215,7 +215,8 @@ let package = Package( .target( name: "SFTPFeature", dependencies: [ - + "Shared", + "InputField" ] ), diff --git a/Sources/App/DependencyRegistrator.swift b/Sources/App/DependencyRegistrator.swift index 776a17b10af562e1b4aadc0e1e7305db8bf52c78..4ad75419d54accc4c3e9b8bc15eb7f4b249d0e33 100644 --- a/Sources/App/DependencyRegistrator.swift +++ b/Sources/App/DependencyRegistrator.swift @@ -161,6 +161,7 @@ struct DependencyRegistrator { container.register( RestoreCoordinator( + sftpFactory: SFTPController.init, successFactory: RestoreSuccessController.init, chatListFactory: ChatListController.init, restoreFactory: RestoreController.init(_:_:), diff --git a/Sources/RestoreFeature/Controllers/RestoreListController.swift b/Sources/RestoreFeature/Controllers/RestoreListController.swift index 68a5edcaf45b7f3d052d2fee89322c0b1f5d93e9..4588630a1bc561ac5abd0c17a2c2ab07e8076850 100644 --- a/Sources/RestoreFeature/Controllers/RestoreListController.swift +++ b/Sources/RestoreFeature/Controllers/RestoreListController.swift @@ -58,8 +58,9 @@ public final class RestoreListController: UIViewController { viewModel.didFetchBackup .receive(on: DispatchQueue.main) - .sink { [unowned self] in coordinator.toRestore(using: ndf, with: $0, from: self) } - .store(in: &cancellables) + .sink { [unowned self] in + coordinator.toRestore(using: ndf, with: $0, from: self) + }.store(in: &cancellables) screenView.cancelButton .publisher(for: .touchUpInside) @@ -68,23 +69,27 @@ public final class RestoreListController: UIViewController { screenView.driveButton .publisher(for: .touchUpInside) - .sink { [unowned self] in viewModel.didTapCloud(.drive, from: self) } - .store(in: &cancellables) + .sink { [unowned self] in + viewModel.didTapCloud(.drive, from: self) + }.store(in: &cancellables) screenView.icloudButton .publisher(for: .touchUpInside) - .sink { [unowned self] in viewModel.didTapCloud(.icloud, from: self) } - .store(in: &cancellables) + .sink { [unowned self] in + viewModel.didTapCloud(.icloud, from: self) + }.store(in: &cancellables) screenView.dropboxButton .publisher(for: .touchUpInside) - .sink { [unowned self] in viewModel.didTapCloud(.dropbox, from: self) } - .store(in: &cancellables) + .sink { [unowned self] in + viewModel.didTapCloud(.dropbox, from: self) + }.store(in: &cancellables) screenView.sftpButton .publisher(for: .touchUpInside) - .sink { [unowned self] in viewModel.didTapCloud(.sftp, from: self) } - .store(in: &cancellables) + .sink { [unowned self] in + coordinator.toSFTP(from: self) //viewModel.didTapCloud(.sftp, from: self) + }.store(in: &cancellables) } @objc private func didTapBack() { diff --git a/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift b/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift index 2183035bca4a57ee9fd4435b2656fed7123de814..3a63883c13726d9c398f270534760ffcc0c98d21 100644 --- a/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift +++ b/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift @@ -4,6 +4,7 @@ import Shared import Presentation public protocol RestoreCoordinating { + func toSFTP(from: UIViewController) func toChats(from: UIViewController) func toSuccess(from: UIViewController) func toDrawer(_: UIViewController, from: UIViewController) @@ -16,17 +17,20 @@ public struct RestoreCoordinator: RestoreCoordinating { var bottomPresenter: Presenting = BottomPresenter() var replacePresenter: Presenting = ReplacePresenter() + var sftpFactory: () -> UIViewController var successFactory: () -> UIViewController var chatListFactory: () -> UIViewController var restoreFactory: (String, RestoreSettings) -> UIViewController var passphraseFactory: (@escaping StringClosure) -> UIViewController public init( + sftpFactory: @escaping () -> UIViewController, successFactory: @escaping () -> UIViewController, chatListFactory: @escaping () -> UIViewController, restoreFactory: @escaping (String, RestoreSettings) -> UIViewController, passphraseFactory: @escaping (@escaping StringClosure) -> UIViewController ) { + self.sftpFactory = sftpFactory self.successFactory = successFactory self.restoreFactory = restoreFactory self.chatListFactory = chatListFactory @@ -65,4 +69,9 @@ public extension RestoreCoordinator { let screen = passphraseFactory(completion) bottomPresenter.present(screen, from: parent) } + + func toSFTP(from parent: UIViewController) { + let screen = sftpFactory() + pushPresenter.present(screen, from: parent) + } } diff --git a/Sources/SFTPFeature/SFTPController.swift b/Sources/SFTPFeature/SFTPController.swift index 332d7079e6be9d77061a0b499a41878746d6897e..5ccb14adf258de9650a38aec59262ee43173dff3 100644 --- a/Sources/SFTPFeature/SFTPController.swift +++ b/Sources/SFTPFeature/SFTPController.swift @@ -1,8 +1,29 @@ -// -// File.swift -// -// -// Created by Bruno Muniz on 6/30/22. -// - -import Foundation +import UIKit + +public final class SFTPController: UIViewController { + lazy private var screenView = SFTPView() + + public override func loadView() { + view = screenView + } + + public override func viewDidLoad() { + super.viewDidLoad() + setupNavigationBar() + } + + private func setupNavigationBar() { + navigationItem.backButtonTitle = "" + + let back = UIButton.back() + back.addTarget(self, action: #selector(didTapBack), for: .touchUpInside) + + navigationItem.leftBarButtonItem = UIBarButtonItem( + customView: UIStackView(arrangedSubviews: [back]) + ) + } + + @objc private func didTapBack() { + navigationController?.popViewController(animated: true) + } +} diff --git a/Sources/SFTPFeature/SFTPView.swift b/Sources/SFTPFeature/SFTPView.swift new file mode 100644 index 0000000000000000000000000000000000000000..83ba070d1eaba8a7f4bb5f567d3fc212b6262f30 --- /dev/null +++ b/Sources/SFTPFeature/SFTPView.swift @@ -0,0 +1,88 @@ +import UIKit +import Shared +import InputField + +final class SFTPView: UIView { + let titleLabel = UILabel() + let subtitleLabel = UILabel() + let hostField = InputField() + let usernameField = InputField() + let passwordField = InputField() + let loginButton = CapsuleButton() + let stackView = UIStackView() + + init() { + super.init(frame: .zero) + backgroundColor = Asset.neutralWhite.color + + titleLabel.textColor = Asset.neutralDark.color + titleLabel.text = Localized.AccountRestore.Sftp.title + titleLabel.font = Fonts.Mulish.bold.font(size: 24.0) + + let paragraph = NSMutableParagraphStyle() + paragraph.alignment = .left + paragraph.lineHeightMultiple = 1.15 + + let attString = NSAttributedString( + string: Localized.AccountRestore.Sftp.subtitle, + attributes: [ + .foregroundColor: Asset.neutralBody.color, + .font: Fonts.Mulish.regular.font(size: 16.0) as Any, + .paragraphStyle: paragraph + ]) + + subtitleLabel.numberOfLines = 0 + subtitleLabel.attributedText = attString + + hostField.setup( + style: .regular, + placeholder: Localized.AccountRestore.Sftp.host + ) + + usernameField.setup( + style: .regular, + placeholder: Localized.AccountRestore.Sftp.username + ) + + passwordField.setup( + style: .regular, + placeholder: Localized.AccountRestore.Sftp.password, + rightView: .toggleSecureEntry + ) + + loginButton.set(style: .brandColored, title: Localized.AccountRestore.Sftp.login) + + stackView.spacing = 30 + stackView.axis = .vertical + stackView.distribution = .fillEqually + stackView.addArrangedSubview(hostField) + stackView.addArrangedSubview(usernameField) + stackView.addArrangedSubview(passwordField) + stackView.addArrangedSubview(loginButton) + + addSubview(titleLabel) + addSubview(subtitleLabel) + addSubview(stackView) + + titleLabel.snp.makeConstraints { + $0.top.equalTo(safeAreaLayoutGuide).offset(15) + $0.left.equalToSuperview().offset(38) + $0.right.equalToSuperview().offset(-41) + } + + subtitleLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(8) + $0.left.equalToSuperview().offset(38) + $0.right.equalToSuperview().offset(-41) + } + + stackView.snp.makeConstraints { + $0.top.equalTo(subtitleLabel.snp.bottom).offset(28) + $0.left.equalToSuperview().offset(38) + $0.right.equalToSuperview().offset(-38) + $0.bottom.lessThanOrEqualToSuperview() + } + } + + required init?(coder: NSCoder) { nil } +} diff --git a/Sources/Shared/AutoGenerated/Strings.swift b/Sources/Shared/AutoGenerated/Strings.swift index 26455e8689ac10078ac41cc5ccc8feb24d1bb835..7a9d630ba3dd810978900603ae63e8deb3168c37 100644 --- a/Sources/Shared/AutoGenerated/Strings.swift +++ b/Sources/Shared/AutoGenerated/Strings.swift @@ -211,6 +211,20 @@ public enum Localized { /// Backup not found public static let title = Localized.tr("Localizable", "accountRestore.notFound.title") } + public enum Sftp { + /// Host + public static let host = Localized.tr("Localizable", "accountRestore.sftp.host") + /// Login + public static let login = Localized.tr("Localizable", "accountRestore.sftp.login") + /// Password + public static let password = Localized.tr("Localizable", "accountRestore.sftp.password") + /// Login to your server. Your credentials will be automatically and securley saved locally on your device. + public static let subtitle = Localized.tr("Localizable", "accountRestore.sftp.subtitle") + /// Login to your SFTP + public static let title = Localized.tr("Localizable", "accountRestore.sftp.title") + /// Username + public static let username = Localized.tr("Localizable", "accountRestore.sftp.username") + } public enum Success { /// You now have access to all your contacts. public static let subtitle = Localized.tr("Localizable", "accountRestore.success.subtitle") diff --git a/Sources/Shared/Resources/en.lproj/Localizable.strings b/Sources/Shared/Resources/en.lproj/Localizable.strings index 7b68750b8d5018d2067245a01698fb67ec95df02..455683161b0aa9fb2145dad2df0ae30ee89aa4f3 100644 --- a/Sources/Shared/Resources/en.lproj/Localizable.strings +++ b/Sources/Shared/Resources/en.lproj/Localizable.strings @@ -831,6 +831,19 @@ "accountRestore.list.cancel" = "Cancel"; +"accountRestore.sftp.title" += "Login to your SFTP"; +"accountRestore.sftp.subtitle" += "Login to your server. Your credentials will be automatically and securley saved locally on your device."; +"accountRestore.sftp.host" += "Host"; +"accountRestore.sftp.username" += "Username"; +"accountRestore.sftp.password" += "Password"; +"accountRestore.sftp.login" += "Login"; + "accountRestore.header" = "Account restore"; "accountRestore.found.title"