From 53a5ee45168c26cb55a33d288c75a83ef1090c8a Mon Sep 17 00:00:00 2001 From: Jonikorjk Date: Mon, 22 Dec 2025 12:09:45 +0200 Subject: [PATCH 1/6] Provide search by country name and code --- .../xcshareddata/xcschemes/gaios.xcscheme | 4 +- gaios/BuyBTC/BuyBTCFlow.storyboard | 181 ++++++++++-------- .../SelectCountryViewController.swift | 47 ++++- .../SelectCountryViewModel.swift | 18 +- gaios/Helpers/SearchTextField.swift | 2 +- gaios/Shared/Dialogs.storyboard | 18 +- 6 files changed, 163 insertions(+), 107 deletions(-) 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"> - + - + @@ -18,7 +18,7 @@ - + @@ -48,7 +48,7 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -842,6 +873,7 @@ + @@ -849,9 +881,6 @@ - - - diff --git a/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift b/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift index 3c8cf9071..cf032f368 100644 --- a/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift +++ b/gaios/BuyBTC/SelectCountry/SelectCountryViewController.swift @@ -14,12 +14,13 @@ class SelectCountryViewController: KeyboardViewController { @IBOutlet weak var handle: UIView! @IBOutlet weak var lblTitle: UILabel! @IBOutlet weak var searchTextField: SearchTextField! - @IBOutlet weak var anchorBottom: NSLayoutConstraint! + @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! @@ -137,7 +138,7 @@ class SelectCountryViewController: KeyboardViewController { }, completion: { _ in self.dismiss(animated: false, completion: nil) if let indexPath = indexPath { - self.delegate?.didSelectCountry(self.viewModel.filteredCountries[indexPath.row]) + self.delegate?.didSelectCountry(self.viewModel.searchedCountries[indexPath.row]) } }) } @@ -153,12 +154,12 @@ extension SelectCountryViewController: UITableViewDelegate, UITableViewDataSourc } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return viewModel.filteredCountries.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.filteredCountries[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 10ff8851f..ff02233b4 100644 --- a/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift +++ b/gaios/BuyBTC/SelectCountry/SelectCountryViewModel.swift @@ -2,11 +2,11 @@ import Foundation import UIKit class SelectCountryViewModel { - var title = "Billing" - var hint = "Please select your correct billing location to complete the checkout successfully." + var title = "id_billing".localized + var hint = "id_please_select_your_correct".localized private var countries = Country.allMeld() - var filteredCountries = Country.allMeld() + var searchedCountries = Country.allMeld() func searchCountries(_ searchText: String) { let query = searchText @@ -14,10 +14,10 @@ class SelectCountryViewModel { .replacingOccurrences(of: " ", with: "") .folding(options: .diacriticInsensitive, locale: .current); - guard !query.isEmpty else { filteredCountries = Country.allMeld(); return } + guard !query.isEmpty else { searchedCountries = Country.allMeld(); return } - filteredCountries = countries.filter { - $0.code.lowercased().contains(query) || $0.name.lowercased().contains(query) + searchedCountries = countries.filter { + $0.name.lowercased().contains(query) } } } diff --git a/gaios/cs.lproj/Localizable.strings b/gaios/cs.lproj/Localizable.strings index d09e0bd40..d4d50bfa2 100644 --- a/gaios/cs.lproj/Localizable.strings +++ b/gaios/cs.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Vaše peněženka ještě není zcela zabezpečená.\nAktivujte prosím 2-Faktorové ověřování."; "id_your_watchonly_username_and" = "Vaše uživatelské jméno a heslo pro Pouze-pro-sledování bude na tomto zařízení uloženo nešifrované. Pokud je zařízení ohroženo, mohou třetí strany získat přístup k vaší historii transakcí. Pokračujte stisknutím tlačítka „OK“."; "id_youve_entered_an_invalid_pin" = "Příliš mnohokrát jste zadali neplatný kód PIN."; +"id_billing" = "Fakturace"; diff --git a/gaios/de.lproj/Localizable.strings b/gaios/de.lproj/Localizable.strings index c66a1f0f9..0ab84538b 100644 --- a/gaios/de.lproj/Localizable.strings +++ b/gaios/de.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Deine Wallet ist noch nicht vollständig gesichert. \nBitte aktiviere die Zwei-Faktor Authentifizierung."; "id_your_watchonly_username_and" = "Dein Watch-Only Benutzername und Passwort werden unverschlüsselt auf diesem Gerät gespeichert. Sollte dein Gerät kompromittiert werden, können Dritte Zugang zu deinem Transaktionsverlauf erhalten. Drücke \"OK\", um fortzufahren."; "id_youve_entered_an_invalid_pin" = "Du hast zu oft eine ungültige PIN eingegeben."; +"id_billing" = "Abrechnung"; diff --git a/gaios/en.lproj/Localizable.strings b/gaios/en.lproj/Localizable.strings index a8ceda01a..ab50d8e7d 100644 --- a/gaios/en.lproj/Localizable.strings +++ b/gaios/en.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Your wallet is not yet fully secured.\nPlease enable Two-Factor authentication."; "id_your_watchonly_username_and" = "Your watch-only username and password will be stored un-encrypted on this device. If your device is compromised third parties can get access to your transaction history. Press \"OK\" to continue."; "id_youve_entered_an_invalid_pin" = "You've entered an invalid PIN too many times."; +"id_billing" = "Billing"; diff --git a/gaios/es.lproj/Localizable.strings b/gaios/es.lproj/Localizable.strings index 6ea444bab..08c42b3a3 100644 --- a/gaios/es.lproj/Localizable.strings +++ b/gaios/es.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Su cartera aún no está completamente protegida.\nHabilite la autenticación de dos factores."; "id_your_watchonly_username_and" = "Su nombre de usuario y contraseña del modo de solo lectura se guardarán sin encriptar en este dispositivo. Si su dispositivo queda expuesto, cualquier tercero podría acceder a su historial de transacciones. Presione \"OK\" para continuar."; "id_youve_entered_an_invalid_pin" = "Ha ingresado un PIN inválido demasiadas veces."; +"id_billing" = "Facturación"; diff --git a/gaios/fr.lproj/Localizable.strings b/gaios/fr.lproj/Localizable.strings index 5bff146b8..e83ac2d7f 100644 --- a/gaios/fr.lproj/Localizable.strings +++ b/gaios/fr.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Votre portefeuille n'est pas complètement sécurisé.\nVeuillez activer un deuxième facteur d'authentification."; "id_your_watchonly_username_and" = "Votre nom d'utilisateur et votre mot de passe pour la surveillance seulement seront stockés en clair sur cet appareil. Si votre appareil est compromis, des tiers peuvent avoir accès à l'historique de vos transactions. Appuyez sur \"OK\" pour continuer."; "id_youve_entered_an_invalid_pin" = "Vous avez entré un code PIN invalide un trop grand nombre de fois."; +"id_billing" = "Facturation"; diff --git a/gaios/he.lproj/Localizable.strings b/gaios/he.lproj/Localizable.strings index 76d59156c..f0bd71c90 100644 --- a/gaios/he.lproj/Localizable.strings +++ b/gaios/he.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Your wallet is not yet fully secured.\nPlease enable Two-Factor authentication."; "id_your_watchonly_username_and" = "Your watch-only username and password will be stored un-encrypted on this device. If your device is compromised third parties can get access to your transaction history. Press \"OK\" to continue."; "id_youve_entered_an_invalid_pin" = "You've entered an invalid PIN too many times."; +"id_billing" = "Billing"; diff --git a/gaios/it.lproj/Localizable.strings b/gaios/it.lproj/Localizable.strings index d2b82f5f5..aba901838 100644 --- a/gaios/it.lproj/Localizable.strings +++ b/gaios/it.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Il tuo wallet non è ancora completamente al sicuro.\nAbilita Autenticazione a Due Fattori."; "id_your_watchonly_username_and" = "Il tuo username e la tua password watch-only verranno salvati in chiaro su questo dispositivo. Se il tuo dispositivo è compromesso, soggetti terzi possono accedere alle cronologia delle tue transazioni. Premi OK per continuare."; "id_youve_entered_an_invalid_pin" = "PIN non valido inserito troppe volte."; +"id_billing" = "Fatturazione"; diff --git a/gaios/ja.lproj/Localizable.strings b/gaios/ja.lproj/Localizable.strings index 3ad7c8e53..a5a827f5e 100644 --- a/gaios/ja.lproj/Localizable.strings +++ b/gaios/ja.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "ウォレットが安全ではありません。\n2段階認証を設定してください。"; "id_your_watchonly_username_and" = "読み取りモードのアクセスに使用するユーザー名とパスワードはデバイス上に平文で保管されます。デバイスに不正アクセスがあると第三者に取引履歴を閲覧される可能性があります。よろしければ続行してください。"; "id_youve_entered_an_invalid_pin" = "無効なPINの入力回数が上限に達しました。"; +"id_billing" = "請求"; diff --git a/gaios/ko.lproj/Localizable.strings b/gaios/ko.lproj/Localizable.strings index a1bb58d20..b738d50c3 100644 --- a/gaios/ko.lproj/Localizable.strings +++ b/gaios/ko.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "지갑의 보안 수준이 완전하지 않습니다.\n이중 인증을 활성화하세요."; "id_your_watchonly_username_and" = "보기 전용 사용자 이름과 비밀번호는 이 기기에 암호화되지 않은 상태로 저장됩니다. 기기가 보안 위험에 노출된 경우 제 3자가 거래 내역에 액세스할 수 있습니다. 계속하려면 \"OK\"를 누르세요."; "id_youve_entered_an_invalid_pin" = "잘못된 PIN을 너무 많이 입력했습니다."; +"id_billing" = "결제"; diff --git a/gaios/nl.lproj/Localizable.strings b/gaios/nl.lproj/Localizable.strings index 4b2768e4b..127e1b2a7 100644 --- a/gaios/nl.lproj/Localizable.strings +++ b/gaios/nl.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Je wallet is nog niet volledig beveiligd.\nSchakel tweetrapsauthenticatie in."; "id_your_watchonly_username_and" = "Je gebruikersnaam en wachtwoord voor watch-only worden onversleuteld op dit apparaat opgeslagen. Als je apparaat is gecompromitteerd, kunnen derden toegang krijgen tot je transactiegeschiedenis. Druk op \"OK\" om verder te gaan."; "id_youve_entered_an_invalid_pin" = "Je hebt te vaak een ongeldige PIN ingevoerd."; +"id_billing" = "Facturatie"; diff --git a/gaios/pt-BR.lproj/Localizable.strings b/gaios/pt-BR.lproj/Localizable.strings index fa4198869..9625f45e3 100644 --- a/gaios/pt-BR.lproj/Localizable.strings +++ b/gaios/pt-BR.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Sua carteira não está completamente segura.\nPor favor, ative o 2FA."; "id_your_watchonly_username_and" = "Seu nome de usuário e senha serão gravados de forma não criptografada neste aparelho. Se seu aparelho estiver exposto, terceiros podem obter acesso ao seu histórico de transações. Pressione \"OK\" para continuar."; "id_youve_entered_an_invalid_pin" = "Você inseriu um PIN inválido muitas vezes."; +"id_billing" = "Faturamento"; diff --git a/gaios/ro.lproj/Localizable.strings b/gaios/ro.lproj/Localizable.strings index d8cbcf7bb..df31025c2 100644 --- a/gaios/ro.lproj/Localizable.strings +++ b/gaios/ro.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Portofelul dvs nu este securizat la maximum. \nVă rugăm să activați autentificarea cu doi factori."; "id_your_watchonly_username_and" = "Numele de utilizator și parola necesare unei logări în modul watch-only vor fi stocate pe acest dispozitiv fără a fi criptate. Dacă dispozitivul dvs este compromis, atunci terțe părți vor putea să aibă acces la istoricul dvs de tranzacții. Apăsați \"OK\" pentru a continua."; "id_youve_entered_an_invalid_pin" = "You've entered an invalid PIN too many times."; +"id_billing" = "Facturare"; diff --git a/gaios/ru.lproj/Localizable.strings b/gaios/ru.lproj/Localizable.strings index 571a9792d..10793c274 100644 --- a/gaios/ru.lproj/Localizable.strings +++ b/gaios/ru.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Ваш кошелек не защищен.\nПожалуйста, включите двухфакторную аутентификацию."; "id_your_watchonly_username_and" = "Ваше имя пользователя и пароль для режима watch-only будут храниться на этом устройстве в незашифрованном виде. Если ваше устройство будет взломано, третьи лица смогут получить доступ к истории ваших транзакций. Нажмите «ОК», чтобы продолжить."; "id_youve_entered_an_invalid_pin" = "Вы ввели неверный PIN-код слишком много раз."; +"id_billing" = "Платежи"; diff --git a/gaios/uk.lproj/Localizable.strings b/gaios/uk.lproj/Localizable.strings index d5d9e836d..3470b53e2 100644 --- a/gaios/uk.lproj/Localizable.strings +++ b/gaios/uk.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Ваш гаманець ще не надійно захищений.\nБудь ласка, увімкніть двофакторну аутентифікацію."; "id_your_watchonly_username_and" = "Ваше ім'я користувача та пароль watch-only зберігатимуться на цьому пристрої в незашифрованому вигляді. Якщо ваш пристрій буде зламано, треті особи зможуть отримати доступ до історії транзакцій. Натисніть \"OK\", щоб продовжити."; "id_youve_entered_an_invalid_pin" = "Ви надто багато разів вводили неправильний PIN-код."; +"id_billing" = "Платежі"; diff --git a/gaios/vi.lproj/Localizable.strings b/gaios/vi.lproj/Localizable.strings index fefcbce45..f7e3883ef 100644 --- a/gaios/vi.lproj/Localizable.strings +++ b/gaios/vi.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "Ví của bạn chưa bảo mật đầy đủ\nLàm ơn kích hoạt xác thực 2 lớp"; "id_your_watchonly_username_and" = "Tên người dùng và mật khẩu chỉ xem của bạn sẽ được lưu trữ không được mã hóa trên thiết bị này. Nếu thiết bị của bạn bị xâm phạm, bên thứ ba có thể truy cập vào lịch sử giao dịch của bạn. Nhấn \"OK\" để tiếp tục."; "id_youve_entered_an_invalid_pin" = "You've entered an invalid PIN too many times."; +"id_billing" = "Thanh toán"; diff --git a/gaios/zh.lproj/Localizable.strings b/gaios/zh.lproj/Localizable.strings index 9d1a0cae9..bb06106b9 100644 --- a/gaios/zh.lproj/Localizable.strings +++ b/gaios/zh.lproj/Localizable.strings @@ -1837,3 +1837,4 @@ "id_your_wallet_is_not_yet_fully" = "你的钱包还没完成安全设置。\n请开启双重验证。"; "id_your_watchonly_username_and" = "你的watch-only用户名和密码会被以非加密形式保存在当前设备上。如果你的设备被入侵,第三方会拥有查看你的转账记录的权限。点击“OK”继续。"; "id_youve_entered_an_invalid_pin" = "您输入无效PIN的次数过多。"; +"id_billing" = "计费"; From 94026a281c6bdffb80cd8c454e9b503780403f4c Mon Sep 17 00:00:00 2001 From: Jonikorjk Date: Tue, 23 Dec 2025 19:53:07 +0200 Subject: [PATCH 3/6] Fix scroll --- gaios/BuyBTC/BuyBTCFlow.storyboard | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gaios/BuyBTC/BuyBTCFlow.storyboard b/gaios/BuyBTC/BuyBTCFlow.storyboard index f9a2fe724..e1a614a6e 100644 --- a/gaios/BuyBTC/BuyBTCFlow.storyboard +++ b/gaios/BuyBTC/BuyBTCFlow.storyboard @@ -174,7 +174,7 @@ - + @@ -771,7 +771,7 @@ - + From 5e1124421dfb55591850832b92ceeec5d2bb37ce Mon Sep 17 00:00:00 2001 From: Jonikorjk Date: Tue, 23 Dec 2025 19:56:24 +0200 Subject: [PATCH 4/6] Disable interaction with price chart --- .../Tabs/Cells/PriceChartCell/PriceChartCell.xib | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gaios/WalletTabBar/Tabs/Cells/PriceChartCell/PriceChartCell.xib b/gaios/WalletTabBar/Tabs/Cells/PriceChartCell/PriceChartCell.xib index eaf60dcda..51c0bb7ae 100644 --- a/gaios/WalletTabBar/Tabs/Cells/PriceChartCell/PriceChartCell.xib +++ b/gaios/WalletTabBar/Tabs/Cells/PriceChartCell/PriceChartCell.xib @@ -1,9 +1,9 @@ - + - + @@ -81,7 +81,7 @@ - + From 235446bf5be42455b3bb566a34a266b0b418b7ab Mon Sep 17 00:00:00 2001 From: Jonikorjk Date: Wed, 24 Dec 2025 15:08:39 +0200 Subject: [PATCH 5/6] Add app bottom sheet in auto logout timeout --- gaios.xcodeproj/project.pbxproj | 20 ++ .../Cells/AutoLogoutCell/AutoLogoutCell.swift | 45 ++++ .../Cells/AutoLogoutCell/AutoLogoutCell.xib | 49 ++++ .../AutoLogoutCell/AutoLogoutCellModel.swift | 17 ++ .../DialogList/DialogListViewController.swift | 8 +- .../DialogList/DialogListViewModel.swift | 2 + gaios/UserSettings/UserSettings.storyboard | 232 +++++++++--------- .../Tabs/Settings/TabSettingsVC.swift | 49 ++-- 8 files changed, 288 insertions(+), 134 deletions(-) create mode 100644 gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.swift create mode 100644 gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCell.xib create mode 100644 gaios/Shared/Controllers/DialogList/Cells/AutoLogoutCell/AutoLogoutCellModel.swift 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/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/UserSettings/UserSettings.storyboard b/gaios/UserSettings/UserSettings.storyboard index c2b021063..4115dfccc 100644 --- a/gaios/UserSettings/UserSettings.storyboard +++ b/gaios/UserSettings/UserSettings.storyboard @@ -1,6 +1,6 @@ - + @@ -15,11 +15,11 @@ - + - + - + @@ -578,7 +578,7 @@ - + @@ -590,13 +590,13 @@