@ -30,10 +30,21 @@ class SendViewController: FormViewController {
static let address = " address "
static let amount = " amount "
}
struct Pair {
let left : String
let right : String
func swapPair ( ) -> Pair {
return Pair ( left : right , right : left )
}
}
var pairValue = 0.0
let session : WalletSession
let account : Account
let transferType : TransferType
let storage : TokensDataStore
var addressRow : TextFloatLabelRow ? {
return form . rowBy ( tag : Values . address ) as ? TextFloatLabelRow
@ -41,19 +52,29 @@ class SendViewController: FormViewController {
var amountRow : TextFloatLabelRow ? {
return form . rowBy ( tag : Values . amount ) as ? TextFloatLabelRow
}
private var gasPrice : BigInt ?
lazy var currentPair : Pair = {
return Pair ( left : viewModel . symbol , right : Config ( ) . currency . rawValue )
} ( )
init (
session : WalletSession ,
storage : TokensDataStore ,
account : Account ,
transferType : TransferType = . ether ( destination : . none )
) {
self . session = session
self . account = account
self . transferType = transferType
self . storage = storage
super . init ( nibName : nil , bundle : nil )
storage . updatePrices ( )
getGasPrice ( )
title = viewModel . title
view . backgroundColor = viewModel . backgroundColor
@ -82,18 +103,24 @@ class SendViewController: FormViewController {
maxButton . translatesAutoresizingMaskIntoConstraints = false
maxButton . setTitle ( NSLocalizedString ( " send.max.button.title " , value : " Max " , comment : " " ) , for : . normal )
maxButton . addTarget ( self , action : #selector ( useMaxAmount ) , for : . touchUpInside )
let fiatButton = Button ( size : . normal , style : . borderless )
fiatButton . translatesAutoresizingMaskIntoConstraints = false
fiatButton . setTitle ( currentPair . right , for : . normal )
fiatButton . addTarget ( self , action : #selector ( fiatAction ) , for : . touchUpInside )
fiatButton . isHidden = isFiatViewHidden ( )
let amountRightView = UIStackView ( arrangedSubviews : [
maxButton ,
fiat Button,
] )
amountRightView . translatesAutoresizingMaskIntoConstraints = false
amountRightView . distribution = . equalSpacing
amountRightView . spacing = 10
amountRightView . spacing = 1
amountRightView . axis = . horizontal
form = Section ( )
+++ Section ( " " )
+++ Section ( header : " " , footer : isFiatViewHidden ( ) ? " " : " ~ \( String ( self . pairValue ) ) " + " \( currentPair . right ) " )
<<< AppFormAppearance . textFieldFloat ( tag : Values . address ) {
$0 . add ( rule : EthereumAddressRule ( ) )
$0 . validationOptions = . validatesOnDemand
@ -104,25 +131,17 @@ class SendViewController: FormViewController {
cell . textField . rightViewMode = . always
cell . textField . accessibilityIdentifier = " amount-field "
}
<<< AppFormAppearance . textFieldFloat ( tag : Values . amount ) {
$0 . add ( rule : RuleRequired ( ) )
$0 . validationOptions = . validatesOnDemand
} . cellUpdate { [ weak self ] cell , _ in
cell . textField . textAlignment = . left
cell . textField . placeholder = " \( self ? . viewModel . symbol ? ? " " ) " + NSLocalizedString ( " send.amount.textField.placeholder " , value : " Amount " , comment : " " )
cell . textField . delegate = self
cell . textField . placeholder = " \( self ? . currentPair . left ? ? " " ) " + NSLocalizedString ( " send.amount.textField.placeholder " , value : " Amount " , comment : " " )
cell . textField . keyboardType = . decimalPad
// c e l l . t e x t F i e l d . r i g h t V i e w = m a x B u t t o n / / T O D O E n a b l e i t ' s r e a d y
cell . textField . rightView = amountRightView
cell . textField . rightViewMode = . always
}
+++ Section {
$0 . hidden = Eureka . Condition . function ( [ Values . amount ] , { [ weak self ] _ in
return self ? . amountRow ? . value ? . isEmpty ? ? true
} )
}
getGasPrice ( )
}
func getGasPrice ( ) {
@ -149,7 +168,12 @@ class SendViewController: FormViewController {
guard errors . isEmpty else { return }
let addressString = addressRow ? . value ? . trimmed ? ? " "
let amountString = amountRow ? . value ? . trimmed ? ? " "
var amountString = " "
if self . currentPair . left = = viewModel . symbol {
amountString = amountRow ? . value ? . trimmed ? ? " "
} else {
amountString = String ( pairValue ) . trimmed
}
let address = Address ( string : addressString )
@ -205,6 +229,23 @@ class SendViewController: FormViewController {
amountRow ? . value = value
amountRow ? . reload ( )
}
@objc func fiatAction ( sender : UIButton ) {
let swappedPair = currentPair . swapPair ( )
// N e w p a i r f o r f u t u r e c a l c u l a t i o n w e s h o u l d s w a p p a i r e a c h t i m e w e p r e s s f i a t b u t t o n .
self . currentPair = swappedPair
// U p d a t e b u t t o n t i t l e .
sender . setTitle ( currentPair . right , for : . normal )
// R e s e t a m o u n t R o w v a l u e .
amountRow ? . value = nil
amountRow ? . reload ( )
// R e s e t p a i r v a l u e .
pairValue = 0.0
// U p d a t e s e c t i o n .
updatePriceSection ( )
// S e t f o c u s e o n p a i r c h a n g e .
activateAmountView ( )
}
func activateAmountView ( ) {
amountRow ? . cell . textField . becomeFirstResponder ( )
@ -213,6 +254,37 @@ class SendViewController: FormViewController {
required init ? ( coder aDecoder : NSCoder ) {
fatalError ( " init(coder:) has not been implemented " )
}
private func updatePriceSection ( ) {
// W e u s e t h i s s e c t i o n u p d a t e t o p r e v e n t u p d a t e o f t h e a l l s e c t i o n i n c l u d i n g c e l l s .
UIView . setAnimationsEnabled ( false )
tableView . beginUpdates ( )
if let containerView = tableView . footerView ( forSection : 1 ) {
containerView . textLabel ! . text = " ~ \( String ( self . pairValue ) ) " + " \( currentPair . right ) "
containerView . sizeToFit ( )
}
tableView . endUpdates ( )
UIView . setAnimationsEnabled ( true )
}
private func updatePairPrice ( with amount : Double ) {
guard let rates = storage . tickers , let currentTokenInfo = rates [ viewModel . contract ] , let price = Double ( currentTokenInfo . price ) else {
return
}
if self . currentPair . left = = viewModel . symbol {
pairValue = amount * price
} else {
pairValue = amount / price
}
self . updatePriceSection ( )
}
private func isFiatViewHidden ( ) -> Bool {
guard let rates = storage . tickers , let currentTokenInfo = rates [ viewModel . contract ] , let _ = Double ( currentTokenInfo . price ) else {
return true
}
return false
}
}
extension SendViewController : QRCodeReaderDelegate {
@ -230,3 +302,17 @@ extension SendViewController: QRCodeReaderDelegate {
activateAmountView ( )
}
}
extension SendViewController : UITextFieldDelegate {
func textField ( _ textField : UITextField , shouldChangeCharactersIn range : NSRange , replacementString string : String ) -> Bool {
let text = ( textField . text as NSString ? ) ? . replacingCharacters ( in : range , with : string )
guard let total = text , let amount = Double ( total ) else {
// S h o u l d b e d o n e i n a n o t h e r w a y .
pairValue = 0.0
updatePriceSection ( )
return true
}
self . updatePairPrice ( with : amount )
return true
}
}