Refresh wallets balances on pull

pull/3273/head
Vladyslav shepitko 3 years ago committed by Vladyslav Shepitko
parent 19b95f8dc8
commit d232ff8f01
  1. 16
      AlphaWallet/Accounts/ViewControllers/AccountsViewController.swift
  2. 28
      AlphaWallet/Core/Coordinators/WalletBalance/PrivateBalanceFetcher.swift
  3. 23
      AlphaWallet/Core/Coordinators/WalletBalance/WalletBalanceCoordinator.swift
  4. 40
      AlphaWallet/Core/Coordinators/WalletBalance/WalletBalanceFetcher.swift
  5. 8
      AlphaWallet/Transactions/Coordinators/BalanceCoordinator.swift
  6. 9
      AlphaWalletTests/Redeem/CreateRedeemTests.swift
  7. 12
      AlphaWalletTests/Settings/Coordinators/SettingsCoordinatorTests.swift

@ -43,6 +43,7 @@ class AccountsViewController: UIViewController {
tableView.rowHeight = UITableView.automaticDimension
tableView.register(AccountViewCell.self)
tableView.register(WalletSummaryTableViewCell.self)
tableView.addSubview(tableViewRefreshControl)
roundedBackground.addSubview(tableView)
NSLayoutConstraint.activate([
@ -53,6 +54,12 @@ class AccountsViewController: UIViewController {
] + roundedBackground.createConstraintsWithContainer(view: view))
}
private lazy var tableViewRefreshControl: UIRefreshControl = {
let control = UIRefreshControl()
control.addTarget(self, action: #selector(pullToRefresh), for: .valueChanged)
return control
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
@ -81,6 +88,15 @@ class AccountsViewController: UIViewController {
}
}
@objc private func pullToRefresh(_ sender: UIRefreshControl) {
tableViewRefreshControl.beginRefreshing()
walletBalanceCoordinator.refreshBalance(updatePolicy: .all, force: true).done { _ in
// no-op
}.cauterize().finally { [weak self] in
self?.tableViewRefreshControl.endRefreshing()
}
}
private func delete(account: Wallet) {
navigationController?.displayLoading(text: R.string.localizable.deleting())
let result = keystore.delete(wallet: account)

@ -21,7 +21,7 @@ protocol PrivateBalanceFetcherType: AnyObject {
var delegate: PrivateTokensDataStoreDelegate? { get set }
var erc721TokenIdsFetcher: Erc721TokenIdsFetcher? { get set }
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool)
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void>
}
// swiftlint:disable type_body_length
@ -65,13 +65,17 @@ class PrivateBalanceFetcher: PrivateBalanceFetcherType {
case .initial(let tokenObjects):
let tokenObjects = tokenObjects.map { Activity.AssignedToken(tokenObject: $0) }
strongSelf.refreshBalance(tokenObjects: Array(tokenObjects), updatePolicy: .all, force: true)
strongSelf.refreshBalance(tokenObjects: Array(tokenObjects), updatePolicy: .all, force: true).done { _ in
// no-op
}.cauterize()
case .update(let updates, _, let insertions, _):
let values = updates.map { Activity.AssignedToken(tokenObject: $0) }
let tokenObjects = insertions.map { values[$0] }
guard !tokenObjects.isEmpty else { return }
strongSelf.refreshBalance(tokenObjects: tokenObjects, updatePolicy: .all, force: true)
strongSelf.refreshBalance(tokenObjects: tokenObjects, updatePolicy: .all, force: true).done { _ in
// no-op
}.cauterize()
strongSelf.delegate?.didAddToken(in: strongSelf)
case .error:
@ -89,7 +93,7 @@ class PrivateBalanceFetcher: PrivateBalanceFetcherType {
return openSea.makeFetchPromise()
}
func refreshBalance(updatePolicy: RefreshBalancePolicy, force: Bool = false) {
func refreshBalance(updatePolicy: RefreshBalancePolicy, force: Bool = false) -> Promise<Void> {
Promise<[Activity.AssignedToken]> { seal in
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else { return seal.reject(PMKError.cancelled) }
@ -97,9 +101,9 @@ class PrivateBalanceFetcher: PrivateBalanceFetcherType {
seal.fulfill(tokenObjects)
}
}.done(on: queue, { tokenObjects in
self.refreshBalance(tokenObjects: tokenObjects, updatePolicy: .all, force: false)
}).cauterize()
}.then(on: queue, { tokenObjects in
return self.refreshBalance(tokenObjects: tokenObjects, updatePolicy: .all, force: false)
})
}
private func refreshBalanceForNonErc721Or1155Tokens(tokens: [Activity.AssignedToken]) -> Promise<[PrivateBalanceFetcher.TokenBatchOperation]> {
@ -118,8 +122,8 @@ class PrivateBalanceFetcher: PrivateBalanceFetcherType {
case all
}
private func refreshBalance(tokenObjects: [Activity.AssignedToken], updatePolicy: RefreshBalancePolicy, force: Bool = false) {
guard !isRefeshingBalance || force else { return }
private func refreshBalance(tokenObjects: [Activity.AssignedToken], updatePolicy: RefreshBalancePolicy, force: Bool = false) -> Promise<Void> {
guard !isRefeshingBalance || force else { return .value(()) }
isRefeshingBalance = true
var promises: [Promise<Bool?>] = []
@ -134,18 +138,18 @@ class PrivateBalanceFetcher: PrivateBalanceFetcherType {
promises += [refreshEthBalance(etherToken: etherToken)]
}
firstly {
return firstly {
when(resolved: promises).map(on: queue, { values -> Bool? in
//NOTE: taking for first element means that values was updated
return values.compactMap { $0.optionalValue }.compactMap { $0 }.first
})
}.done(on: queue, { balanceValueHasChange in
}.get(on: queue, { balanceValueHasChange in
self.isRefeshingBalance = false
if let value = balanceValueHasChange, value {
self.delegate?.didUpdate(in: self)
}
})
}).asVoid()
}
private func refreshEthBalance(etherToken: Activity.AssignedToken) -> Promise<Bool?> {

@ -16,8 +16,9 @@ protocol WalletBalanceCoordinatorType: AnyObject {
func subscribableWalletBalance(wallet: Wallet) -> Subscribable<WalletBalance>
func subscribableTokenBalance(addressAndRPCServer: AddressAndRPCServer) -> Subscribable<BalanceBaseViewModel>
func start()
func refreshBalance()
func refreshEthBalance()
func refreshBalance() -> Promise<Void>
func refreshEthBalance() -> Promise<Void>
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void>
func transactionsStorage(wallet: Wallet, server: RPCServer) -> TransactionsStorage
func tokensDatastore(wallet: Wallet, server: RPCServer) -> TokensDataStore
@ -83,12 +84,22 @@ class WalletBalanceCoordinator: NSObject, WalletBalanceCoordinatorType {
return .init(nil)
}
func refreshBalance() {
balanceFetchers[keystore.currentWallet].flatMap { $0.refreshBalance() }
func refreshBalance() -> Promise<Void> {
guard let promise = balanceFetchers[keystore.currentWallet].flatMap({ $0.refreshBalance() }) else { return .value(()) }
return promise
}
func refreshEthBalance() {
balanceFetchers[keystore.currentWallet].flatMap { $0.refreshEthBalance() }
func refreshEthBalance() -> Promise<Void> {
guard let promise = balanceFetchers[keystore.currentWallet].flatMap({ $0.refreshEthBalance() }) else { return .value(()) }
return promise
}
///Refreshes available wallets balances
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void> {
let promises = keystore.wallets.compactMap { wallet in
balanceFetchers[wallet]?.refreshBalance(updatePolicy: updatePolicy, force: force)
}
return when(resolved: promises).asVoid()
}
func start() {

@ -28,8 +28,9 @@ protocol WalletBalanceFetcherType: AnyObject {
func start()
func stop()
func update(servers: [RPCServer])
func refreshEthBalance()
func refreshBalance()
func refreshEthBalance() -> Promise<Void>
func refreshBalance() -> Promise<Void>
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void>
func transactionsStorage(server: RPCServer) -> TransactionsStorage
func tokensDatastore(server: RPCServer) -> TokensDataStore
}
@ -106,8 +107,8 @@ class WalletBalanceFetcher: NSObject, WalletBalanceFetcherType {
}
}
let delatedServers = services.filter { !servers.contains($0.key) }.map { $0.key }
for each in delatedServers {
let deletedServers = services.filter { !servers.contains($0.key) }.map { $0.key }
for each in deletedServers {
services.remove(at: each)
}
}
@ -226,33 +227,48 @@ class WalletBalanceFetcher: NSObject, WalletBalanceFetcherType {
}
func start() {
timedCallForBalanceRefresh()
timedCallForBalanceRefresh().done { _ in
}.cauterize()
timer = Timer.scheduledTimer(withTimeInterval: Self.updateBalanceInterval, repeats: true) { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.queue.async {
strongSelf.timedCallForBalanceRefresh()
strongSelf.timedCallForBalanceRefresh().done { _ in
}.cauterize()
}
}
}
private func timedCallForBalanceRefresh() {
for each in services {
private func timedCallForBalanceRefresh() -> Promise<Void> {
let promises = services.map { each in
each.value.1.refreshBalance(updatePolicy: .all, force: false)
}
return when(resolved: promises).asVoid()
}
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void> {
let promises = services.map { each in
each.value.1.refreshBalance(updatePolicy: updatePolicy, force: force)
}
return when(resolved: promises).asVoid()
}
func refreshEthBalance() {
for each in services {
func refreshEthBalance() -> Promise<Void> {
let promises = services.map { each in
each.value.1.refreshBalance(updatePolicy: .eth, force: true)
}
return when(resolved: promises).asVoid()
}
func refreshBalance() {
for each in services {
func refreshBalance() -> Promise<Void> {
let promises = services.map { each in
each.value.1.refreshBalance(updatePolicy: .ercTokens, force: true)
}
return when(resolved: promises).asVoid()
}
func stop() {

@ -69,10 +69,14 @@ class BalanceCoordinator: NSObject, BalanceCoordinatorType {
}
func refresh() {
walletBalanceCoordinator.refreshBalance()
walletBalanceCoordinator.refreshBalance().done { _ in
}.cauterize()
}
func refreshEthBalance() {
walletBalanceCoordinator.refreshEthBalance()
walletBalanceCoordinator.refreshEthBalance().done { _ in
}.cauterize()
}
func update() {

@ -18,11 +18,14 @@ class CreateRedeemTests: XCTestCase {
let account = keyStore.createAccount()
let message = CreateRedeem(token: TokenObject()).redeemMessage(tokenIds: token).0
let data = message.data(using: String.Encoding.utf8)
let signature = try! keyStore.signMessageData(data!, for: account.dematerialize())
do {
let signature = try keyStore.signMessageData(data!, for: account.dematerialize())
//message and signature is to go in qr code
debug("message: " + message)
debug(try! "signature: " + signature.dematerialize().hexString)
debug(try "signature: " + signature.dematerialize().hexString)
//TODO no test?
} catch {
debug(error)
}
}
}

@ -72,6 +72,8 @@ class SettingsCoordinatorTests: XCTestCase {
}
}
import PromiseKit
final class FakeWalletBalanceCoordinator: WalletBalanceCoordinatorType {
var subscribableWalletsSummary: Subscribable<WalletSummary> = .init(nil)
@ -87,12 +89,16 @@ final class FakeWalletBalanceCoordinator: WalletBalanceCoordinatorType {
}
func refreshBalance() {
func refreshBalance() -> Promise<Void> {
return .value(())
}
func refreshEthBalance() {
func refreshEthBalance() -> Promise<Void> {
return .value(())
}
func refreshBalance(updatePolicy: PrivateBalanceFetcher.RefreshBalancePolicy, force: Bool) -> Promise<Void> {
return .value(())
}
func transactionsStorage(wallet: Wallet, server: RPCServer) -> TransactionsStorage {

Loading…
Cancel
Save