133 lines
3.9 KiB
Swift
133 lines
3.9 KiB
Swift
//
|
|
// TransactionAmountInputStore.swift
|
|
// secant-testnet
|
|
//
|
|
// Created by Adam Stener on 4/5/22.
|
|
//
|
|
|
|
import ComposableArchitecture
|
|
|
|
typealias TransactionAmountInputReducer = Reducer<
|
|
TransactionAmountInputState,
|
|
TransactionAmountInputAction,
|
|
TransactionAmountInputEnvironment
|
|
>
|
|
|
|
typealias TransactionAmountInputStore = Store<TransactionAmountInputState, TransactionAmountInputAction>
|
|
|
|
struct TransactionAmountInputState: Equatable {
|
|
var textFieldState: TextFieldState
|
|
var currencySelectionState: CurrencySelectionState
|
|
var maxValue: Int64 = 0
|
|
// TODO: - Get the ZEC price from the SDK, issue 311, https://github.com/zcash/secant-ios-wallet/issues/311
|
|
var zecPrice = 140.0
|
|
|
|
var amount: Int64 {
|
|
switch currencySelectionState.currencyType {
|
|
case .zec:
|
|
return (textFieldState.text.doubleValue ?? 0.0).asZec()
|
|
case .usd:
|
|
return ((textFieldState.text.doubleValue ?? 0.0) / zecPrice).asZec()
|
|
}
|
|
}
|
|
|
|
var maxCurrencyConvertedValue: Int64 {
|
|
switch currencySelectionState.currencyType {
|
|
case .zec:
|
|
return maxValue
|
|
case .usd:
|
|
return (maxValue.asHumanReadableZecBalance() * zecPrice).asZec()
|
|
}
|
|
}
|
|
|
|
var isMax: Bool {
|
|
return amount == maxValue
|
|
}
|
|
}
|
|
|
|
enum TransactionAmountInputAction: Equatable {
|
|
case clearValue
|
|
case setMax
|
|
case textField(TextFieldAction)
|
|
case currencySelection(CurrencySelectionAction)
|
|
}
|
|
|
|
struct TransactionAmountInputEnvironment: Equatable {}
|
|
|
|
extension TransactionAmountInputReducer {
|
|
static let `default` = TransactionAmountInputReducer.combine(
|
|
[
|
|
textFieldReducer,
|
|
currencySelectionReducer,
|
|
maxOverride,
|
|
currencyUpdate
|
|
]
|
|
)
|
|
|
|
static let maxOverride = TransactionAmountInputReducer { state, action, _ in
|
|
switch action {
|
|
case .setMax:
|
|
state.textFieldState.text = "\(state.maxCurrencyConvertedValue.asZecString())"
|
|
|
|
case .clearValue:
|
|
state.textFieldState.text = ""
|
|
|
|
default: break
|
|
}
|
|
|
|
return .none
|
|
}
|
|
|
|
static let currencyUpdate = TransactionAmountInputReducer { state, action, _ in
|
|
switch action {
|
|
case .currencySelection:
|
|
guard let currentDoubleValue = state.textFieldState.text.doubleValue else {
|
|
return .none
|
|
}
|
|
|
|
let currencyType = state.currencySelectionState.currencyType
|
|
|
|
let newValue = currencyType == .zec ?
|
|
currentDoubleValue / state.zecPrice :
|
|
currentDoubleValue * state.zecPrice
|
|
state.textFieldState.text = "\(newValue.asZecString())"
|
|
|
|
default: break
|
|
}
|
|
|
|
return .none
|
|
}
|
|
|
|
private static let textFieldReducer: TransactionAmountInputReducer = TextFieldReducer.default.pullback(
|
|
state: \TransactionAmountInputState.textFieldState,
|
|
action: /TransactionAmountInputAction.textField,
|
|
environment: { _ in return .init() }
|
|
)
|
|
|
|
private static let currencySelectionReducer: TransactionAmountInputReducer = CurrencySelectionReducer.default.pullback(
|
|
state: \TransactionAmountInputState.currencySelectionState,
|
|
action: /TransactionAmountInputAction.currencySelection,
|
|
environment: { _ in return .init() }
|
|
)
|
|
}
|
|
|
|
extension TransactionAmountInputState {
|
|
static let placeholder = TransactionAmountInputState(
|
|
textFieldState: .placeholder,
|
|
currencySelectionState: CurrencySelectionState()
|
|
)
|
|
|
|
static let amount = TransactionAmountInputState(
|
|
textFieldState: .amount,
|
|
currencySelectionState: CurrencySelectionState()
|
|
)
|
|
}
|
|
|
|
extension TransactionAmountInputStore {
|
|
static let placeholder = TransactionAmountInputStore(
|
|
initialState: .placeholder,
|
|
reducer: .default,
|
|
environment: TransactionAmountInputEnvironment()
|
|
)
|
|
}
|