Created
December 4, 2017 17:13
-
-
Save westonal/31be9f60ba25ca802dcf23f5038b1a48 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package MVI | |
import electrum.Electrum | |
import io.reactivex.Observable | |
typealias WalletViewStateReducer = (WalletViewState) -> WalletViewState | |
class WalletModel( | |
val intent: Observable<WalletIntent>, | |
val electrum: Electrum | |
) { | |
val reducers: Observable<WalletViewStateReducer> = | |
intent.flatMap { | |
getStateReducer(it) | |
} | |
private fun getStateReducer(intent: WalletIntent): Observable<WalletViewStateReducer> = | |
when (intent) { | |
is WalletIntent.New -> { | |
Observable.just(getInitialStateReducer()) | |
} | |
is WalletIntent.NewBlockHeight -> Observable.just({ state -> state.copy(blockHeight = intent.height) }) | |
is WalletIntent.AddAddress -> getAddAddressStateReducer(intent) | |
is WalletIntent.RemoveAddress -> getRemoveAddressStateReducer(intent) | |
} | |
private fun getAddAddressStateReducer(intent: WalletIntent.AddAddress): Observable<WalletViewStateReducer> { | |
val value: WalletViewStateReducer = { it -> | |
upsertAddressReducer(it, AddressWalletViewState(intent.address, Electrum.Balance(intent.address))) | |
} | |
val maped: Observable<WalletViewStateReducer> = | |
electrum.balanceOf(intent.address) | |
.map { AddressWalletViewState(intent.address, it) } | |
.map { it -> { wallet: WalletViewState -> updateAddressReducer(wallet, it) } } | |
return Observable.just(value) | |
.concatWith(maped) | |
} | |
private fun getRemoveAddressStateReducer(intent: WalletIntent.RemoveAddress): Observable<WalletViewStateReducer> { | |
val value: WalletViewStateReducer = { it -> | |
removeAddressReducer(it, intent.address) | |
} | |
return Observable.just(value) | |
} | |
private fun upsertAddressReducer(wallet: WalletViewState, newAddressValue: AddressWalletViewState): WalletViewState { | |
val copy = wallet.addresses.toMutableList() | |
val idx = copy.indexOfFirst { (address) -> address == newAddressValue.address } | |
if (idx > -1) | |
copy[idx] = newAddressValue | |
else | |
copy += newAddressValue | |
return wallet.copy(addresses = copy) | |
} | |
private fun updateAddressReducer(wallet: WalletViewState, newAddressValue: AddressWalletViewState): WalletViewState { | |
val idx = wallet.addresses.indexOfFirst { (address) -> address == newAddressValue.address } | |
return if (idx > -1) { | |
val copy = wallet.addresses.toMutableList() | |
.also { it[idx] = newAddressValue } | |
wallet.copy(addresses = copy) | |
} else { | |
wallet | |
} | |
} | |
private fun removeAddressReducer(wallet: WalletViewState, newAddressValue: String): WalletViewState { | |
val copy = wallet.addresses.toMutableList() | |
copy.removeIf { (address) -> address == newAddressValue } | |
return wallet.copy(addresses = copy) | |
} | |
private fun getInitialStateReducer(): WalletViewStateReducer = { WalletViewState() } | |
val stream: Observable<WalletViewState> = reducers.scan( | |
WalletViewState(0, emptyList()), | |
{ oldState, reducer -> | |
reducer(oldState).also { | |
println("\toldState:\t$oldState") | |
println("\tnewState:\t$it") | |
} | |
} | |
) | |
} | |
fun walletDialog(intent: Observable<WalletIntent>, electrum: Electrum): Observable<WalletViewState> { | |
return WalletModel(intent, electrum).stream | |
} | |
data class AddressWalletViewState( | |
val address: String, | |
val balance: Electrum.Balance | |
) | |
data class WalletViewState( | |
val blockHeight: Int = 0, | |
val addresses: List<AddressWalletViewState> = emptyList()) { | |
val balanceConfirmed: Long = addresses.sumByDouble { it.balance.confirmed.toDouble() }.toLong() | |
val balanceUnconfirmed: Long = addresses.sumByDouble { it.balance.unconfirmed.toDouble() }.toLong() | |
} | |
sealed class WalletIntent { | |
class New : WalletIntent() | |
class NewBlockHeight(val height: Int) : WalletIntent() | |
class AddAddress(val address: String) : WalletIntent() | |
class RemoveAddress(val address: String) : WalletIntent() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment