diff --git a/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj b/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj index 1543f16473..64a1225fe8 100644 --- a/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj +++ b/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj @@ -2377,6 +2377,7 @@ ABC9A7F5ECEC3311216A407F /* SendMemoInputService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A80143F95E28346C81FE /* SendMemoInputService.swift */; }; ABC9A802418438F6BD1FC1E3 /* WalletTokenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A64A66778C137FA9642C /* WalletTokenViewController.swift */; }; ABC9A80BCDA72347C6619E6C /* SendTimeLockErrorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9ADF114FCFABEA148AF04 /* SendTimeLockErrorService.swift */; }; + ABC9A8117EAF046CDD020077 /* BorderedEmptyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A87D38298791EBAC52DB /* BorderedEmptyCell.swift */; }; ABC9A819DDAEE683FCCA02EF /* NftAssetCellFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A30A8F78E9C9AEE861F1 /* NftAssetCellFactory.swift */; }; ABC9A82C93C9E266D1AFD1C3 /* WalletConnectTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9AF0029A65DAB20925BDF /* WalletConnectTransaction.swift */; }; ABC9A8451CEF02EA0A94CEAA /* ProFeaturesAuthorizationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A9628A708749A31EEA70 /* ProFeaturesAuthorizationManager.swift */; }; @@ -2473,6 +2474,7 @@ ABC9AB83EE3F909BD80E0539 /* BackupCryptoHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9AD5CB1911A698718213F /* BackupCryptoHelper.swift */; }; ABC9AB86218564E4873F6428 /* WalletConnectUriHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A1C31F5343EB2BEA4540 /* WalletConnectUriHandler.swift */; }; ABC9AB92AA6E6B239B147FA7 /* ProposalChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A768C7AA282229C30409 /* ProposalChain.swift */; }; + ABC9AB982879DE0BAE6701EC /* BorderedEmptyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A87D38298791EBAC52DB /* BorderedEmptyCell.swift */; }; ABC9AB9DCC782F2EC14A7031 /* TechnicalIndicatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A3EE670713BA4B6110F4 /* TechnicalIndicatorService.swift */; }; ABC9ABA70CEF664E8E01FA7A /* SendNftModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A82A1E9AE6CC0E24756B /* SendNftModule.swift */; }; ABC9ABBE120DB35A597FFE44 /* Encodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC9A3DFC1E03CB2E6C12F2C /* Encodable.swift */; }; @@ -4273,6 +4275,7 @@ ABC9A830FE79DBF62FD63CC4 /* ThemeMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeMode.swift; sourceTree = ""; }; ABC9A85E2F420CB76C0E1CC3 /* WCSignMessageRequestService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCSignMessageRequestService.swift; sourceTree = ""; }; ABC9A86EA911DA12C7A6AC20 /* WalletTokenBalanceViewItemFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletTokenBalanceViewItemFactory.swift; sourceTree = ""; }; + ABC9A87D38298791EBAC52DB /* BorderedEmptyCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderedEmptyCell.swift; sourceTree = ""; }; ABC9A88CFC0598CD6D780AC2 /* WalletConnectRequestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletConnectRequestHandler.swift; sourceTree = ""; }; ABC9A88E126AB21F856522A7 /* IntegerAmountInputView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerAmountInputView.swift; sourceTree = ""; }; ABC9A896A83640B618328FE1 /* EnsAddressParserItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnsAddressParserItem.swift; sourceTree = ""; }; @@ -4912,6 +4915,7 @@ 11B3597E2B288ECD850C1DFE /* PasteInputCell.swift */, 11B356F4578E266268264021 /* QrCodeCell.swift */, D00267B82A57E6CE00D6B2D5 /* ResendPastInputCell.swift */, + ABC9A87D38298791EBAC52DB /* BorderedEmptyCell.swift */, ); path = Cells; sourceTree = ""; @@ -10407,6 +10411,7 @@ ABC9A57D1DA5481E44DEE8C0 /* PrimaryCircleButtonStyle.swift in Sources */, ABC9AD8A956680AAC03DE7F1 /* Alert.swift in Sources */, ABC9A22690729B58621A1BBA /* InformedModifier.swift in Sources */, + ABC9A8117EAF046CDD020077 /* BorderedEmptyCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11812,6 +11817,7 @@ ABC9AD530352E51084B1B4B7 /* PrimaryCircleButtonStyle.swift in Sources */, ABC9A267A28122E3E6E3D5DC /* Alert.swift in Sources */, ABC9A639040A77968B5D86B8 /* InformedModifier.swift in Sources */, + ABC9AB982879DE0BAE6701EC /* BorderedEmptyCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/UnstoppableWallet/UnstoppableWallet/Core/Managers/AppManager.swift b/UnstoppableWallet/UnstoppableWallet/Core/Managers/AppManager.swift index f691cbb45a..ce438cf3cb 100644 --- a/UnstoppableWallet/UnstoppableWallet/Core/Managers/AppManager.swift +++ b/UnstoppableWallet/UnstoppableWallet/Core/Managers/AppManager.swift @@ -1,5 +1,6 @@ import Foundation import RxSwift +import UIKit class AppManager { private let accountManager: AccountManager @@ -49,10 +50,17 @@ class AppManager { self.walletConnectSocketConnectionService = walletConnectSocketConnectionService self.nftMetadataSyncer = nftMetadataSyncer } + + private func warmUp() { + DispatchQueue.global(qos: .userInitiated).async { + _ = UIImage.qrCodeImage(qrCodeString: "", size: .margin48) + } + } } extension AppManager { func didFinishLaunching() { + warmUp() debugBackgroundLogger?.logFinishLaunching() keychainManager.handleLaunch() diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionCell.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionCell.swift index e312628fd1..45cd4abc66 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionCell.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionCell.swift @@ -1,13 +1,18 @@ import UIKit +import ComponentKit class DonateDescriptionCell: UITableViewCell { private static let horizontalPadding: CGFloat = .margin32 private static let verticalPadding: CGFloat = .margin24 private static let labelFont: UIFont = .headline2 - private static let emojiFont: UIFont = .title3 + private static let descriptionLabelFont: UIFont = .subhead2 let label = UILabel() - let emoji = UILabel() + let emoji = UIImageView() + let getAddressButton = PrimaryButton() + let descriptionLabel = UILabel() + + var onGetAddressAction: (() -> ())? override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) @@ -28,26 +33,49 @@ class DonateDescriptionCell: UITableViewCell { contentView.addSubview(emoji) emoji.snp.makeConstraints { maker in - maker.leading.trailing.equalToSuperview().inset(DonateDescriptionCell.horizontalPadding) + maker.centerX.equalToSuperview() maker.top.equalTo(label.snp.bottom).offset(DonateDescriptionCell.verticalPadding) } - emoji.font = DonateDescriptionCell.emojiFont - emoji.textColor = .themeLeah - emoji.text = "🙏" - emoji.textAlignment = .center + emoji.image = UIImage(named: "heart_fill_24")?.withTintColor(.themeJacob) + + contentView.addSubview(getAddressButton) + getAddressButton.snp.makeConstraints { maker in + maker.leading.trailing.equalToSuperview().inset(CGFloat.margin16) + maker.top.equalTo(emoji.snp.bottom).offset(DonateDescriptionCell.verticalPadding) + } + + getAddressButton.set(style: .gray) + getAddressButton.setTitle("donate.list.get_address".localized, for: .normal) + getAddressButton.addTarget(self, action: #selector(onGetAddress), for: .touchUpInside) + + contentView.addSubview(descriptionLabel) + descriptionLabel.snp.makeConstraints { maker in + maker.leading.trailing.equalToSuperview().inset(DonateDescriptionCell.horizontalPadding) + maker.top.equalTo(getAddressButton.snp.bottom).offset(DonateDescriptionCell.verticalPadding) + } + + descriptionLabel.numberOfLines = 0 + descriptionLabel.font = DonateDescriptionCell.descriptionLabelFont + descriptionLabel.textColor = .themeGray + descriptionLabel.textAlignment = .center + descriptionLabel.text = "donate.support.bottom_description".localized } @available(*, unavailable) required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } + + @objc private func onGetAddress() { + onGetAddressAction?() + } } extension DonateDescriptionCell { static func height(containerWidth: CGFloat, text: String, font: UIFont? = nil, ignoreBottomMargin: Bool = false) -> CGFloat { let textHeight = text.height(forContainerWidth: containerWidth - 2 * horizontalPadding, font: font ?? Self.labelFont) - let emojiHeight = "🙏".height(forContainerWidth: containerWidth - 2 * horizontalPadding, font: font ?? Self.labelFont) - return textHeight + .margin24 + emojiHeight + (ignoreBottomMargin ? 1 : 2) * verticalPadding + let descriptionTextHeight = text.height(forContainerWidth: containerWidth - 2 * horizontalPadding, font: font ?? Self.descriptionLabelFont) + return textHeight + .margin24 + .margin24 + .heightButton + +.margin24 + descriptionTextHeight + (ignoreBottomMargin ? 1 : 2) * verticalPadding } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionDataSource.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionDataSource.swift index 787bd16e98..7b98ec2e36 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionDataSource.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Donate/DonateDescriptionDataSource.swift @@ -11,18 +11,9 @@ class DonateDescriptionDataSource: NSObject, ISectionDataSource { self.viewController?.navigationController?.pushViewController(viewController, animated: true) } - private let rootGetAddressElement: CellBuilderNew.CellElement = .hStack([ - .textElement(text: .body("donate.list.get_address".localized)), - .margin8, - .image20 { (component: ImageComponent) in - component.imageView.image = UIImage(named: "arrow_big_forward_20")?.withTintColor(.themeGray) - }, - ]) - func prepare(tableView: UITableView) { tableView.registerCell(forClass: DonateDescriptionCell.self) - tableView.registerCell(forClass: BaseSelectableThemeCell.self) - tableView.registerCell(forClass: EmptyCell.self) + tableView.registerCell(forClass: BorderedEmptyCell.self) } func numberOfSections(in _: UITableView) -> Int { @@ -30,7 +21,7 @@ class DonateDescriptionDataSource: NSObject, ISectionDataSource { } func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { - 3 + 2 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { @@ -38,42 +29,24 @@ class DonateDescriptionDataSource: NSObject, ISectionDataSource { switch indexPath.row { case 0: return tableView.dequeueReusableCell(withIdentifier: String(describing: DonateDescriptionCell.self), for: originalIndexPath) - case 1: return tableView.dequeueReusableCell(withIdentifier: String(describing: EmptyCell.self), for: indexPath) - default: - return CellBuilderNew.preparedCell( - tableView: tableView, - indexPath: originalIndexPath, - selectable: true, - rootElement: rootGetAddressElement, - layoutMargins: UIEdgeInsets(top: 0, left: .margin16, bottom: 0, right: .margin16) - ) + default: return tableView.dequeueReusableCell(withIdentifier: String(describing: BorderedEmptyCell.self), for: indexPath) } } func tableView(_: UITableView, willDisplay cell: UITableViewCell, forRowAt _: IndexPath) { if let cell = cell as? DonateDescriptionCell { cell.label.text = "donate.support.description".localized + cell.onGetAddressAction = { [weak self] in self?.showAddresses() } } - - if let cell = cell as? BaseSelectableThemeCell { - cell.set(backgroundStyle: .transparent, isLast: true) - cell.bind(rootElement: rootGetAddressElement) + if let cell = cell as? BorderedEmptyCell { + cell.bottomBorder.isHidden = false } } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { switch indexPath.row { case 0: return DonateDescriptionCell.height(containerWidth: tableView.width, text: "donate.support.description".localized) - case 1: return .margin12 - default: return .heightSingleLineCell - } - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.row == 2 { - let originalIndexPath = delegate?.originalIndexPath(tableView: tableView, dataSource: self, indexPath: indexPath) ?? indexPath - tableView.deselectRow(at: originalIndexPath, animated: true) - showAddresses() + default: return .margin12 } } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListViewController.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListViewController.swift index 8826a19f21..a612673c16 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListViewController.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListViewController.swift @@ -12,6 +12,8 @@ import UIKit class WalletTokenListViewController: ThemeSearchViewController { private let viewModel: WalletTokenListViewModel + var hideSearchBar: Bool = false + let tableView = UITableView(frame: .zero, style: .plain) private let dataSource: ISectionDataSource @@ -37,6 +39,9 @@ class WalletTokenListViewController: ThemeSearchViewController { navigationItem.rightBarButtonItem = UIBarButtonItem(title: "button.cancel".localized, style: .plain, target: self, action: #selector(onTapClose)) navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) navigationItem.searchController?.searchBar.placeholder = "add_token.coin_name".localized + if hideSearchBar { + navigationItem.searchController = nil + } view.addSubview(tableView) tableView.snp.makeConstraints { maker in diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift index e59a8c3d42..dbfa74202e 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift @@ -223,6 +223,7 @@ struct WalletModule { dataSourceChain.append(source: dataSource) let viewController = WalletTokenListViewController(viewModel: viewModel, dataSource: dataSourceChain) + viewController.hideSearchBar = true descriptionDataSource.viewController = viewController dataSource.viewController = viewController diff --git a/UnstoppableWallet/UnstoppableWallet/UserInterface/Cells/BorderedEmptyCell.swift b/UnstoppableWallet/UnstoppableWallet/UserInterface/Cells/BorderedEmptyCell.swift new file mode 100644 index 0000000000..850e802087 --- /dev/null +++ b/UnstoppableWallet/UnstoppableWallet/UserInterface/Cells/BorderedEmptyCell.swift @@ -0,0 +1,35 @@ +import UIKit +import ComponentKit + +class BorderedEmptyCell: EmptyCell { + + let topBorder = UIView() + let bottomBorder = UIView() + + override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(topBorder) + topBorder.snp.makeConstraints { maker in + maker.leading.top.trailing.equalToSuperview() + maker.height.equalTo(CGFloat.heightOnePixel) + } + + topBorder.backgroundColor = .themeSteel20 + topBorder.isHidden = true + + contentView.addSubview(bottomBorder) + bottomBorder.snp.makeConstraints { maker in + maker.leading.bottom.trailing.equalToSuperview() + maker.height.equalTo(CGFloat.heightOnePixel) + } + + bottomBorder.backgroundColor = .themeSteel20 + bottomBorder.isHidden = true + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings b/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings index dfff4480c6..e96b72fb81 100644 --- a/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings +++ b/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings @@ -473,11 +473,12 @@ // Donate "donate.list.title" = "Donate with"; -"donate.list.get_address" = "Get Address"; +"donate.list.get_address" = "Get Donate Address"; "donate.list.get_address.title" = "Addresses"; "donate.title" = "Donate %@"; "donate.no_assets" = "You have no assets to donate."; "donate.support.description" = "Together, with your support, we can make this app even better!"; +"donate.support.bottom_description" = "Or select a coin to donate"; // CoinSelector