diff --git a/gaios.xcodeproj/project.pbxproj b/gaios.xcodeproj/project.pbxproj index fa474a64f..66b6b60a3 100644 --- a/gaios.xcodeproj/project.pbxproj +++ b/gaios.xcodeproj/project.pbxproj @@ -560,6 +560,9 @@ 34FF27A527C7E5A7008FD72C /* DialogReceiveMoreOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34FF27A427C7E5A7008FD72C /* DialogReceiveMoreOptions.swift */; }; 34FF27AE27CCE926008FD72C /* DialogCustomFee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34FF27AD27CCE926008FD72C /* DialogCustomFee.swift */; }; 34FF27B027CD0689008FD72C /* DialogMnemonicLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34FF27AF27CD0689008FD72C /* DialogMnemonicLength.swift */; }; + 586EB69D2EFB1EF200DFAEF6 /* AutoLogoutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586EB69C2EFB1EEB00DFAEF6 /* AutoLogoutCell.swift */; }; + 586EB69F2EFB1EFC00DFAEF6 /* AutoLogoutCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586EB69E2EFB1EF400DFAEF6 /* AutoLogoutCellModel.swift */; }; + 586EB6A52EFB223300DFAEF6 /* AutoLogoutCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 586EB6A42EFB223300DFAEF6 /* AutoLogoutCell.xib */; }; 6713533921E23E7200A9ACC0 /* QRCodeReaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6713533821E23E7200A9ACC0 /* QRCodeReaderView.swift */; }; 671FC43021DBABCD0047AF8E /* MnemonicWordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671FC42F21DBABCD0047AF8E /* MnemonicWordCell.swift */; }; 67439CD921D92AEA00280FE2 /* KeyboardSuggestions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 67439CD821D92AEA00280FE2 /* KeyboardSuggestions.xib */; }; @@ -1579,6 +1582,9 @@ 34FF27A427C7E5A7008FD72C /* DialogReceiveMoreOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogReceiveMoreOptions.swift; sourceTree = ""; }; 34FF27AD27CCE926008FD72C /* DialogCustomFee.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogCustomFee.swift; sourceTree = ""; }; 34FF27AF27CD0689008FD72C /* DialogMnemonicLength.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogMnemonicLength.swift; sourceTree = ""; }; + 586EB69C2EFB1EEB00DFAEF6 /* AutoLogoutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoLogoutCell.swift; sourceTree = ""; }; + 586EB69E2EFB1EF400DFAEF6 /* AutoLogoutCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoLogoutCellModel.swift; sourceTree = ""; }; + 586EB6A42EFB223300DFAEF6 /* AutoLogoutCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AutoLogoutCell.xib; sourceTree = ""; }; 6713533821E23E7200A9ACC0 /* QRCodeReaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeReaderView.swift; sourceTree = ""; }; 671FC42F21DBABCD0047AF8E /* MnemonicWordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicWordCell.swift; sourceTree = ""; }; 67439CD821D92AEA00280FE2 /* KeyboardSuggestions.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KeyboardSuggestions.xib; sourceTree = ""; }; @@ -2558,6 +2564,7 @@ 3457F4AF2923986D00EF33B5 /* Cells */ = { isa = PBXGroup; children = ( + 586EB6992EFB1D5000DFAEF6 /* AutoLogoutCell */, 342F980A29350788005876A8 /* DialogEnable2faCell */, 342F980929350773005876A8 /* DialogListCell */, ); @@ -3683,6 +3690,16 @@ path = DialogNode; sourceTree = ""; }; + 586EB6992EFB1D5000DFAEF6 /* AutoLogoutCell */ = { + isa = PBXGroup; + children = ( + 586EB6A42EFB223300DFAEF6 /* AutoLogoutCell.xib */, + 586EB69E2EFB1EF400DFAEF6 /* AutoLogoutCellModel.swift */, + 586EB69C2EFB1EEB00DFAEF6 /* AutoLogoutCell.swift */, + ); + path = AutoLogoutCell; + sourceTree = ""; + }; 676FCF131F9D0CF800354E93 = { isa = PBXGroup; children = ( @@ -4984,6 +5001,7 @@ 3484020C2DB8E7B200A91C65 /* BuyBTCFlow.storyboard in Resources */, 34C1A4C92E27A3F400CB83D4 /* AccountSettingsCell.xib in Resources */, 344D57CC2D71B5B5009725A3 /* WalletTab.storyboard in Resources */, + 586EB6A52EFB223300DFAEF6 /* AutoLogoutCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5145,6 +5163,7 @@ 34C680EA2A72779900369639 /* DialogInputDenominationViewModel.swift in Sources */, 344D57CF2D71B5E7009725A3 /* TabTransactVC.swift in Sources */, 34465BA12D082EF7002E5033 /* GenuineCheckEndViewController.swift in Sources */, + 586EB69D2EFB1EF200DFAEF6 /* AutoLogoutCell.swift in Sources */, 6D0983C623FC848C00289ACA /* HelpCell.swift in Sources */, 8173B8F22AB1B10C00C15C85 /* DialogViewController.swift in Sources */, 3497936C25F8B18C0029ECB1 /* StrokeColorAnimation.swift in Sources */, @@ -5404,6 +5423,7 @@ 34580EB126FCB78D00D3BEFC /* UITableView.swift in Sources */, 34DA78A62D807F3F0022FBB1 /* DialogAccountsViewController.swift in Sources */, 345402F72A20A6A7002CB598 /* LTAuthViewController.swift in Sources */, + 586EB69F2EFB1EFC00DFAEF6 /* AutoLogoutCellModel.swift in Sources */, 34742D3E2CE4AB670064F327 /* AssetToBuyCell.swift in Sources */, 348A71062D8AE02C00490B55 /* WelcomeView.swift in Sources */, 34FB697727FEF9D000A13197 /* AccountArchiveCell.swift in Sources */, diff --git a/gaios.xcodeproj/xcshareddata/xcschemes/gaios.xcscheme b/gaios.xcodeproj/xcshareddata/xcschemes/gaios.xcscheme index 2ae825a75..33e1e05dc 100644 --- a/gaios.xcodeproj/xcshareddata/xcschemes/gaios.xcscheme +++ b/gaios.xcodeproj/xcshareddata/xcschemes/gaios.xcscheme @@ -56,13 +56,13 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" disableMainThreadChecker = "YES" + disablePerformanceAntipatternChecker = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES" - disablePerformanceAntipatternChecker = "YES"> + allowLocationSimulation = "YES"> - - + + - + @@ -14,23 +14,23 @@ - + - + - + - + - + - + @@ -39,23 +39,23 @@ - + - + @@ -102,7 +102,7 @@ - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -832,6 +873,7 @@ + diff --git a/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift b/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift index b446fe7dd..88a3c054f 100644 --- a/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift +++ b/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift @@ -9,17 +9,18 @@ enum SelectCountrySection: CaseIterable { // case common case all } -class SelectCountryViewController: UIViewController { - +class SelectCountryViewController: KeyboardViewController { @IBOutlet weak var tappableBg: UIView! @IBOutlet weak var handle: UIView! - @IBOutlet weak var anchorBottom: NSLayoutConstraint! @IBOutlet weak var lblTitle: UILabel! + @IBOutlet weak var searchTextField: SearchTextField! + @IBOutlet weak var lblHint: UILabel! @IBOutlet weak var cardView: UIView! @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var tableView: UITableView! + @IBOutlet weak var anchorBottom: NSLayoutConstraint! weak var delegate: SelectCountryViewControllerDelegate? var viewModel: SelectCountryViewModel! @@ -38,6 +39,24 @@ class SelectCountryViewController: UIViewController { return containerView }() + override func keyboardWillShow(notification: Notification) { + super.keyboardWillShow(notification: notification) + guard + let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect + else { return } + + let bottomInset = frame.height - view.safeAreaInsets.bottom + + tableView.contentInset.bottom = bottomInset + tableView.verticalScrollIndicatorInsets.bottom = bottomInset + } + + override func keyboardWillHide(notification: Notification) { + super.keyboardWillHide(notification: notification) + tableView.contentInset.bottom = 0 + tableView.verticalScrollIndicatorInsets.bottom = 0 + } + override func viewDidLoad() { super.viewDidLoad() @@ -47,6 +66,14 @@ class SelectCountryViewController: UIViewController { view.addSubview(blurredView) view.sendSubviewToBack(blurredView) + searchTextField.padding = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 0) + + searchTextField.addTarget( + self, + action: #selector(searchFieldDidChange), + for: .editingChanged + ) + ["SelectCountryCell" ].forEach { tableView.register(UINib(nibName: $0, bundle: nil), forCellReuseIdentifier: $0) } @@ -61,8 +88,12 @@ class SelectCountryViewController: UIViewController { tappableBg.addGestureRecognizer(tapToClose) } - @objc func didSwipe(gesture: UIGestureRecognizer) { + @objc func searchFieldDidChange(_ textField: UITextField) { + viewModel?.searchCountries(textField.text ?? ""); + tableView.reloadData() + } + @objc func didSwipe(gesture: UIGestureRecognizer) { if let swipeGesture = gesture as? UISwipeGestureRecognizer { switch swipeGesture.direction { case .down: @@ -74,11 +105,12 @@ class SelectCountryViewController: UIViewController { } @objc func didTap(gesture: UIGestureRecognizer) { - dismiss(nil) } func setContent() { + searchTextField.text = ""; + searchTextField.placeholder = "id_search".localized; lblTitle.text = viewModel?.title ?? "" lblHint.text = viewModel?.hint ?? "" } @@ -106,7 +138,7 @@ class SelectCountryViewController: UIViewController { }, completion: { _ in self.dismiss(animated: false, completion: nil) if let indexPath = indexPath { - self.delegate?.didSelectCountry(self.viewModel.countries[indexPath.row]) + self.delegate?.didSelectCountry(self.viewModel.searchedCountries[indexPath.row]) } }) } @@ -122,12 +154,12 @@ extension SelectCountryViewController: UITableViewDelegate, UITableViewDataSourc } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return viewModel.countries.count + return viewModel.searchedCountries.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: SelectCountryCell.identifier, for: indexPath) as? SelectCountryCell { - let model = SelectCountryCellModel(country: viewModel.countries[indexPath.row]) + let model = SelectCountryCellModel(country: viewModel.searchedCountries[indexPath.row]) cell.configure(model: model, onTap: { [weak self] in self?.didSelect(indexPath) }) diff --git a/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift b/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift index 57f4ab73a..b15af3d89 100644 --- a/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift +++ b/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift @@ -2,10 +2,22 @@ import Foundation import UIKit class SelectCountryViewModel { + var title = "id_billing".localized + var hint = "id_please_select_your_correct".localized - var title = "Billing" - var hint = "Please select your correct billing location to complete the checkout successfully." - var countries = Country.allMeld() - init() { + private var countries = Country.allMeld() + var searchedCountries = Country.allMeld() + + func searchCountries(_ searchText: String) { + let query = searchText + .lowercased() + .replacingOccurrences(of: " ", with: "") + .folding(options: .diacriticInsensitive, locale: .current) + + guard !query.isEmpty else { searchedCountries = Country.allMeld(); return } + + searchedCountries = countries.filter { + $0.name.lowercased().contains(query) + } } } diff --git a/gaios/Helpers/SearchTextField.swift b/gaios/Helpers/SearchTextField.swift index ce5fcc364..8fae46525 100644 --- a/gaios/Helpers/SearchTextField.swift +++ b/gaios/Helpers/SearchTextField.swift @@ -3,7 +3,7 @@ import UIKit class SearchTextField: UITextField { - let padding = UIEdgeInsets(top: 0, left: 30, bottom: 0, right: 0) + var padding = UIEdgeInsets(top: 0, left: 30, bottom: 0, right: 0) override open func textRect(forBounds bounds: CGRect) -> CGRect { return bounds.inset(by: padding) diff --git a/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.swift b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.swift new file mode 100644 index 000000000..c152a7930 --- /dev/null +++ b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.swift @@ -0,0 +1,45 @@ +import UIKit + +class AutoLogoutCell: UITableViewCell { + private var isCurrentOption = false + private var onSelect: ((Int) -> Void)? + private var index: Int? + + class var identifier: String { return String(describing: self) } + + @IBOutlet weak var optionButton: UIButton! + + override func awakeFromNib() { + super.awakeFromNib() + + optionButton.addTarget(self, action: #selector(onSelectOption), for: .touchUpInside) + + } + + func configure( + _ model: DialogCellModel + ) { + guard let model = model as? AutoLogoutCellModel else { return } + + index = model.index + onSelect = model.onSelected + optionButton.setTitle(model.title, for: .normal) + isCurrentOption = model.selected + + handleSelectionStatus() + } + + @objc private func onSelectOption() { + isCurrentOption = true + handleSelectionStatus() + onSelect?(index ?? 0) + } + + private func handleSelectionStatus() { + if (isCurrentOption) { + optionButton.backgroundColor = UIColor.gBlackBg() + } else { + optionButton.backgroundColor = UIColor.gGrayBtn() + } + } +} diff --git a/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.xib b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.xib new file mode 100644 index 000000000..dabcd1d09 --- /dev/null +++ b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCellModel.swift b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCellModel.swift new file mode 100644 index 000000000..90c6f7b8e --- /dev/null +++ b/gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCellModel.swift @@ -0,0 +1,17 @@ + +class AutoLogoutCellModel: DialogCellModel { + var type: DialogCellType + + let title: String + let index: Int + let selected: Bool + let onSelected: ((Int) -> Void)? + + init(title: String, index: Int, selected: Bool, onSelected: ((Int) -> Void)?) { + self.type = .autoLogout + self.title = title + self.index = index + self.selected = selected + self.onSelected = onSelected + } +} diff --git a/gaios/Shared/Controllers/DialogList/DialogListViewController.swift b/gaios/Shared/Controllers/DialogList/DialogListViewController.swift index dd1ceef53..09680e0f0 100644 --- a/gaios/Shared/Controllers/DialogList/DialogListViewController.swift +++ b/gaios/Shared/Controllers/DialogList/DialogListViewController.swift @@ -46,7 +46,7 @@ class DialogListViewController: UIViewController { view.addSubview(blurredView) view.sendSubviewToBack(blurredView) - ["DialogListCell", "DialogEnable2faCell" ].forEach { + ["DialogListCell", "DialogEnable2faCell", "AutoLogoutCell"].forEach { tableView.register(UINib(nibName: $0, bundle: nil), forCellReuseIdentifier: $0) } @@ -161,6 +161,12 @@ extension DialogListViewController: UITableViewDelegate, UITableViewDataSource { cell.selectionStyle = .none return cell } + case .autoLogout: + if let cell = tableView.dequeueReusableCell(withIdentifier: AutoLogoutCell.identifier, for: indexPath) as? AutoLogoutCell, let vm = viewModel { + cell.configure(vm.items[indexPath.row]) + cell.selectionStyle = .none + return cell + } case .none: break } diff --git a/gaios/Shared/Controllers/DialogList/DialogListViewModel.swift b/gaios/Shared/Controllers/DialogList/DialogListViewModel.swift index be6324ce4..516392b7c 100644 --- a/gaios/Shared/Controllers/DialogList/DialogListViewModel.swift +++ b/gaios/Shared/Controllers/DialogList/DialogListViewModel.swift @@ -14,11 +14,13 @@ enum DialogType: CaseIterable { case redeemPrefs case debugPrefs case walletListPrefs + case autoLogoutPrefs } enum DialogCellType: CaseIterable { case list case enable2fa + case autoLogout } protocol DialogCellModel: AnyObject { diff --git a/gaios/Shared/Dialogs.storyboard b/gaios/Shared/Dialogs.storyboard index 7e24369c4..e39c6fe8d 100644 --- a/gaios/Shared/Dialogs.storyboard +++ b/gaios/Shared/Dialogs.storyboard @@ -46,7 +46,7 @@