Merge pull request #3330 from vladyslav-iosdev/#3283

Show the camera right away (or go back) instead of an empty WalletConnect session screen #3283
pull/3337/head
Hwee-Boon Yar 3 years ago committed by GitHub
commit 5b3dcc5d11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      AlphaWallet.xcodeproj/project.pbxproj
  2. 2
      AlphaWallet/Activities/Views/ActivitiesView.swift
  3. 5
      AlphaWallet/Alerts/ViewModels/PriceAlertsPageViewModel.swift
  4. 2
      AlphaWallet/Alerts/Views/PriceAlertsPageView.swift
  5. 21
      AlphaWallet/Assets.xcassets/iconsIllustrationsEmptyWalletConnect.imageset/Contents.json
  6. BIN
      AlphaWallet/Assets.xcassets/iconsIllustrationsEmptyWalletConnect.imageset/iconsIllustrationsEmptyWalletConnect.pdf
  7. 21
      AlphaWallet/Assets.xcassets/iconsIllustrationsSearchResults.imageset/Contents.json
  8. BIN
      AlphaWallet/Assets.xcassets/iconsIllustrationsSearchResults.imageset/iconsIllustrationsSearchResults.pdf
  9. 5
      AlphaWallet/Localization/en.lproj/Localizable.strings
  10. 5
      AlphaWallet/Localization/es.lproj/Localizable.strings
  11. 5
      AlphaWallet/Localization/ja.lproj/Localizable.strings
  12. 5
      AlphaWallet/Localization/ko.lproj/Localizable.strings
  13. 5
      AlphaWallet/Localization/zh-Hans.lproj/Localizable.strings
  14. 5
      AlphaWallet/Tokens/ViewControllers/AddHideTokensViewController.swift
  15. 10
      AlphaWallet/Tokens/ViewControllers/SelectTokenViewController.swift
  16. 2
      AlphaWallet/Tokens/ViewControllers/TokensViewController.swift
  17. 5
      AlphaWallet/Transactions/ViewControllers/TransactionsViewController.swift
  18. 74
      AlphaWallet/Transactions/Views/TransactionsEmptyView.swift
  19. 2
      AlphaWallet/UI/Button.swift
  20. 202
      AlphaWallet/UI/EmptyView.swift
  21. 12
      AlphaWallet/WalletConnect/Coordinator/WalletConnectCoordinator.swift
  22. 4
      AlphaWallet/WalletConnect/View/WalletConnectSessionCell.swift
  23. 3
      AlphaWallet/WalletConnect/ViewController/WalletConnectSessionDetailsViewController.swift
  24. 53
      AlphaWallet/WalletConnect/ViewController/WalletConnectSessionsViewController.swift
  25. 6
      AlphaWallet/WalletConnect/WalletConnectServer.swift

@ -58,7 +58,6 @@
294EC1DA1FD8E4E60065EB20 /* GasPriceRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294EC1D91FD8E4E60065EB20 /* GasPriceRequest.swift */; };
295247DF1F8326EF007FDC31 /* AccountViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295247DE1F8326EF007FDC31 /* AccountViewCell.swift */; };
295996031FAA865800DB66A8 /* TokensCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295996021FAA865800DB66A8 /* TokensCoordinatorTests.swift */; };
2959960E1FAB05C200DB66A8 /* TransactionsEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2959960D1FAB05C100DB66A8 /* TransactionsEmptyView.swift */; };
2959961C1FAE3EDF00DB66A8 /* AlphaWalletService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2959961B1FAE3EDF00DB66A8 /* AlphaWalletService.swift */; };
2959961F1FAE759700DB66A8 /* RawTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2959961E1FAE759700DB66A8 /* RawTransaction.swift */; };
295A59381F71C1B90092F0FC /* AccountsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 295A59371F71C1B90092F0FC /* AccountsCoordinator.swift */; };
@ -1080,7 +1079,6 @@
294EC1D91FD8E4E60065EB20 /* GasPriceRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GasPriceRequest.swift; sourceTree = "<group>"; };
295247DE1F8326EF007FDC31 /* AccountViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewCell.swift; sourceTree = "<group>"; };
295996021FAA865800DB66A8 /* TokensCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensCoordinatorTests.swift; sourceTree = "<group>"; };
2959960D1FAB05C100DB66A8 /* TransactionsEmptyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsEmptyView.swift; sourceTree = "<group>"; };
2959961B1FAE3EDF00DB66A8 /* AlphaWalletService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlphaWalletService.swift; sourceTree = "<group>"; };
2959961E1FAE759700DB66A8 /* RawTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawTransaction.swift; sourceTree = "<group>"; };
295A59371F71C1B90092F0FC /* AccountsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsCoordinator.swift; sourceTree = "<group>"; };
@ -2569,7 +2567,6 @@
8736214B264D3AFF00AAF794 /* XYMarkerView.swift */,
29E2E33D1F7A2423000CF94A /* TransactionHeaderView.swift */,
293B8B441F70A20200356286 /* TransactionViewCell.swift */,
2959960D1FAB05C100DB66A8 /* TransactionsEmptyView.swift */,
87713EAF264BAB2500B1B9CB /* TokenPagesContainerView.swift */,
87713EB1264BAB4700B1B9CB /* TokenInfoPageView.swift */,
87713EB3264BAB5A00B1B9CB /* ActivityPageView.swift */,
@ -5567,7 +5564,6 @@
CCA4FE381FD428B300749AE4 /* JailbreakChecker.swift in Sources */,
8757E5DC25DD162E00812392 /* SignatureConfirmationViewController.swift in Sources */,
291A1B651F974E8600ADEC80 /* WalletEntryPoint.swift in Sources */,
2959960E1FAB05C200DB66A8 /* TransactionsEmptyView.swift in Sources */,
29BB94931F6FC380009B09CC /* BalanceViewModel.swift in Sources */,
8736214D264D3B0000AAF794 /* XYMarkerView.swift in Sources */,
29D03F1D1F712183006E548C /* Button.swift in Sources */,

@ -45,7 +45,7 @@ class ActivitiesView: UIView {
tableView.anchorsConstraint(to: self)
])
emptyView = TransactionsEmptyView(title: R.string.localizable.activityEmpty(), image: R.image.activities_empty_list())
emptyView = EmptyView.activitiesEmptyView()
}
func resetStatefulStateToReleaseObjectToAvoidMemoryLeak() {

@ -8,14 +8,13 @@
import UIKit
struct PriceAlertsPageViewModel {
var title: String { return "Alerts" }
var title: String { return R.string.localizable.priceAlertNavigationTitle() }
var backgroundColor: UIColor = Colors.appWhite
var emptyAlertListTitle: String = "Alerts will appear here"
var alerts: [PriceAlert]
var addNewAlertViewModel: ShowAddHideTokensViewModel {
return .init(addHideTokensIcon: R.image.add_hide_tokens(), addHideTokensTitle: "Add New Price Alert", backgroundColor: R.color.alabaster()!, badgeText: nil)
return .init(addHideTokensIcon: R.image.add_hide_tokens(), addHideTokensTitle: R.string.localizable.priceAlertNewAlert(), backgroundColor: R.color.alabaster()!, badgeText: nil)
}
mutating func removeAlert(indexPath: IndexPath) {

@ -66,7 +66,7 @@ class PriceAlertsPageView: UIView, PageViewType {
addNotificationView.heightAnchor.constraint(equalToConstant: TokensViewController.addHideTokensViewHeight)
])
statefulView.emptyView = TransactionsEmptyView(title: viewModel.emptyAlertListTitle, image: R.image.iconsIllustrationsAlert2(), spacing: 0)
statefulView.emptyView = EmptyView.activitiesEmptyView()
}
required init?(coder: NSCoder) {

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "iconsIllustrationsEmptyWalletConnect.pdf",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "iconsIllustrationsSearchResults.pdf",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -696,3 +696,8 @@
"url.facebook" = "Facebook";
"url.faq" = "faq";
"url.github" = "Github (File an issue)";
"walletConnect.sessions.empty" = "No active WalletConnect sessions";
"walletConnect.sessions.scanQrCode" = "Scan QR Code";
"priceAlert.emptyList" = "Alerts will appear here";
"priceAlert.navigationTitle" = "Alerts";
"priceAlert.newAlert" = "Add New Price Alert";

@ -696,3 +696,8 @@
"url.facebook" = "Facebook";
"url.faq" = "faq";
"url.github" = "Github (File an issue)";
"walletConnect.sessions.empty" = "No active WalletConnect sessions";
"walletConnect.sessions.scanQrCode" = "Scan QR Code";
"priceAlert.emptyList" = "Alerts will appear here";
"priceAlert.navigationTitle" = "Alerts";
"priceAlert.newAlert" = "Add New Price Alert";

@ -696,3 +696,8 @@
"url.facebook" = "Facebook";
"url.faq" = "faq";
"url.github" = "Github (File an issue)";
"walletConnect.sessions.empty" = "No active WalletConnect sessions";
"walletConnect.sessions.scanQrCode" = "Scan QR Code";
"priceAlert.emptyList" = "Alerts will appear here";
"priceAlert.navigationTitle" = "Alerts";
"priceAlert.newAlert" = "Add New Price Alert";

@ -696,3 +696,8 @@
"url.facebook" = "Facebook";
"url.faq" = "faq";
"url.github" = "Github (File an issue)";
"walletConnect.sessions.empty" = "No active WalletConnect sessions";
"walletConnect.sessions.scanQrCode" = "Scan QR Code";
"priceAlert.emptyList" = "Alerts will appear here";
"priceAlert.navigationTitle" = "Alerts";
"priceAlert.newAlert" = "Add New Price Alert";

@ -696,3 +696,8 @@
"url.facebook" = "Facebook";
"url.faq" = "faq";
"url.github" = "Github (File an issue)";
"walletConnect.sessions.empty" = "No active WalletConnect sessions";
"walletConnect.sessions.scanQrCode" = "Scan QR Code";
"priceAlert.emptyList" = "Alerts will appear here";
"priceAlert.navigationTitle" = "Alerts";
"priceAlert.newAlert" = "Add New Price Alert";

@ -51,12 +51,11 @@ class AddHideTokensViewController: UIViewController {
hidesBottomBarWhenPushed = true
searchController.delegate = self
let t = R.string.localizable.seachTokenNoresultsTitle()
emptyView = EmptyFilteringResultView(title: t, onRetry: { [weak self] in
emptyView = EmptyView.filterTokensEmptyView(completion: { [weak self] in
guard let strongSelf = self, let delegate = strongSelf.delegate else { return }
delegate.didPressAddToken(in: strongSelf)
})
})
view.addSubview(tableView)

@ -63,12 +63,10 @@ class SelectTokenViewController: UIViewController {
})
loadingView = LoadingView()
emptyView = EmptyView(
title: R.string.localizable.emptyViewNoTokensLabelTitle(),
onRetry: { [weak self] in
self?.startLoading()
self?.tokenCollection.fetch()
})
emptyView = EmptyView.tokensEmptyView(completion: { [weak self] in
self?.startLoading()
self?.tokenCollection.fetch()
})
configure(viewModel: viewModel)
}

@ -238,7 +238,7 @@ class TokensViewController: UIViewController {
self?.tokenCollection.fetch()
})
loadingView = LoadingView()
emptyView = EmptyView(title: R.string.localizable.emptyViewNoTokensLabelTitle(), onRetry: { [weak self] in
emptyView = EmptyView.tokensEmptyView(completion: { [weak self] in
self?.startLoading()
self?.tokenCollection.fetch()
})

@ -64,10 +64,7 @@ class TransactionsViewController: UIViewController {
loadingView.loadingIndicator.color = Colors.appWhite
loadingView.label.font = Fonts.regular(size: 18)
}
emptyView = {
let view = TransactionsEmptyView()
return view
}()
emptyView = EmptyView.transactionsEmptyView()
}
override func viewWillAppear(_ animated: Bool) {

@ -1,74 +0,0 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import UIKit
import StatefulViewController
class TransactionsEmptyView: UIView {
private let titleLabel = UILabel()
private let imageView = UIImageView()
private let button = Button(size: .normal, style: .solid)
private let insets: UIEdgeInsets
private var onRetry: (() -> Void)? = .none
private let viewModel = StateViewModel()
init(
title: String = R.string.localizable.transactionsNoTransactionsLabelTitle(),
image: UIImage? = R.image.no_transactions_mascot(),
insets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0),
spacing: CGFloat = 30,
onRetry: (() -> Void)? = .none
) {
self.insets = insets
self.onRetry = onRetry
super.init(frame: .zero)
backgroundColor = .white
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.text = title
titleLabel.font = viewModel.descriptionFont
titleLabel.textColor = viewModel.descriptionTextColor
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = image
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(R.string.localizable.refresh(), for: .normal)
button.addTarget(self, action: #selector(retry), for: .touchUpInside)
let stackView = [
imageView,
titleLabel,
].asStackView(axis: .vertical, spacing: spacing, alignment: .center)
stackView.translatesAutoresizingMaskIntoConstraints = false
if onRetry != nil {
stackView.addArrangedSubview(button)
}
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
button.widthAnchor.constraint(equalToConstant: 180),
])
}
@objc func retry() {
onRetry?()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension TransactionsEmptyView: StatefulPlaceholderView {
func placeholderViewInsets() -> UIEdgeInsets {
return insets
}
}

@ -82,7 +82,7 @@ enum ButtonStyle {
case .solid, .squared: return UIColor(white: 1, alpha: 0.8)
case .border: return Colors.appWhite
case .borderless, .system, .special: return Colors.appTint
case .green: return ButtonsBarViewModel.greenButton.buttonBackgroundColor
case .green: return Colors.appWhite.withAlphaComponent(0.8)
}
}

@ -4,66 +4,101 @@ import Foundation
import UIKit
import StatefulViewController
protocol EmptyViewPlacement {
func resolveContraints(superView: UIView, container: UIView) -> [NSLayoutConstraint]
}
class EmptyView: UIView {
private let titleLabel = UILabel()
private let imageView = UIImageView()
private let button = Button(size: .normal, style: .solid)
private let insets: UIEdgeInsets
private var onRetry: (() -> Void)? = .none
private let viewModel = StateViewModel()
init(
frame: CGRect = .zero,
title: String = R.string.localizable.empty(),
image: UIImage? = R.image.no_transactions_mascot(),
insets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0),
onRetry: (() -> Void)? = .none
) {
self.insets = insets
self.onRetry = onRetry
super.init(frame: frame)
private let stackView: UIStackView = [].asStackView(axis: .vertical, spacing: 30, alignment: .center)
private var titleLabel: UILabel?
private var imageView: UIImageView?
private var button: Button?
private var insets: UIEdgeInsets = .zero
private var buttonSelectionClosure: (() -> Void)? = .none
private var placementConstraints: [NSLayoutConstraint] = []
backgroundColor = .white
init(placement: EmptyViewPlacement = EmptyViewDefaultPlacement()) {
super.init(frame: .zero)
backgroundColor = Colors.appBackground
stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.text = title
titleLabel.font = viewModel.descriptionFont
titleLabel.textColor = viewModel.descriptionTextColor
placementConstraints = placement.resolveContraints(superView: self, container: stackView)
NSLayoutConstraint.activate(placementConstraints)
}
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = image
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(R.string.localizable.refresh(), for: .normal)
button.addTarget(self, action: #selector(retry), for: .touchUpInside)
func configure(title: String?) -> Self {
let attributedTitle = title.flatMap { value in
return NSAttributedString.init(string: value, attributes: [
.foregroundColor: Colors.appText,
.font: Fonts.regular(size: 16)
])
}
return configure(attributedTitle: attributedTitle)
}
let stackView = [
imageView,
titleLabel,
].asStackView(axis: .vertical, spacing: 30, alignment: .center)
stackView.translatesAutoresizingMaskIntoConstraints = false
func configure(attributedTitle: NSAttributedString?) -> Self {
self.titleLabel = attributedTitle.flatMap { attributedTitle -> UILabel in
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.attributedText = attributedTitle
if onRetry != nil {
stackView.addArrangedSubview(button)
return label
}
return build()
}
addSubview(stackView)
func configure(image: UIImage?) -> Self {
self.imageView = image.flatMap { image -> UIImageView in
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = image
NSLayoutConstraint.activate([
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
button.widthAnchor.constraint(equalToConstant: 160),
])
return imageView
}
return build()
}
@objc func retry() {
onRetry?()
func configure(buttonTitle title: String?, width: CGFloat = 180, size: ButtonSize = .large, style: ButtonStyle = .green, buttonSelectionClosure: (() -> Void)?) -> Self {
self.buttonSelectionClosure = buttonSelectionClosure
self.button = title.flatMap { title -> Button in
let button = Button(size: size, style: style)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(title, for: .normal)
button.addTarget(self, action: #selector(buttonSelected), for: .touchUpInside)
NSLayoutConstraint.activate([
button.widthAnchor.constraint(equalToConstant: width)
])
return button
}
return build()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@objc private func buttonSelected(_ sender: UIButton) {
buttonSelectionClosure?()
}
func configure(insets: UIEdgeInsets) -> Self {
self.insets = insets
return build()
}
func configure(spacing: CGFloat) -> Self {
stackView.spacing = spacing
return build()
}
func build() -> Self {
stackView.removeAllArrangedSubviews()
stackView.addArrangedSubviews([imageView, titleLabel, button].compactMap({ $0 }))
return self
}
}
@ -72,3 +107,78 @@ extension EmptyView: StatefulPlaceholderView {
return insets
}
}
final class EmptyViewDefaultPlacement: EmptyViewPlacement {
func resolveContraints(superView: UIView, container: UIView) -> [NSLayoutConstraint] {
return [
container.trailingAnchor.constraint(equalTo: superView.trailingAnchor),
container.leadingAnchor.constraint(equalTo: superView.leadingAnchor),
container.centerXAnchor.constraint(equalTo: superView.centerXAnchor),
container.centerYAnchor.constraint(equalTo: superView.centerYAnchor),
]
}
}
final class FilterTokensEmptyViewDefaultPlacement: EmptyViewPlacement {
func resolveContraints(superView: UIView, container: UIView) -> [NSLayoutConstraint] {
return [
container.trailingAnchor.constraint(equalTo: superView.trailingAnchor),
container.leadingAnchor.constraint(equalTo: superView.leadingAnchor),
container.centerXAnchor.constraint(equalTo: superView.centerXAnchor),
container.bottomAnchor.constraint(equalTo: superView.centerYAnchor, constant: -30)
]
}
}
extension EmptyView {
static func tokensEmptyView(completion: @escaping () -> Void) -> EmptyView {
EmptyView()
.configure(image: R.image.no_transactions_mascot())
.configure(title: R.string.localizable.emptyViewNoTokensLabelTitle())
.configure(buttonTitle: R.string.localizable.refresh(), width: 240, buttonSelectionClosure: completion)
.configure(spacing: 30)
.configure(insets: .zero)
}
static func walletSessionEmptyView(completion: @escaping () -> Void) -> EmptyView {
EmptyView()
.configure(spacing: 24)
.configure(insets: .zero)
.configure(image: R.image.iconsIllustrationsEmptyWalletConnect())
.configure(title: R.string.localizable.walletConnectSessionsEmpty())
.configure(buttonTitle: R.string.localizable.walletConnectSessionsScanQrCode(), width: 240, buttonSelectionClosure: completion)
}
static func transactionsEmptyView() -> EmptyView {
EmptyView()
.configure(image: R.image.no_transactions_mascot())
.configure(title: R.string.localizable.emptyViewNoTokensLabelTitle())
.configure(spacing: 30)
.configure(insets: .zero)
}
static func activitiesEmptyView() -> EmptyView {
EmptyView()
.configure(image: R.image.activities_empty_list())
.configure(title: R.string.localizable.activityEmpty())
.configure(spacing: 30)
.configure(insets: .zero)
}
static func priceAlertsEmpryView() -> EmptyView {
EmptyView()
.configure(image: R.image.iconsIllustrationsAlert2())
.configure(title: R.string.localizable.activityEmpty())
.configure(spacing: 0)
.configure(insets: .zero)
}
static func filterTokensEmptyView(completion: @escaping () -> Void) -> EmptyView {
EmptyView(placement: FilterTokensEmptyViewDefaultPlacement())
.configure(image: R.image.iconsIllustrationsSearchResults())
.configure(title: R.string.localizable.seachTokenNoresultsTitle())
.configure(buttonTitle: R.string.localizable.addCustomTokenTitle(), width: 240, buttonSelectionClosure: completion)
.configure(spacing: 30)
.configure(insets: .zero)
}
}

@ -18,7 +18,7 @@ enum SessionsToDisconnect {
case all
}
typealias SessionsToURLServersMap = (sessions: [WalletConnectSession], urlToServer: [WCURL: RPCServer])
typealias SessionsToURLServersMap = (sessions: [WalletConnectSession], urlToServer: [WalletConnectURL: RPCServer])
protocol WalletConnectCoordinatorDelegate: class, CanOpenURL {
func universalScannerSelected(in coordinator: WalletConnectCoordinator)
@ -121,6 +121,11 @@ class WalletConnectCoordinator: NSObject, Coordinator {
func showSessions() {
navigationController.setNavigationBarHidden(false, animated: false)
showSessions(state: .sessions, navigationController: navigationController)
let sessions = server.sessions.value ?? []
if sessions.isEmpty {
startUniversalScanner()
}
}
private func showSessions(state: WalletConnectSessionsViewController.State, navigationController: UINavigationController, completion: @escaping (() -> Void) = {}) {
@ -373,9 +378,12 @@ extension WalletConnectCoordinator: WalletConnectServerDelegate {
}
extension WalletConnectCoordinator: WalletConnectSessionsViewControllerDelegate {
func startUniversalScanner() {
delegate?.universalScannerSelected(in: self)
}
func qrCodeSelected(in viewController: WalletConnectSessionsViewController) {
delegate?.universalScannerSelected(in: self)
startUniversalScanner()
}
func didClose(in viewController: WalletConnectSessionsViewController) {

@ -13,8 +13,8 @@ class WalletConnectSessionCell: UITableViewCell {
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.anchorsConstraint(to: contentView, edgeInsets: .init(top: 7, left: StyleLayout.sideMargin, bottom: 7, right: StyleLayout.sideMargin)),
stackView.heightAnchor.constraint(equalToConstant: 44),
//NOTE: using edge insets to avoid braking constraints
stackView.anchorsConstraint(to: contentView, edgeInsets: .init(top: 20, left: StyleLayout.sideMargin, bottom: 20, right: StyleLayout.sideMargin))
])
}

@ -5,8 +5,7 @@
// Created by Vladyslav Shepitko on 02.07.2020.
//
import UIKit
import WalletConnectSwift
import UIKit
import Kingfisher
protocol WalletConnectSessionViewControllerDelegate: AnyObject {

@ -1,6 +1,7 @@
// Copyright © 2020 Stormbird PTE. LTD.
import UIKit
import StatefulViewController
protocol WalletConnectSessionsViewControllerDelegate: AnyObject {
func didSelect(session: WalletConnectSession, in viewController: WalletConnectSessionsViewController)
@ -33,11 +34,14 @@ class WalletConnectSessionsViewController: UIViewController {
tableView.tableFooterView = UIView.tableFooterToRemoveEmptyCellSeparators()
tableView.separatorInset = .zero
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = GroupedTable.Color.background
return tableView
}()
weak var delegate: WalletConnectSessionsViewControllerDelegate?
private let roundedBackground = RoundedBackground()
private lazy var spinner: UIActivityIndicatorView = {
let view = UIActivityIndicatorView(style: .gray)
view.translatesAutoresizingMaskIntoConstraints = false
@ -45,25 +49,40 @@ class WalletConnectSessionsViewController: UIViewController {
view.tintColor = .red
return view
}()
private var state: State = .sessions
init(sessionsToURLServersMap: Subscribable<SessionsToURLServersMap>) {
self.sessionsToURLServersMap = sessionsToURLServersMap
super.init(nibName: nil, bundle: nil)
view.addSubview(tableView)
view.addSubview(spinner)
roundedBackground.backgroundColor = GroupedTable.Color.background
view.addSubview(roundedBackground)
roundedBackground.addSubview(tableView)
roundedBackground.addSubview(spinner)
sessionsToURLServersMap.subscribe { [weak self] _ in
self?.tableView.reloadData()
self?.endLoading()
}
NSLayoutConstraint.activate([
tableView.anchorsConstraint(to: view),
tableView.leadingAnchor.constraint(equalTo: roundedBackground.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: roundedBackground.trailingAnchor),
tableView.topAnchor.constraint(equalTo: roundedBackground.topAnchor),
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
spinner.centerXAnchor.constraint(equalTo: tableView.centerXAnchor),
spinner.centerYAnchor.constraint(equalTo: tableView.centerYAnchor)
])
] + roundedBackground.createConstraintsWithContainer(view: view))
navigationItem.leftBarButtonItem = UIBarButtonItem.backBarButton(self, selector: #selector(closeButtonSelected))
navigationItem.rightBarButtonItem = UIBarButtonItem.qrCodeBarButton(self, selector: #selector(qrCodeButtonSelected))
emptyView = EmptyView.walletSessionEmptyView(completion: { [weak self] in
guard let strongSelf = self else { return }
strongSelf.delegate?.qrCodeSelected(in: strongSelf)
})
}
required init?(coder aDecoder: NSCoder) {
@ -75,6 +94,10 @@ class WalletConnectSessionsViewController: UIViewController {
navigationItem.largeTitleDisplayMode = .never
hidesBottomBarWhenPushed = true
if let host = emptyView {
spinner.bringSubviewToFront(host)
}
}
func configure(state: State) {
@ -83,24 +106,34 @@ class WalletConnectSessionsViewController: UIViewController {
}
func set(state: State) {
self.state = state
switch state {
case .loading:
spinner.startAnimating()
case .sessions:
spinner.stopAnimating()
}
self.endLoading()
}
@objc private func qrCodeButtonSelected(_ sender: UIBarButtonItem) {
guard let delegate = self.delegate else { return }
delegate.qrCodeSelected(in: self)
delegate?.qrCodeSelected(in: self)
}
@objc private func closeButtonSelected(_ sender: UIBarButtonItem) {
guard let delegate = self.delegate else { return }
delegate?.didClose(in: self)
}
}
delegate.didClose(in: self)
extension WalletConnectSessionsViewController: StatefulViewController {
func hasContent() -> Bool {
switch state {
case .sessions:
return !sessionsValue.isEmpty
case .loading:
return true
}
}
}

@ -79,7 +79,7 @@ class WalletConnectServer {
}
}
var urlToServer: [WCURL: RPCServer] {
var urlToServer: [WalletConnectURL: RPCServer] {
UserDefaults.standard.urlToServer
}
var sessions: Subscribable<[WalletConnectSession]> = Subscribable([])
@ -342,12 +342,12 @@ extension WalletConnectServer: ServerDelegate {
}
struct WalletConnectConnection {
let url: WCURL
let url: WalletConnectURL
let name: String
let icon: URL?
let server: RPCServer?
init(dAppInfo info: Session.DAppInfo, url: WCURL) {
init(dAppInfo info: Session.DAppInfo, url: WalletConnectURL) {
self.url = url
name = info.peerMeta.name
icon = info.peerMeta.icons.first

Loading…
Cancel
Save