Skip to content

Commit

Permalink
Optimize layout for transaction and improve gas calculation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
vikmeup committed Apr 18, 2018
1 parent 4faeb50 commit 62eb834
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 101 deletions.
6 changes: 6 additions & 0 deletions Trust/Extensions/Address.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ enum Errors: LocalizedError {
}
}
}

extension Address {
static var zero: Address {
return Address(string: "0x0000000000000000000000000000000000000000")!
}
}
5 changes: 5 additions & 0 deletions Trust/Style/AppStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import UIKit
enum AppStyle {
case heading
case paragraph
case largeAmount

var font: UIFont {
switch self {
case .heading:
return UIFont.systemFont(ofSize: 18, weight: .medium)
case .paragraph:
return UIFont.systemFont(ofSize: 15, weight: .light)
case .largeAmount:
return UIFont.systemFont(ofSize: 20, weight: .medium)
}
}

Expand All @@ -21,6 +24,8 @@ enum AppStyle {
return Colors.black
case .paragraph:
return Colors.charcoal
case .largeAmount:
return UIColor.black // Usually colors based on the amount
}
}
}
2 changes: 1 addition & 1 deletion Trust/Transactions/Layout/TransactionsLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import UIKit

struct TransactionsLayout {
struct tableView {
static let height: CGFloat = 68
static let height: CGFloat = 70
static let layoutInsets = UIEdgeInsets(top: 0, left: 58, bottom: 0, right: 0)
}
}
8 changes: 8 additions & 0 deletions Trust/Transactions/Storage/Transaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ class Transaction: Object, Decodable {
var state: TransactionState {
return TransactionState(int: self.internalState)
}

var toAddress: Address? {
return Address(string: to)
}

var fromAddress: Address? {
return Address(string: from)
}
}

extension Transaction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class TransactionViewController: UIViewController {

let header = TransactionHeaderView()
header.translatesAutoresizingMaskIntoConstraints = false
header.amountLabel.attributedText = viewModel.amountAttributedString
header.amountLabel.text = viewModel.amountString
header.amountLabel.textColor = viewModel.amountTextColor
header.amountLabel.font = viewModel.amountFont

let dividerColor = Colors.whisper
let dividerOffset = UIEdgeInsets(top: 0, left: 26, bottom: 0, right: 26)
Expand Down
18 changes: 14 additions & 4 deletions Trust/Transactions/ViewModels/TransactionCellViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,22 @@ struct TransactionCellViewModel {
}

var subTitle: String {
if transaction.toAddress == nil {
return NSLocalizedString("transaction.deployContract.label.title", value: "Deploy smart contract", comment: "")
}
switch transactionViewModel.direction {
case .incoming:
return "From: \(transactionViewModel.transactionFrom)"
return String(
format: "%@: %@",
NSLocalizedString("transaction.from.label.title", value: "From", comment: ""),
transactionViewModel.transactionFrom
)
case .outgoing:
return "To: \(transactionViewModel.transactionTo)"
return String(
format: "%@: %@",
NSLocalizedString("transaction.to.label.title", value: "To", comment: ""),
transactionViewModel.transactionTo
)
}
}

Expand All @@ -105,8 +116,7 @@ struct TransactionCellViewModel {
}

var amountText: String {
let value = transactionViewModel.shortValue
return transactionViewModel.amountWithSign(for: value.amount) + " " + value.symbol
return transactionViewModel.amountText
}

var amountFont: UIFont {
Expand Down
18 changes: 15 additions & 3 deletions Trust/Transactions/ViewModels/TransactionDetailsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import BigInt
import Foundation
import UIKit
import TrustCore

struct TransactionDetailsViewModel {

Expand Down Expand Up @@ -85,6 +86,9 @@ struct TransactionDetailsViewModel {
}

var address: String {
if transaction.toAddress == nil {
return Address.zero.description
}
if transactionViewModel.direction == .incoming {
return transaction.from
} else {
Expand Down Expand Up @@ -133,7 +137,7 @@ struct TransactionDetailsViewModel {
var gasFeeLabelTitle: String {
return NSLocalizedString("transaction.gasFee.label.title", value: "Gas Fee", comment: "")
}

var confirmation: String {
guard let confirmation = chainState.confirmations(fromBlock: transaction.blockNumber) else {
return "--"
Expand All @@ -145,8 +149,16 @@ struct TransactionDetailsViewModel {
return NSLocalizedString("transaction.confirmation.label.title", value: "Confirmation", comment: "")
}

var amountAttributedString: NSAttributedString {
return transactionViewModel.fullAmountAttributedString
var amountString: String {
return transactionViewModel.amountText
}

var amountTextColor: UIColor {
return transactionViewModel.amountTextColor
}

var amountFont: UIFont {
return AppStyle.largeAmount.font
}

var shareItem: URL? {
Expand Down
32 changes: 5 additions & 27 deletions Trust/Transactions/ViewModels/TransactionViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,33 +61,6 @@ struct TransactionViewModel {
return transactionValue(for: fullFormatter)
}

var shortAmountAttributedString: NSAttributedString {
return amountAttributedString(for: shortValue)
}

var fullAmountAttributedString: NSAttributedString {
return amountAttributedString(for: fullValue)
}

func amountAttributedString(for value: TransactionValue) -> NSAttributedString {
let amount = NSAttributedString(
string: amountWithSign(for: value.amount),
attributes: [
.font: UIFont.systemFont(ofSize: 24),
.foregroundColor: amountTextColor,
]
)

let currency = NSAttributedString(
string: " " + value.symbol,
attributes: [
.font: UIFont.systemFont(ofSize: 14),
]
)

return amount + currency
}

func amountWithSign(for amount: String) -> String {
guard amount != "0" else { return amount }
switch direction {
Expand Down Expand Up @@ -124,4 +97,9 @@ struct TransactionViewModel {
return R.image.transaction_pending()
}
}

var amountText: String {
let value = shortValue
return amountWithSign(for: value.amount) + " " + value.symbol
}
}
9 changes: 8 additions & 1 deletion Trust/Transactions/Views/TransactionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ class TransactionViewCell: UITableViewCell {
rightStackView.translatesAutoresizingMaskIntoConstraints = false
rightStackView.axis = .vertical

let stackView = UIStackView(arrangedSubviews: [statusImageView, titlesStackView, rightStackView])
let stackView = UIStackView(arrangedSubviews: [
statusImageView,
titlesStackView,
.spacerWidth(),
rightStackView,
])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.spacing = 15
Expand All @@ -44,6 +49,8 @@ class TransactionViewCell: UITableViewCell {
statusImageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal)
subTitleLabel.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal)
titleLabel.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal)
titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
subTitleLabel.setContentCompressionResistancePriority(.required, for: .vertical)

amountLabel.setContentHuggingPriority(UILayoutPriority.required, for: .horizontal)
stackView.setContentHuggingPriority(UILayoutPriority.required, for: .horizontal)
Expand Down
95 changes: 43 additions & 52 deletions Trust/Transfer/Controllers/TransactionConfigurator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,7 @@ class TransactionConfigurator {
configurationUpdate.value = configuration
}
}
lazy var calculatedGasPrice: BigInt = {
return max(transaction.gasPrice ?? configuration.gasPrice, GasPriceConfiguration.min)
}()

var calculatedGasLimit: BigInt? {
return transaction.gasLimit
}

var requestEstimateGas: Bool {
return transaction.gasLimit == .none
}
var requestEstimateGas: Bool

var configurationUpdate: Subscribable<TransactionConfiguration> = Subscribable(nil)

Expand All @@ -52,15 +42,30 @@ class TransactionConfigurator {
self.session = session
self.account = account
self.transaction = transaction
self.requestEstimateGas = transaction.gasLimit == .none

let nonce = transaction.nonce ?? BigInt(session.nonceProvider.nextNonce ?? -1)
let data: Data = TransactionConfigurator.data(for: transaction)
let calculatedGasLimit = transaction.gasLimit ?? TransactionConfigurator.gasLimit(for: transaction.transferType)
let calculatedGasPrice = min(max(transaction.gasPrice ?? session.chainState.gasPrice ?? GasPriceConfiguration.default, GasPriceConfiguration.min), GasPriceConfiguration.max)

self.configuration = TransactionConfiguration(
gasPrice: min(max(transaction.gasPrice ?? session.chainState.gasPrice ?? GasPriceConfiguration.default, GasPriceConfiguration.min), GasPriceConfiguration.max),
gasLimit: transaction.gasLimit ?? TransactionConfigurator.gasLimit(for: transaction.transferType),
data: transaction.data ?? Data(),
nonce: transaction.nonce ?? BigInt(session.nonceProvider.nextNonce ?? -1)
gasPrice: calculatedGasPrice,
gasLimit: calculatedGasLimit,
data: data,
nonce: nonce
)
}

private static func data(for transaction: UnconfirmedTransaction) -> Data {
switch transaction.transferType {
case .ether, .dapp:
return transaction.data ?? Data()
case .token:
return ERC20Encoder.encodeTransfer(to: transaction.to!, tokens: transaction.value.magnitude)
}
}

private static func gasLimit(for type: TransferType) -> BigInt {
switch type {
case .ether:
Expand All @@ -77,40 +82,12 @@ class TransactionConfigurator {
}

func load(completion: @escaping (Result<Void, AnyError>) -> Void) {
refreshConfiguration()
if requestEstimateGas {
estimateGasLimit()
}
loadNonce(completion: completion)
}

func refreshConfiguration() {
switch transaction.transferType {
case .ether:
self.configuration = TransactionConfiguration(
gasPrice: calculatedGasPrice,
gasLimit: GasLimitConfiguration.default,
data: transaction.data ?? configuration.data,
nonce: configuration.nonce
)
case .token:
let encoded = ERC20Encoder.encodeTransfer(to: transaction.to!, tokens: transaction.value.magnitude)
self.configuration = TransactionConfiguration(
gasPrice: calculatedGasPrice,
gasLimit: GasLimitConfiguration.tokenTransfer,
data: encoded,
nonce: configuration.nonce
)
case .dapp:
self.configuration = TransactionConfiguration(
gasPrice: calculatedGasPrice,
gasLimit: GasLimitConfiguration.dappTransfer,
data: transaction.data ?? configuration.data,
nonce: configuration.nonce
)
}
}

func estimateGasLimit() {
let request = EstimateGasRequest(transaction: signTransaction())
Session.send(EtherServiceRequest(batch: BatchFactory().create(request))) { [weak self] result in
Expand All @@ -124,24 +101,38 @@ class TransactionConfigurator {
}
return limit + (limit * 20 / 100)
}()

self.configuration = TransactionConfiguration(
gasPrice: self.calculatedGasPrice,
gasLimit: gasLimit,
data: self.configuration.data,
nonce: self.configuration.nonce
)
self.refreshGasLimit(gasLimit)
case .failure(let error):
NSLog("estimateGasLimit \(error)")
}
}
}

// combine into one function

func refreshGasLimit(_ gasLimit: BigInt) {
configuration = TransactionConfiguration(
gasPrice: configuration.gasPrice,
gasLimit: gasLimit,
data: configuration.data,
nonce: configuration.nonce
)
}

func refreshNonce(_ nonce: BigInt) {
configuration = TransactionConfiguration(
gasPrice: configuration.gasPrice,
gasLimit: configuration.gasLimit,
data: configuration.data,
nonce: nonce
)
}

func loadNonce(completion: @escaping (Result<Void, AnyError>) -> Void) {
session.nonceProvider.getNextNonce(force: false) { [weak self] result in
switch result {
case .success:
self?.refreshConfiguration()
case .success(let nonce):
self?.refreshNonce(nonce)
completion(.success(()))
case .failure(let error):
completion(.failure(error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class ConfirmPaymentViewController: UIViewController {
header.translatesAutoresizingMaskIntoConstraints = false
header.amountLabel.text = detailsViewModel.amountString
header.amountLabel.font = detailsViewModel.amountFont
header.amountLabel.textColor = detailsViewModel.amountTextColor

var items: [UIView] = [
.spacer(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct ConfirmPaymentDetailsViewModel {
}

var amountFont: UIFont {
return UIFont.systemFont(ofSize: 20, weight: .medium)
return AppStyle.largeAmount.font
}

private func amountWithSign(for amount: String) -> String {
Expand Down
4 changes: 1 addition & 3 deletions Trust/Welcome/ViewControllers/WelcomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,10 @@ class WelcomeViewController: UIViewController {
return button
}()
let importWalletButton: UIButton = {
let importWalletButton = Button(size: .large, style: .solid)
let importWalletButton = Button(size: .large, style: .border)
importWalletButton.translatesAutoresizingMaskIntoConstraints = false
importWalletButton.setTitle(NSLocalizedString("welcome.importWallet.button.title", value: "IMPORT WALLET", comment: ""), for: .normal)
importWalletButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.semibold)
importWalletButton.setBackgroundColor(Colors.gray, forState: .normal)
importWalletButton.setBackgroundColor(Colors.lightGray, forState: .highlighted)
importWalletButton.accessibilityIdentifier = "import-wallet"
return importWalletButton
}()
Expand Down
Loading

0 comments on commit 62eb834

Please sign in to comment.