Merge pull request #2539 from vladyslav-iosdev/#2517
Need to show WalletConnect is loading instead of not showing anything #2517pull/2527/head
commit
55184cb27c
@ -0,0 +1,52 @@ |
||||
// |
||||
// WalletConnectToSessionCoordinatorBridgeToPromise.swift |
||||
// AlphaWallet |
||||
// |
||||
// Created by Vladyslav Shepitko on 18.02.2021. |
||||
// |
||||
|
||||
import PromiseKit |
||||
|
||||
private class WalletConnectToSessionCoordinatorBridgeToPromise { |
||||
|
||||
private let (promiseToReturn, seal) = Promise<WalletConnectServer.ConnectionChoice>.pending() |
||||
private var retainCycle: WalletConnectToSessionCoordinatorBridgeToPromise? |
||||
|
||||
init(navigationController: UINavigationController, coordinator: Coordinator, connection: WalletConnectConnection, serverChoices: [RPCServer]) { |
||||
retainCycle = self |
||||
|
||||
let newCoordinator = WalletConnectToSessionCoordinator(connection: connection, navigationController: navigationController, serverChoices: serverChoices) |
||||
newCoordinator.delegate = self |
||||
coordinator.addCoordinator(newCoordinator) |
||||
|
||||
_ = promiseToReturn.ensure { |
||||
// ensure we break the retain cycle |
||||
self.retainCycle = nil |
||||
coordinator.removeCoordinator(newCoordinator) |
||||
} |
||||
|
||||
newCoordinator.start() |
||||
} |
||||
|
||||
var promise: Promise<WalletConnectServer.ConnectionChoice> { |
||||
return promiseToReturn |
||||
} |
||||
} |
||||
|
||||
extension WalletConnectToSessionCoordinatorBridgeToPromise: WalletConnectToSessionCoordinatorDelegate { |
||||
func coordinator(_ coordinator: WalletConnectToSessionCoordinator, didCompleteWithConnection result: WalletConnectServer.ConnectionChoice) { |
||||
seal.fulfill(result) |
||||
} |
||||
} |
||||
|
||||
extension WalletConnectToSessionCoordinator { |
||||
|
||||
static func promise(_ navigationController: UINavigationController, coordinator: Coordinator, connection: WalletConnectConnection, serverChoices: [RPCServer]) -> Promise<WalletConnectServer.ConnectionChoice> { |
||||
return WalletConnectToSessionCoordinatorBridgeToPromise( |
||||
navigationController: navigationController, |
||||
coordinator: coordinator, |
||||
connection: connection, |
||||
serverChoices: serverChoices |
||||
).promise |
||||
} |
||||
} |
@ -0,0 +1,112 @@ |
||||
// |
||||
// WalletConnectToSessionCoordinator.swift |
||||
// AlphaWallet |
||||
// |
||||
// Created by Vladyslav Shepitko on 18.02.2021. |
||||
// |
||||
|
||||
import UIKit |
||||
|
||||
protocol WalletConnectToSessionCoordinatorDelegate: class { |
||||
func coordinator(_ coordinator: WalletConnectToSessionCoordinator, didCompleteWithConnection result: WalletConnectServer.ConnectionChoice) |
||||
} |
||||
|
||||
class WalletConnectToSessionCoordinator: Coordinator { |
||||
var coordinators: [Coordinator] = [] |
||||
|
||||
private let connection: WalletConnectConnection |
||||
private let presentationNavigationController: UINavigationController |
||||
private lazy var viewModel = WalletConnectToSessionViewModel(connection: connection, serverToConnect: serverToConnect) |
||||
private lazy var viewController: WalletConnectToSessionViewController = { |
||||
let viewController = WalletConnectToSessionViewController(viewModel: viewModel) |
||||
viewController.delegate = self |
||||
|
||||
return viewController |
||||
}() |
||||
private lazy var navigationController: UINavigationController = { |
||||
let controller = UINavigationController(rootViewController: viewController) |
||||
controller.modalPresentationStyle = .overFullScreen |
||||
controller.modalTransitionStyle = .crossDissolve |
||||
controller.view.backgroundColor = UIColor.black.withAlphaComponent(0.6) |
||||
|
||||
return controller |
||||
}() |
||||
private var serverToConnect: RPCServer |
||||
private let serverChoices: [RPCServer] |
||||
weak var delegate: WalletConnectToSessionCoordinatorDelegate? |
||||
|
||||
init(connection: WalletConnectConnection, navigationController: UINavigationController, serverChoices: [RPCServer]) { |
||||
self.connection = connection |
||||
self.serverToConnect = connection.server ?? .main |
||||
self.presentationNavigationController = navigationController |
||||
self.serverChoices = serverChoices |
||||
} |
||||
|
||||
func start() { |
||||
presentationNavigationController.present(navigationController, animated: false) |
||||
viewController.configure(for: viewModel) |
||||
viewController.reloadView() |
||||
} |
||||
|
||||
func dissmissAnimated(completion: @escaping () -> Void) { |
||||
viewController.dismissViewAnimated { |
||||
//Needs a strong self reference otherwise `self` might have been removed by its owner by the time animation completes and the `completion` block not called |
||||
self.navigationController.dismiss(animated: true, completion: completion) |
||||
} |
||||
} |
||||
} |
||||
|
||||
extension WalletConnectToSessionCoordinator: WalletConnectToSessionViewControllerDelegate { |
||||
|
||||
func changeConnectionServerSelected(in controller: WalletConnectToSessionViewController) { |
||||
showAvailableToConnectServers(completion: { [weak self] result in |
||||
guard let strongSelf = self else { return } |
||||
|
||||
switch result { |
||||
case .connect(let server): |
||||
strongSelf.serverToConnect = server |
||||
strongSelf.viewModel.set(serverToConnect: server) |
||||
case .cancel: |
||||
break |
||||
} |
||||
|
||||
strongSelf.viewController.configure(for: strongSelf.viewModel) |
||||
strongSelf.viewController.reloadView() |
||||
}) |
||||
} |
||||
|
||||
func controller(_ controller: WalletConnectToSessionViewController, continueButtonTapped sender: UIButton) { |
||||
dissmissAnimated(completion: { |
||||
guard let delegate = self.delegate else { return } |
||||
|
||||
delegate.coordinator(self, didCompleteWithConnection: .connect(self.serverToConnect)) |
||||
}) |
||||
} |
||||
|
||||
func didClose(in controller: WalletConnectToSessionViewController) { |
||||
navigationController.dismiss(animated: false) { [weak self] in |
||||
guard let strongSelf = self, let delegate = strongSelf.delegate else { return } |
||||
|
||||
delegate.coordinator(strongSelf, didCompleteWithConnection: .cancel) |
||||
} |
||||
} |
||||
|
||||
private func showAvailableToConnectServers(completion: @escaping (WalletConnectServer.ConnectionChoice) -> Void) { |
||||
let style: UIAlertController.Style = UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet |
||||
let alertViewController = UIAlertController(title: connection.name, message: R.string.localizable.walletConnectStart(connection.url.absoluteString), preferredStyle: style) |
||||
for each in serverChoices { |
||||
let action = UIAlertAction(title: each.name, style: .default) { _ in |
||||
completion(.connect(each)) |
||||
} |
||||
alertViewController.addAction(action) |
||||
} |
||||
|
||||
let cancelAction = UIAlertAction(title: R.string.localizable.cancel(), style: .cancel) { _ in |
||||
completion(.cancel) |
||||
} |
||||
alertViewController.addAction(cancelAction) |
||||
|
||||
navigationController.present(alertViewController, animated: true) |
||||
} |
||||
|
||||
} |
@ -0,0 +1,395 @@ |
||||
// |
||||
// WalletConnectToSessionViewController.swift |
||||
// AlphaWallet |
||||
// |
||||
// Created by Vladyslav Shepitko on 17.02.2021. |
||||
// |
||||
|
||||
import UIKit |
||||
|
||||
protocol WalletConnectToSessionViewControllerDelegate: class { |
||||
func controller(_ controller: WalletConnectToSessionViewController, continueButtonTapped sender: UIButton) |
||||
func changeConnectionServerSelected(in controller: WalletConnectToSessionViewController) |
||||
|
||||
func didClose(in controller: WalletConnectToSessionViewController) |
||||
} |
||||
|
||||
class WalletConnectToSessionViewController: UIViewController { |
||||
private lazy var headerView: HeaderView = HeaderView(viewModel: .init(title: viewModel.navigationTitle)) |
||||
private let buttonsBar = ButtonsBar(configuration: .custom(types: [.green, .white])) |
||||
private var viewModel: WalletConnectToSessionViewModel |
||||
|
||||
private let stackView: UIStackView = { |
||||
let stackView = UIStackView() |
||||
stackView.axis = .vertical |
||||
stackView.spacing = 0 |
||||
stackView.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
return stackView |
||||
}() |
||||
|
||||
private lazy var scrollView: UIScrollView = { |
||||
let scrollView = UIScrollView() |
||||
scrollView.translatesAutoresizingMaskIntoConstraints = false |
||||
scrollView.addSubview(stackView) |
||||
return scrollView |
||||
}() |
||||
|
||||
private let separatorLine: UIView = { |
||||
let view = UIView() |
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
view.backgroundColor = R.color.mercury() |
||||
|
||||
return view |
||||
}() |
||||
|
||||
private var contentSizeObservation: NSKeyValueObservation? |
||||
|
||||
private lazy var footerBar: UIView = { |
||||
let view = UIView() |
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
view.backgroundColor = viewModel.footerBackgroundColor |
||||
view.addSubview(buttonsBar) |
||||
|
||||
return view |
||||
}() |
||||
|
||||
private lazy var backgroundView: UIView = { |
||||
let view = UIView() |
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
view.backgroundColor = .clear |
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissViewController)) |
||||
view.isUserInteractionEnabled = true |
||||
view.addGestureRecognizer(tap) |
||||
|
||||
return view |
||||
}() |
||||
|
||||
private lazy var containerView: UIView = { |
||||
let view = UIView() |
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
view.backgroundColor = .white |
||||
|
||||
view.addSubview(scrollView) |
||||
view.addSubview(footerBar) |
||||
view.addSubview(headerView) |
||||
view.addSubview(separatorLine) |
||||
|
||||
return view |
||||
}() |
||||
|
||||
private lazy var heightConstraint: NSLayoutConstraint = { |
||||
return containerView.heightAnchor.constraint(equalToConstant: preferredContentSize.height) |
||||
}() |
||||
|
||||
private lazy var bottomConstraint: NSLayoutConstraint = { |
||||
containerView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor) |
||||
}() |
||||
|
||||
private var allowPresentationAnimation: Bool = true |
||||
private var allowDismissalAnimation: Bool = true |
||||
|
||||
weak var delegate: WalletConnectToSessionViewControllerDelegate? |
||||
|
||||
init(viewModel: WalletConnectToSessionViewModel) { |
||||
self.viewModel = viewModel |
||||
super.init(nibName: nil, bundle: nil) |
||||
|
||||
view.addSubview(backgroundView) |
||||
view.addSubview(containerView) |
||||
|
||||
NSLayoutConstraint.activate([ |
||||
backgroundView.bottomAnchor.constraint(equalTo: containerView.topAnchor), |
||||
backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor), |
||||
backgroundView.topAnchor.constraint(equalTo: view.topAnchor), |
||||
backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor), |
||||
|
||||
heightConstraint, |
||||
bottomConstraint, |
||||
containerView.safeAreaLayoutGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor), |
||||
containerView.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor), |
||||
|
||||
headerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), |
||||
headerView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), |
||||
headerView.topAnchor.constraint(equalTo: containerView.topAnchor), |
||||
|
||||
scrollView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), |
||||
scrollView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), |
||||
scrollView.topAnchor.constraint(equalTo: headerView.bottomAnchor), |
||||
scrollView.bottomAnchor.constraint(equalTo: footerBar.topAnchor), |
||||
|
||||
stackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), |
||||
stackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), |
||||
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor), |
||||
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), |
||||
|
||||
separatorLine.heightAnchor.constraint(equalToConstant: DataEntry.Metric.TransactionConfirmation.separatorHeight), |
||||
separatorLine.bottomAnchor.constraint(equalTo: footerBar.topAnchor), |
||||
separatorLine.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor), |
||||
separatorLine.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor), |
||||
|
||||
footerBar.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), |
||||
footerBar.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), |
||||
footerBar.heightAnchor.constraint(equalToConstant: DataEntry.Metric.TransactionConfirmation.footerHeight), |
||||
footerBar.bottomAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.bottomAnchor), |
||||
|
||||
buttonsBar.topAnchor.constraint(equalTo: footerBar.topAnchor, constant: 20), |
||||
buttonsBar.leadingAnchor.constraint(equalTo: footerBar.leadingAnchor), |
||||
buttonsBar.trailingAnchor.constraint(equalTo: footerBar.trailingAnchor), |
||||
buttonsBar.heightAnchor.constraint(equalToConstant: ButtonsBar.buttonsHeight), |
||||
]) |
||||
headerView.closeButton.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) |
||||
|
||||
contentSizeObservation = scrollView.observe(\.contentSize, options: [.new, .initial]) { [weak self] scrollView, _ in |
||||
guard let strongSelf = self, strongSelf.allowDismissalAnimation else { return } |
||||
|
||||
let statusBarHeight = UIApplication.shared.statusBarFrame.height |
||||
let contentHeight = scrollView.contentSize.height + DataEntry.Metric.TransactionConfirmation.footerHeight + DataEntry.Metric.TransactionConfirmation.headerHeight + UIApplication.shared.bottomSafeAreaHeight |
||||
let newHeight = min(UIScreen.main.bounds.height - statusBarHeight, contentHeight) |
||||
|
||||
let fillScreenPercentage = strongSelf.heightConstraint.constant / strongSelf.view.bounds.height |
||||
|
||||
if fillScreenPercentage >= 0.9 { |
||||
strongSelf.heightConstraint.constant = strongSelf.containerView.bounds.height |
||||
} else { |
||||
strongSelf.heightConstraint.constant = newHeight |
||||
} |
||||
} |
||||
|
||||
generateSubviews() |
||||
} |
||||
|
||||
override func viewDidLoad() { |
||||
super.viewDidLoad() |
||||
|
||||
configure(for: viewModel) |
||||
|
||||
//NOTE: to display animation correctly we can take 'view.frame.height' and bottom view will smoothly slide up from button ;) |
||||
bottomConstraint.constant = view.frame.height |
||||
} |
||||
|
||||
override func viewWillAppear(_ animated: Bool) { |
||||
super.viewWillAppear(animated) |
||||
|
||||
if let navigationController = navigationController { |
||||
navigationController.setNavigationBarHidden(true, animated: false) |
||||
} |
||||
} |
||||
|
||||
override func viewDidAppear(_ animated: Bool) { |
||||
super.viewDidAppear(animated) |
||||
|
||||
presentViewAnimated() |
||||
} |
||||
|
||||
override func viewWillDisappear(_ animated: Bool) { |
||||
super.viewWillDisappear(animated) |
||||
|
||||
if let navigationController = navigationController { |
||||
navigationController.setNavigationBarHidden(false, animated: false) |
||||
} |
||||
} |
||||
|
||||
private func presentViewAnimated() { |
||||
guard allowPresentationAnimation else { return } |
||||
allowPresentationAnimation = false |
||||
|
||||
bottomConstraint.constant = 0 |
||||
|
||||
UIView.animate(withDuration: 0.4) { |
||||
self.view.layoutIfNeeded() |
||||
} |
||||
} |
||||
|
||||
func dismissViewAnimated(with completion: @escaping () -> Void) { |
||||
guard allowDismissalAnimation else { return } |
||||
allowDismissalAnimation = false |
||||
|
||||
bottomConstraint.constant = heightConstraint.constant |
||||
|
||||
UIView.animate(withDuration: 0.4, animations: { |
||||
self.view.layoutIfNeeded() |
||||
}, completion: { _ in |
||||
completion() |
||||
}) |
||||
} |
||||
|
||||
@objc private func dismissViewController() { |
||||
dismissViewAnimated(with: { |
||||
//NOTE: strong reff is required |
||||
self.delegate?.didClose(in: self) |
||||
}) |
||||
} |
||||
|
||||
func reloadView() { |
||||
generateSubviews() |
||||
} |
||||
|
||||
func configure(for viewModel: WalletConnectToSessionViewModel) { |
||||
self.viewModel = viewModel |
||||
|
||||
scrollView.backgroundColor = viewModel.backgroundColor |
||||
view.backgroundColor = viewModel.backgroundColor |
||||
navigationItem.title = viewModel.title |
||||
|
||||
buttonsBar.configure() |
||||
|
||||
let button1 = buttonsBar.buttons[0] |
||||
button1.shrinkBorderColor = Colors.loadingIndicatorBorder |
||||
button1.setTitle(viewModel.confirmationButtonTitle, for: .normal) |
||||
button1.addTarget(self, action: #selector(confirmButtonTapped), for: .touchUpInside) |
||||
|
||||
let button2 = buttonsBar.buttons[1] |
||||
button2.shrinkBorderColor = Colors.loadingIndicatorBorder |
||||
button2.setTitle(viewModel.rejectionButtonTitle, for: .normal) |
||||
button2.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) |
||||
} |
||||
|
||||
@objc private func confirmButtonTapped(_ sender: UIButton) { |
||||
delegate?.controller(self, continueButtonTapped: sender) |
||||
} |
||||
|
||||
required init?(coder aDecoder: NSCoder) { |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
fileprivate struct HeaderViewModel { |
||||
let title: String |
||||
var backgroundColor: UIColor { |
||||
Colors.appBackground |
||||
} |
||||
var icon: UIImage? { |
||||
return R.image.awLogoSmall() |
||||
} |
||||
var attributedTitle: NSAttributedString { |
||||
let style = NSMutableParagraphStyle() |
||||
style.alignment = .center |
||||
|
||||
return .init(string: title, attributes: [ |
||||
.font: DataEntry.Font.text as Any, |
||||
.paragraphStyle: style, |
||||
.foregroundColor: Colors.darkGray |
||||
]) |
||||
} |
||||
} |
||||
|
||||
fileprivate class HeaderView: UIView { |
||||
private let separatorLine: UIView = { |
||||
let view = UIView() |
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
view.backgroundColor = R.color.mercury() |
||||
|
||||
return view |
||||
}() |
||||
|
||||
private let titleLabel: UILabel = { |
||||
let titleLabel = UILabel(frame: .zero) |
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
return titleLabel |
||||
}() |
||||
|
||||
private let iconImageView: UIImageView = { |
||||
let imageView = UIImageView(frame: .zero) |
||||
imageView.translatesAutoresizingMaskIntoConstraints = false |
||||
imageView.contentMode = .scaleAspectFit |
||||
|
||||
return imageView |
||||
}() |
||||
|
||||
let closeButton: UIButton = { |
||||
let button = UIButton() |
||||
button.translatesAutoresizingMaskIntoConstraints = false |
||||
button.contentMode = .scaleAspectFit |
||||
button.setImage(R.image.close(), for: .normal) |
||||
|
||||
return button |
||||
}() |
||||
|
||||
init(viewModel: HeaderViewModel) { |
||||
super.init(frame: .zero) |
||||
translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
addSubview(separatorLine) |
||||
addSubview(titleLabel) |
||||
addSubview(iconImageView) |
||||
addSubview(closeButton) |
||||
|
||||
NSLayoutConstraint.activate([ |
||||
separatorLine.heightAnchor.constraint(equalToConstant: DataEntry.Metric.TransactionConfirmation.separatorHeight), |
||||
separatorLine.bottomAnchor.constraint(equalTo: bottomAnchor), |
||||
separatorLine.leadingAnchor.constraint(equalTo: leadingAnchor), |
||||
separatorLine.trailingAnchor.constraint(equalTo: trailingAnchor), |
||||
|
||||
titleLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor), |
||||
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor), |
||||
titleLabel.trailingAnchor.constraint(equalTo: closeButton.leadingAnchor), |
||||
|
||||
iconImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), |
||||
iconImageView.centerYAnchor.constraint(equalTo: centerYAnchor), |
||||
iconImageView.widthAnchor.constraint(equalToConstant: 30), |
||||
iconImageView.heightAnchor.constraint(equalToConstant: 30), |
||||
|
||||
closeButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), |
||||
closeButton.centerYAnchor.constraint(equalTo: centerYAnchor), |
||||
closeButton.widthAnchor.constraint(equalToConstant: 30), |
||||
closeButton.heightAnchor.constraint(equalToConstant: 30), |
||||
|
||||
heightAnchor.constraint(equalToConstant: DataEntry.Metric.TransactionConfirmation.headerHeight) |
||||
]) |
||||
|
||||
titleLabel.attributedText = viewModel.attributedTitle |
||||
iconImageView.image = viewModel.icon |
||||
backgroundColor = viewModel.backgroundColor |
||||
} |
||||
|
||||
required init?(coder: NSCoder) { |
||||
return nil |
||||
} |
||||
} |
||||
|
||||
extension WalletConnectToSessionViewController { |
||||
|
||||
private func generateSubviews() { |
||||
stackView.removeAllArrangedSubviews() |
||||
|
||||
var views: [UIView] = [] |
||||
for (sectionIndex, section) in viewModel.sections.enumerated() { |
||||
let header = TransactionConfirmationHeaderView(viewModel: viewModel.headerViewModel(section: sectionIndex)) |
||||
header.delegate = self |
||||
|
||||
switch section { |
||||
case .name, .url: |
||||
break |
||||
case .network: |
||||
if viewModel.allowChangeConnectionServer { |
||||
header.enableTapAction(title: "Edit") |
||||
} |
||||
} |
||||
views.append(header) |
||||
} |
||||
|
||||
stackView.addArrangedSubviews(views) |
||||
} |
||||
} |
||||
|
||||
extension WalletConnectToSessionViewController: TransactionConfirmationHeaderViewDelegate { |
||||
|
||||
func headerView(_ header: TransactionConfirmationHeaderView, shouldHideChildren section: Int, index: Int) -> Bool { |
||||
return true |
||||
} |
||||
|
||||
func headerView(_ header: TransactionConfirmationHeaderView, shouldShowChildren section: Int, index: Int) -> Bool { |
||||
return false |
||||
} |
||||
|
||||
func headerView(_ header: TransactionConfirmationHeaderView, openStateChanged section: Int) { |
||||
//no-op |
||||
} |
||||
|
||||
func headerView(_ header: TransactionConfirmationHeaderView, tappedSection section: Int) { |
||||
delegate?.changeConnectionServerSelected(in: self) |
||||
} |
||||
} |
@ -0,0 +1,84 @@ |
||||
// |
||||
// SignatureConfirmationConfirmationViewModel.swift |
||||
// AlphaWallet |
||||
// |
||||
// Created by Vladyslav Shepitko on 17.02.2021. |
||||
// |
||||
|
||||
import UIKit |
||||
|
||||
struct WalletConnectToSessionViewModel { |
||||
|
||||
private let connection: WalletConnectConnection |
||||
private var serverToConnect: RPCServer |
||||
|
||||
init(connection: WalletConnectConnection, serverToConnect: RPCServer) { |
||||
self.connection = connection |
||||
self.serverToConnect = serverToConnect |
||||
} |
||||
|
||||
mutating func set(serverToConnect: RPCServer) { |
||||
self.serverToConnect = serverToConnect |
||||
} |
||||
|
||||
var navigationTitle: String { |
||||
return R.string.localizable.walletConnectConnectionTitle() |
||||
} |
||||
|
||||
var title: String { |
||||
return R.string.localizable.confirmPaymentConfirmButtonTitle() |
||||
} |
||||
|
||||
var confirmationButtonTitle: String { |
||||
return R.string.localizable.confirmPaymentConfirmButtonTitle() |
||||
} |
||||
|
||||
var rejectionButtonTitle: String { |
||||
return R.string.localizable.confirmPaymentRejectButtonTitle() |
||||
} |
||||
|
||||
var backgroundColor: UIColor { |
||||
return UIColor.clear |
||||
} |
||||
|
||||
var footerBackgroundColor: UIColor { |
||||
return R.color.white()! |
||||
} |
||||
|
||||
var sections: [Section] { |
||||
Section.allCases |
||||
} |
||||
|
||||
enum Section: CaseIterable { |
||||
case name |
||||
case network |
||||
case url |
||||
|
||||
var title: String { |
||||
switch self { |
||||
case .name: |
||||
return "Name" |
||||
case .network: |
||||
return "Network" |
||||
case .url: |
||||
return "Connected To" |
||||
} |
||||
} |
||||
} |
||||
|
||||
var allowChangeConnectionServer: Bool { |
||||
return connection.server == nil |
||||
} |
||||
|
||||
func headerViewModel(section: Int) -> TransactionConfirmationHeaderViewModel { |
||||
let headerName = sections[section].title |
||||
switch sections[section] { |
||||
case .name: |
||||
return .init(title: .normal(connection.name), headerName: headerName, configuration: .init(section: section)) |
||||
case .network: |
||||
return .init(title: .normal(serverToConnect.displayName), headerName: headerName, configuration: .init(section: section)) |
||||
case .url: |
||||
return .init(title: .normal(connection.url.absoluteString), headerName: headerName, configuration: .init(section: section)) |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue