diff --git a/Trust.xcodeproj/project.pbxproj b/Trust.xcodeproj/project.pbxproj index aae2e5717..ae76ce570 100644 --- a/Trust.xcodeproj/project.pbxproj +++ b/Trust.xcodeproj/project.pbxproj @@ -281,6 +281,7 @@ 5E7C70FF17622C0FFD45A542 /* AlphaWalletSettingPushRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D2AAB777BF35B8B56BD /* AlphaWalletSettingPushRow.swift */; }; 5E7C710331196CD591B51785 /* LockCreatePasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C741196D9D9C9C3EE5E30 /* LockCreatePasscodeViewController.swift */; }; 5E7C713ACE8C72642B1C9F93 /* SendHeaderViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B7A45EDFA8ED1E25863 /* SendHeaderViewViewModel.swift */; }; + 5E7C718043636901114BF76C /* LocalesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7FB99843529061368DA1 /* LocalesViewModel.swift */; }; 5E7C71A6B0BDF301747A49AE /* ScreenChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C77E1E6194F5A1DC8D645 /* ScreenChecker.swift */; }; 5E7C71A7D2BD6FCE3980CC51 /* ImportWalletHelpBubbleViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7A16ABC8BD5D508AA641 /* ImportWalletHelpBubbleViewViewModel.swift */; }; 5E7C71B52A77008694BFA5D1 /* TokensDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C74B9EB81C51E956566E7 /* TokensDataStore.swift */; }; @@ -295,6 +296,7 @@ 5E7C72B0A10A92E591696E48 /* ContactUsBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AE6FAE0DF969B4F52E9 /* ContactUsBannerView.swift */; }; 5E7C72C8A15397C5A40BFE76 /* WhatIsEthereumInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C774BCA281E4B077DBBFA /* WhatIsEthereumInfoViewController.swift */; }; 5E7C72E1D4B4B4C8443F3DA1 /* SendHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7828BD821B6F04B71C00 /* SendHeaderView.swift */; }; + 5E7C730C6AEF556AFB9A4B2C /* LocalesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7BF09AD68C113D58344C /* LocalesViewController.swift */; }; 5E7C7317533D24B6A292F88D /* UIStackView+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C73ED9226646D562B5A3C /* UIStackView+Array.swift */; }; 5E7C731B88842C036A74A039 /* AlphaWalletSettingsButtonRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C71EBD4C95AD4E11F3352 /* AlphaWalletSettingsButtonRow.swift */; }; 5E7C731D0F6128BE8885A2D3 /* ServersCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B8FD1E2BCC325DF4EE4 /* ServersCoordinator.swift */; }; @@ -310,6 +312,7 @@ 5E7C7499A8D6814F7950DA70 /* LockCreatePasscodeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7AB3440C01136DF4F3E9 /* LockCreatePasscodeCoordinator.swift */; }; 5E7C74B5796FB59C8427C7A0 /* GenerateTransferMagicLinkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D46C7CABC31A7477F37 /* GenerateTransferMagicLinkViewController.swift */; }; 5E7C74B99922D0CAB635970E /* PasscodeCharacterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B9220E616F82EDA956F /* PasscodeCharacterView.swift */; }; + 5E7C74BD08801CABF9695853 /* LocaleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C79778E4BFE1322711EA6 /* LocaleViewModel.swift */; }; 5E7C74DBAE43954C185057B3 /* ChooseTicketTransferModeViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7BA578BE5FB0E613A6D6 /* ChooseTicketTransferModeViewControllerViewModel.swift */; }; 5E7C7567A690B6B8F889AE83 /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C70088832B2D161EB4AAB /* SendViewController.swift */; }; 5E7C75C99B9F595F26EDC405 /* LockPasscodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7D5F3CAE69CF932AB236 /* LockPasscodeViewController.swift */; }; @@ -346,6 +349,7 @@ 5E7C79D78AA5E774119BE49B /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7CFDE7DEA8C06C4100AF /* TextField.swift */; }; 5E7C79F30A324D75DF42DDDE /* SellTicketsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7EB14E787BC019660389 /* SellTicketsViewModel.swift */; }; 5E7C7A4384A8E3F22D3F8249 /* SetSellTicketsExpiryDateViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C700CD3E43689E88FBE9B /* SetSellTicketsExpiryDateViewControllerViewModel.swift */; }; + 5E7C7A91D0F6CBDA3C89DEAC /* LocaleViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C79E3BC4CACB123840A42 /* LocaleViewCell.swift */; }; 5E7C7AB2ECFB589632F2A26C /* WalletFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7E2DCCE0D775ECF83088 /* WalletFilter.swift */; }; 5E7C7AB6950E43BD6E8D0CBE /* TokensViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7B3302309706CA0F972A /* TokensViewController.swift */; }; 5E7C7AE1389D3179239249F0 /* ImportWalletTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C743172FCBDCD362C03A6 /* ImportWalletTabBar.swift */; }; @@ -380,6 +384,7 @@ 5E7C7EAEBB435F3909DA36FB /* TransferTicketsViaWalletAddressViewControllerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C76D3CFA12C2236E73E10 /* TransferTicketsViaWalletAddressViewControllerViewModel.swift */; }; 5E7C7EAED92E4AE8B99217AB /* TransferTicketsQuantitySelectionViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7021EE19C4B81CAAF3C0 /* TransferTicketsQuantitySelectionViewControllerTests.swift */; }; 5E7C7EB845B0EE96CC8DCF43 /* ServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C7FCE2427A30ACD860DF8 /* ServerViewModel.swift */; }; + 5E7C7ECE164289A89734B4EF /* LocalesCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C76C895E7BFA47233068C /* LocalesCoordinator.swift */; }; 5E7C7EDA1BB781A45C1C19CD /* ImportWalletTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C73D26F24C4AAE981E2F2 /* ImportWalletTab.swift */; }; 5E7C7EEE563D81793CB96FA0 /* TransferTicketsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C755132D9B6F95080A1BE /* TransferTicketsCoordinator.swift */; }; 5E7C7FAF2A07E7AE21BF09AF /* AlphaWalletSettingsTextRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E7C71684B93F60206992E10 /* AlphaWalletSettingsTextRow.swift */; }; @@ -843,6 +848,7 @@ 5E7C765E0DC0174E9788CCF9 /* EnterSellTicketsPriceQuantityViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterSellTicketsPriceQuantityViewControllerViewModel.swift; sourceTree = ""; }; 5E7C767497AD8DEE83F384D7 /* RequestViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestViewModel.swift; sourceTree = ""; }; 5E7C76AF81B8DFF605558499 /* UniversalLinkCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UniversalLinkCoordinator.swift; sourceTree = ""; }; + 5E7C76C895E7BFA47233068C /* LocalesCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalesCoordinator.swift; sourceTree = ""; }; 5E7C76D3CFA12C2236E73E10 /* TransferTicketsViaWalletAddressViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransferTicketsViaWalletAddressViewControllerViewModel.swift; sourceTree = ""; }; 5E7C77061BEF269BCE358086 /* BaseTicketTableViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTicketTableViewCellViewModel.swift; sourceTree = ""; }; 5E7C77316522DF2B256F1F92 /* TicketsViewControllerHeaderViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketsViewControllerHeaderViewModel.swift; sourceTree = ""; }; @@ -861,9 +867,11 @@ 5E7C794F8EBAEE5E8F2821C2 /* MarketplaceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarketplaceViewController.swift; sourceTree = ""; }; 5E7C796039C0F47CDCA236C0 /* TicketsViewControllerHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TicketsViewControllerHeader.swift; sourceTree = ""; }; 5E7C7962AE417E12F13FF58E /* SetSellTicketsExpiryDateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetSellTicketsExpiryDateViewController.swift; sourceTree = ""; }; + 5E7C79778E4BFE1322711EA6 /* LocaleViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleViewModel.swift; sourceTree = ""; }; 5E7C7981AB6584B25C72D46B /* LockEnterPasscodeCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockEnterPasscodeCoordinator.swift; sourceTree = ""; }; 5E7C79CF6150E4CD4A276FC0 /* GenerateSellMagicLinkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateSellMagicLinkViewController.swift; sourceTree = ""; }; 5E7C79D674D45A07E694CE31 /* LockView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockView.swift; sourceTree = ""; }; + 5E7C79E3BC4CACB123840A42 /* LocaleViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocaleViewCell.swift; sourceTree = ""; }; 5E7C79ED9F842D3FC102AC54 /* TokenViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenViewCellViewModel.swift; sourceTree = ""; }; 5E7C7A16ABC8BD5D508AA641 /* ImportWalletHelpBubbleViewViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletHelpBubbleViewViewModel.swift; sourceTree = ""; }; 5E7C7A65F6033318F7C8AEB0 /* DateEntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateEntryField.swift; sourceTree = ""; }; @@ -884,6 +892,7 @@ 5E7C7B9220E616F82EDA956F /* PasscodeCharacterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeCharacterView.swift; sourceTree = ""; }; 5E7C7BA578BE5FB0E613A6D6 /* ChooseTicketTransferModeViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChooseTicketTransferModeViewControllerViewModel.swift; sourceTree = ""; }; 5E7C7BD9B4BDAFC2D9EBD741 /* StatusViewControllerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusViewControllerViewModel.swift; sourceTree = ""; }; + 5E7C7BF09AD68C113D58344C /* LocalesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalesViewController.swift; sourceTree = ""; }; 5E7C7C077372C3F2A4349FA1 /* TokenViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenViewCell.swift; sourceTree = ""; }; 5E7C7C2872E213BBB05D55BA /* ImportWalletTabBarViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletTabBarViewModel.swift; sourceTree = ""; }; 5E7C7C58586099F082973073 /* WalletFilterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletFilterView.swift; sourceTree = ""; }; @@ -906,6 +915,7 @@ 5E7C7F5C10E3895E805EA7E0 /* BaseTicketTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTicketTableViewCell.swift; sourceTree = ""; }; 5E7C7F610139D24D947B1625 /* EnterSellTicketsPriceQuantityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterSellTicketsPriceQuantityViewController.swift; sourceTree = ""; }; 5E7C7F932B48011A24C26733 /* TokensCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokensCoordinator.swift; sourceTree = ""; }; + 5E7C7FB99843529061368DA1 /* LocalesViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalesViewModel.swift; sourceTree = ""; }; 5E7C7FCE2427A30ACD860DF8 /* ServerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerViewModel.swift; sourceTree = ""; }; 5E7C7FF84A4377FC395772C3 /* SellTicketsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SellTicketsViewController.swift; sourceTree = ""; }; 613D04881FDE15F8008DE72E /* COMODO ECC Domain Validation Secure Server CA 2.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = "COMODO ECC Domain Validation Secure Server CA 2.cer"; sourceTree = ""; }; @@ -1536,6 +1546,7 @@ 7721A6CF202EFD07004DB16C /* AddCustomNetworkCoordinator.swift */, 5E7C7B1FB2702A2A8A4EBD76 /* SettingsCoordinator.swift */, 5E7C7B8FD1E2BCC325DF4EE4 /* ServersCoordinator.swift */, + 5E7C76C895E7BFA47233068C /* LocalesCoordinator.swift */, ); path = Coordinators; sourceTree = ""; @@ -1736,6 +1747,8 @@ 5E7C719B717E002583B1E2E9 /* AdvancedSettingsViewModel.swift */, 5E7C7FCE2427A30ACD860DF8 /* ServerViewModel.swift */, 5E7C7CBEBF984CFCA29D6866 /* ServersViewModel.swift */, + 5E7C7FB99843529061368DA1 /* LocalesViewModel.swift */, + 5E7C79778E4BFE1322711EA6 /* LocaleViewModel.swift */, ); path = ViewModels; sourceTree = ""; @@ -2152,6 +2165,7 @@ 5E7C78581AA28CA5C3CBC468 /* AdvancedSettingsViewController.swift */, 5E7C7AFE9AF9FE6B58C925D4 /* SettingsViewController.swift */, 5E7C74C0C1803DD17FE9EBA7 /* ServersViewController.swift */, + 5E7C7BF09AD68C113D58344C /* LocalesViewController.swift */, ); path = ViewControllers; sourceTree = ""; @@ -2447,6 +2461,7 @@ isa = PBXGroup; children = ( 5E7C7CDB0BAD5D27D2F24F57 /* ServerViewCell.swift */, + 5E7C79E3BC4CACB123840A42 /* LocaleViewCell.swift */, ); path = Views; sourceTree = ""; @@ -3652,6 +3667,11 @@ 5E7C70AE62DBB193399C7F5E /* ServerViewCell.swift in Sources */, 5E7C7EB845B0EE96CC8DCF43 /* ServerViewModel.swift in Sources */, 5E7C745A423BD10CFDED9A81 /* ServersViewModel.swift in Sources */, + 5E7C7ECE164289A89734B4EF /* LocalesCoordinator.swift in Sources */, + 5E7C730C6AEF556AFB9A4B2C /* LocalesViewController.swift in Sources */, + 5E7C718043636901114BF76C /* LocalesViewModel.swift in Sources */, + 5E7C7A91D0F6CBDA3C89DEAC /* LocaleViewCell.swift in Sources */, + 5E7C74BD08801CABF9695853 /* LocaleViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Trust/Settings/Coordinators/LocalesCoordinator.swift b/Trust/Settings/Coordinators/LocalesCoordinator.swift new file mode 100644 index 000000000..0da5fb8d8 --- /dev/null +++ b/Trust/Settings/Coordinators/LocalesCoordinator.swift @@ -0,0 +1,41 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import UIKit + +protocol LocalesCoordinatorDelegate: class { + func didSelect(locale: AppLocale, in coordinator: LocalesCoordinator) +} + +class LocalesCoordinator: Coordinator { + var coordinators: [Coordinator] = [] + var config: Config + + lazy var localesViewController: LocalesViewController = { + let locales: [AppLocale] = [ + .system, + .english, + .simplifiedChinese, + .spanish, + ] + let controller = LocalesViewController() + controller.configure(viewModel: LocalesViewModel(locales: locales, selectedLocale: AppLocale(id: config.locale))) + controller.delegate = self + return controller + }() + weak var delegate: LocalesCoordinatorDelegate? + + init(config: Config) { + self.config = config + } + + func start() { + } +} + +extension LocalesCoordinator: LocalesViewControllerDelegate { + func didSelect(locale: AppLocale, in viewController: LocalesViewController) { + config.locale = locale.id + delegate?.didSelect(locale: locale, in: self) + } +} + diff --git a/Trust/Settings/Coordinators/SettingsCoordinator.swift b/Trust/Settings/Coordinators/SettingsCoordinator.swift index f138dd72a..730e0ee36 100644 --- a/Trust/Settings/Coordinators/SettingsCoordinator.swift +++ b/Trust/Settings/Coordinators/SettingsCoordinator.swift @@ -82,6 +82,14 @@ class SettingsCoordinator: Coordinator { navigationController.pushViewController(coordinator.serversViewController, animated: true) } + @objc func showLocales() { + let coordinator = LocalesCoordinator(config: config) + coordinator.delegate = self + coordinator.start() + addCoordinator(coordinator) + navigationController.pushViewController(coordinator.localesViewController, animated: true) + } + func restart(for wallet: Wallet) { delegate?.didRestart(with: wallet, in: self) } @@ -98,6 +106,8 @@ extension SettingsCoordinator: SettingsViewControllerDelegate { showAccounts() case .servers: showServers() + case .locales: + showLocales() case .RPCServer, .currency, .DAppsBrowser: restart(for: session.account) case .pushNotifications(let enabled): @@ -145,3 +155,11 @@ extension SettingsCoordinator: ServersCoordinatorDelegate { restart(for: session.account) } } + +extension SettingsCoordinator: LocalesCoordinatorDelegate { + func didSelect(locale: AppLocale, in coordinator: LocalesCoordinator) { + coordinator.localesViewController.navigationController?.popViewController(animated: true) + removeCoordinator(coordinator) + restart(for: session.account) + } +} diff --git a/Trust/Settings/Types/SettingsAction.swift b/Trust/Settings/Types/SettingsAction.swift index 2c13d2ded..39d976774 100644 --- a/Trust/Settings/Types/SettingsAction.swift +++ b/Trust/Settings/Types/SettingsAction.swift @@ -7,6 +7,7 @@ enum AlphaWalletSettingsAction { case myWalletAddress case notificationsSettings case wallets + case locales case RPCServer case servers case currency diff --git a/Trust/Settings/ViewControllers/AdvancedSettingsViewController.swift b/Trust/Settings/ViewControllers/AdvancedSettingsViewController.swift index a95f5d56a..a7cad202b 100644 --- a/Trust/Settings/ViewControllers/AdvancedSettingsViewController.swift +++ b/Trust/Settings/ViewControllers/AdvancedSettingsViewController.swift @@ -63,23 +63,21 @@ class AdvancedSettingsViewController: FormViewController { cell.detailTextLabel?.text = String(self.account.address.description.prefix(10)) + "..." cell.accessoryType = .disclosureIndicator } - <<< AlphaWalletSettingPushRow { [weak self] in + + <<< AppFormAppearance.alphaWalletSettingsButton { button in + button.cellStyle = .value1 + }.onCellSelection { [unowned self] _, _ in + self.run(action: .locales) + }.cellSetup { cell, _ in + cell.imageView?.tintColor = Colors.appBackground + }.cellUpdate { [weak self] cell, _ in guard let strongSelf = self else { return } - $0.title = strongSelf.viewModel.localeTitle - $0.options = strongSelf.viewModel.locales - $0.value = AppLocale(id: strongSelf.config.locale) - $0.selectorTitle = strongSelf.viewModel.localeTitle - $0.displayValueFor = { value in - return value?.displayName - } - }.onChange {[weak self] row in - self?.config.locale = row.value?.id - self?.run(action: .locale) - }.cellSetup { cell, _ in - cell.imageView?.tintColor = Colors.appBackground cell.imageView?.image = R.image.settings_language()?.withRenderingMode(.alwaysTemplate) + cell.textLabel?.text = strongSelf.viewModel.localeTitle + cell.detailTextLabel?.text = AppLocale(id: strongSelf.config.locale).displayName + cell.accessoryType = .disclosureIndicator } } diff --git a/Trust/Settings/ViewControllers/LocalesViewController.swift b/Trust/Settings/ViewControllers/LocalesViewController.swift new file mode 100644 index 000000000..adde8146b --- /dev/null +++ b/Trust/Settings/ViewControllers/LocalesViewController.swift @@ -0,0 +1,85 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import TrustKeystore +import UIKit + +protocol LocalesViewControllerDelegate: class { + func didSelect(locale: AppLocale, in viewController: LocalesViewController) +} + +class LocalesViewController: UIViewController { + let headerHeight = CGFloat(70) + weak var delegate: LocalesViewControllerDelegate? + let roundedBackground = RoundedBackground() + let header = TicketsViewControllerTitleHeader() + let tableView = UITableView(frame: .zero, style: .plain) + var viewModel: LocalesViewModel? + private var balances: [Address: Balance?] = [:] + + init() { + super.init(nibName: nil, bundle: nil) + + view.backgroundColor = Colors.appBackground + + roundedBackground.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(roundedBackground) + + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.delegate = self + tableView.separatorStyle = .none + tableView.backgroundColor = Colors.appWhite + tableView.rowHeight = 80 + tableView.tableHeaderView = header + tableView.register(LocaleViewCell.self, forCellReuseIdentifier: LocaleViewCell.identifier) + roundedBackground.addSubview(tableView) + + NSLayoutConstraint.activate([ + header.heightAnchor.constraint(equalToConstant: headerHeight), + + tableView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor), + tableView.topAnchor.constraint(equalTo: roundedBackground.topAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ] + roundedBackground.createConstraintsWithContainer(view: view)) + } + + func configure(viewModel: LocalesViewModel) { + self.viewModel = viewModel + tableView.dataSource = self + header.configure(title: viewModel.title) + header.frame.size.height = headerHeight + tableView.tableHeaderView = header + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension LocalesViewController: UITableViewDelegate, UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + guard let viewModel = viewModel else { return 0 } + return viewModel.locales.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: LocaleViewCell.identifier, for: indexPath) as! LocaleViewCell + if let viewModel = viewModel { + let locale = viewModel.locale(for: indexPath) + let cellViewModel = LocaleViewModel(locale: locale, selected: viewModel.isLocaleSelected(locale)) + cell.configure(viewModel: cellViewModel) + } + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + guard let viewModel = viewModel else { return } + let locale = viewModel.locale(for: indexPath) + delegate?.didSelect(locale: locale, in: self) + } +} diff --git a/Trust/Settings/ViewModels/AdvancedSettingsViewModel.swift b/Trust/Settings/ViewModels/AdvancedSettingsViewModel.swift index 60ca1446f..5a78fd52f 100644 --- a/Trust/Settings/ViewModels/AdvancedSettingsViewModel.swift +++ b/Trust/Settings/ViewModels/AdvancedSettingsViewModel.swift @@ -36,13 +36,4 @@ struct AdvancedSettingsViewModel { var localeTitle: String { return R.string.localizable.settingsLanguageButtonTitle() } - - var locales: [AppLocale] { - return [ - .system, - .english, - .simplifiedChinese, - .spanish, - ] - } } diff --git a/Trust/Settings/ViewModels/LocaleViewModel.swift b/Trust/Settings/ViewModels/LocaleViewModel.swift new file mode 100644 index 000000000..f66df026c --- /dev/null +++ b/Trust/Settings/ViewModels/LocaleViewModel.swift @@ -0,0 +1,46 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import Foundation +import UIKit + +struct LocaleViewModel { + let locale: AppLocale + let isSelected: Bool + + init(locale: AppLocale, selected: Bool) { + self.locale = locale + self.isSelected = selected + } + + var selectionIcon: UIImage { + if isSelected { + return R.image.ticket_bundle_checked()! + } else { + return R.image.ticket_bundle_unchecked()! + } + } + + var backgroundColor: UIColor { + return Colors.appWhite + } + + var contentsBackgroundColor: UIColor { + return backgroundColor + } + + var contentsBorderColor: UIColor { + return Colors.appHighlightGreen + } + + var contentsBorderWidth: CGFloat { + return 1 + } + + var localeFont: UIFont { + return Fonts.light(size: 20)! + } + + var localeName: String { + return locale.displayName + } +} diff --git a/Trust/Settings/ViewModels/LocalesViewModel.swift b/Trust/Settings/ViewModels/LocalesViewModel.swift new file mode 100644 index 000000000..0898b25f3 --- /dev/null +++ b/Trust/Settings/ViewModels/LocalesViewModel.swift @@ -0,0 +1,26 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import Foundation +import TrustKeystore + +struct LocalesViewModel { + let locales: [AppLocale] + let selectedLocale: AppLocale + + var title: String { + return R.string.localizable.settingsLanguageButtonTitle() + } + + init(locales: [AppLocale], selectedLocale: AppLocale) { + self.locales = locales + self.selectedLocale = selectedLocale + } + + func locale(for indexPath: IndexPath) -> AppLocale { + return locales[indexPath.row] + } + + func isLocaleSelected(_ locale: AppLocale) -> Bool { + return locale.id == selectedLocale.id + } +} diff --git a/Trust/Settings/Views/LocaleViewCell.swift b/Trust/Settings/Views/LocaleViewCell.swift new file mode 100644 index 000000000..8e9a44ebf --- /dev/null +++ b/Trust/Settings/Views/LocaleViewCell.swift @@ -0,0 +1,70 @@ +// Copyright © 2018 Stormbird PTE. LTD. + +import TrustKeystore +import UIKit + +class LocaleViewCell: UITableViewCell { + static let identifier = "LocaleViewCell" + + let background = UIView() + var selectedIcon = UIImageView(image: R.image.ticket_bundle_checked()) + var nameLabel = UILabel() + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(background) + background.translatesAutoresizingMaskIntoConstraints = false + + selectedIcon.translatesAutoresizingMaskIntoConstraints = false + selectedIcon.contentMode = .scaleAspectFit + + nameLabel.translatesAutoresizingMaskIntoConstraints = false + + let stackView = [selectedIcon, nameLabel].asStackView(spacing: 15, alignment: .center) + stackView.translatesAutoresizingMaskIntoConstraints = false + + selectedIcon.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal) + nameLabel.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal) + + stackView.setContentHuggingPriority(UILayoutPriority.required, for: .horizontal) + + background.addSubview(stackView) + + // TODO extract constant. Maybe StyleLayout.sideMargin + let xMargin = CGFloat(7) + let yMargin = CGFloat(7) + NSLayoutConstraint.activate([ + selectedIcon.widthAnchor.constraint(equalToConstant: 44), + + stackView.topAnchor.constraint(equalTo: background.topAnchor, constant: StyleLayout.sideMargin), + stackView.trailingAnchor.constraint(equalTo: background.trailingAnchor, constant: -StyleLayout.sideMargin), + stackView.bottomAnchor.constraint(equalTo: background.bottomAnchor, constant: -StyleLayout.sideMargin), + stackView.leadingAnchor.constraint(equalTo: background.leadingAnchor, constant: StyleLayout.sideMargin), + + background.leadingAnchor.constraint(equalTo: leadingAnchor, constant: xMargin), + background.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -xMargin), + background.topAnchor.constraint(equalTo: topAnchor, constant: yMargin), + background.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -yMargin), + ]) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configure(viewModel: LocaleViewModel) { + selectionStyle = .none + backgroundColor = viewModel.backgroundColor + + background.backgroundColor = viewModel.contentsBackgroundColor + background.layer.cornerRadius = 20 + background.borderColor = viewModel.contentsBorderColor + background.borderWidth = viewModel.contentsBorderWidth + + selectedIcon.image = viewModel.selectionIcon + + nameLabel.font = viewModel.localeFont + nameLabel.text = viewModel.localeName + } +}