Skip to content

Commit

Permalink
Bug/437 (trustwallet#487)
Browse files Browse the repository at this point in the history
* Add possibility to edit custom tokens.

* Add parallel operation for heavy requests.
  • Loading branch information
OlegGordiichuk authored and vikmeup committed Mar 16, 2018
1 parent e5f940b commit 180c147
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 29 deletions.
10 changes: 7 additions & 3 deletions Trust/Tokens/ViewControllers/TokensViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class TokensViewController: UIViewController {
self.viewModel = viewModel
tableView = UITableView(frame: .zero, style: .plain)
super.init(nibName: nil, bundle: nil)
self.viewModel.delegate = self
self.tokensObservation()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
Expand Down Expand Up @@ -190,9 +191,6 @@ extension TokensViewController: UITableViewDelegate {
return viewModel.canEdit(for: indexPath)
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
guard !viewModel.canEdit(for: indexPath) else {
return []
}
let token = viewModel.item(for: indexPath)
let delete = UITableViewRowAction(style: .destructive, title: NSLocalizedString("Delete", value: "Delete", comment: "")) {[unowned self] (_, _) in
self.delegate?.didDelete(token: token, in: self)
Expand All @@ -216,3 +214,9 @@ extension TokensViewController: UITableViewDataSource {
return viewModel.tokens.count
}
}
extension TokensViewController: TokensViewModelDelegate {
func refresh() {
self.tableView.reloadData()
self.refreshHeaderAndFooterView()
}
}
65 changes: 39 additions & 26 deletions Trust/Tokens/ViewModels/TokensViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ enum TokenItem {
case token(TokenObject)
}

class TokensViewModel {
protocol TokensViewModelDelegate: class {
func refresh()
}

class TokensViewModel: NSObject {
let config: Config

let store: TokensDataStore
Expand Down Expand Up @@ -58,13 +62,21 @@ class TokensViewModel {
return UIFont.systemFont(ofSize: 13, weight: .light)
}

private var operationQueue: OperationQueue = {
weak var delegate: TokensViewModelDelegate?

private var serailOperationQueue: OperationQueue = {
let queue = OperationQueue()
queue.qualityOfService = .background
queue.maxConcurrentOperationCount = 1
return queue
}()

private var parallelOperationQueue: OperationQueue = {
let queue = OperationQueue()
queue.qualityOfService = .background
return queue
}()

init(
config: Config = Config(),
address: Address,
Expand All @@ -76,6 +88,7 @@ class TokensViewModel {
self.store = store
self.tokensNetwork = tokensNetwork
self.tokens = store.tokens
super.init()
updateEthBalance { [weak self] _ in
self?.runOperations()
}
Expand Down Expand Up @@ -110,11 +123,7 @@ class TokensViewModel {
}

func canEdit(for path: IndexPath) -> Bool {
let token = item(for: path)
switch token {
case .token(let token):
return token.isCustom
}
return tokens[path.row].isCustom
}

func cellViewModel(for path: IndexPath) -> TokenViewCellViewModel {
Expand All @@ -124,7 +133,7 @@ class TokensViewModel {

func updateEthBalance(completion: ((_ completed: Bool) -> Void)? = nil) {
tokensNetwork.ethBalance { result in
guard let balance = result, let token = self.store.objects.first (where: { $0.name == self.config.server.name }), self.operationQueue.operationCount == 0 else {
guard let balance = result, let token = self.store.objects.first (where: { $0.name == self.config.server.name }), self.serailOperationQueue.operationCount == 0 else {
completion?(true)
return
}
Expand All @@ -134,50 +143,54 @@ class TokensViewModel {
}

private func runOperations() {

guard operationQueue.operationCount == 0, let chaineToken = self.store.objects.first (where: { $0.name == self.config.server.name }) else {
guard serailOperationQueue.operationCount == 0, let chaineToken = self.store.objects.first (where: { $0.name == self.config.server.name }), parallelOperationQueue.operationCount == 0 else {
return
}

let ethBalanceOperation = EthBalanceOperation(network: tokensNetwork)

let tokensOperation = TokensOperation(network: tokensNetwork, address: address)

let tokensBalanceOperation = TokensBalanceOperation(network: tokensNetwork, address: address)

let tokensTickerOperation = TokensTickerOperation(network: tokensNetwork, address: address)

let tempChaine = TokensDataStore.etherToken(for: config)
tempChaine.value = chaineToken.value

operationQueue.addOperation(ethBalanceOperation)
serailOperationQueue.addOperation(ethBalanceOperation)

ethBalanceOperation.completionBlock = { [weak self] in
guard let strongSelf = self else { return }
tempChaine.value = ethBalanceOperation.balance.value.description
tokensOperation.tokens.append(tempChaine)
strongSelf.operationQueue.addOperation(tokensOperation)
self?.serailOperationQueue.addOperation(tokensOperation)
}

tokensOperation.completionBlock = { [weak self] in
guard let strongSelf = self else { return }
tokensBalanceOperation.tokens = tokensOperation.tokens
strongSelf.operationQueue.addOperation(tokensBalanceOperation)
self?.parallelOperations(for: tokensOperation.tokens)
DispatchQueue.main.async {
self?.store.add(tokens: tokensOperation.tokens)
}
}
}

private func parallelOperations(for tokens: [TokenObject]) {
let tokensBalanceOperation = TokensBalanceOperation(network: tokensNetwork, address: address)
tokensBalanceOperation.tokens = tokens

tokensBalanceOperation.completionBlock = { [weak self] in
guard let strongSelf = self else { return }
tokensTickerOperation.tokens = tokensBalanceOperation.tokens
strongSelf.operationQueue.addOperation(tokensTickerOperation)
DispatchQueue.main.async {
self?.store.add(tokens: tokensBalanceOperation.tokens)
}
}

let tokensTickerOperation = TokensTickerOperation(network: tokensNetwork, address: address)
tokensTickerOperation.tokens = tokens

tokensTickerOperation.completionBlock = { [weak self] in
guard let strongSelf = self else { return }
self?.store.tickers = tokensTickerOperation.tickers
DispatchQueue.main.async {
strongSelf.store.tickers = tokensTickerOperation.tickers
strongSelf.store.add(tokens: tokensTickerOperation.tokens)
self?.delegate?.refresh()
}
}

parallelOperationQueue.addOperations([tokensBalanceOperation, tokensTickerOperation], waitUntilFinished: true)
}

func fetch() {
Expand Down

0 comments on commit 180c147

Please sign in to comment.