Everything functional before changing startup sequence
This commit is contained in:
parent
ba51a19b0b
commit
ad708e69d5
Binary file not shown.
|
@ -1,24 +1,16 @@
|
||||||
package cash.z.android.wallet.di.module
|
package cash.z.android.wallet.di.module
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import cash.z.android.wallet.BuildConfig
|
import cash.z.android.wallet.BuildConfig
|
||||||
import cash.z.android.wallet.ZcashWalletApplication
|
import cash.z.android.wallet.ZcashWalletApplication
|
||||||
import cash.z.android.wallet.di.module.Properties.CACHE_DB_NAME
|
import cash.z.android.wallet.sample.SampleProperties
|
||||||
import cash.z.android.wallet.di.module.Properties.COMPACT_BLOCK_PORT
|
import cash.z.android.wallet.sample.SampleProperties.COMPACT_BLOCK_PORT
|
||||||
import cash.z.android.wallet.di.module.Properties.COMPACT_BLOCK_SERVER
|
import cash.z.android.wallet.sample.SampleProperties.COMPACT_BLOCK_SERVER
|
||||||
import cash.z.android.wallet.di.module.Properties.DATA_DB_NAME
|
|
||||||
import cash.z.android.wallet.di.module.Properties.SEED_PROVIDER
|
|
||||||
import cash.z.android.wallet.di.module.Properties.SPENDING_KEY_PROVIDER
|
|
||||||
import cash.z.wallet.sdk.data.*
|
import cash.z.wallet.sdk.data.*
|
||||||
import cash.z.wallet.sdk.jni.JniConverter
|
import cash.z.wallet.sdk.jni.JniConverter
|
||||||
import cash.z.wallet.sdk.secure.Wallet
|
import cash.z.wallet.sdk.secure.Wallet
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import okio.ByteString
|
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.properties.ReadOnlyProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module that contributes all the objects necessary for the synchronizer, which is basically everything that has
|
* Module that contributes all the objects necessary for the synchronizer, which is basically everything that has
|
||||||
|
@ -43,21 +35,21 @@ internal object SynchronizerModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideProcessor(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): CompactBlockProcessor {
|
fun provideProcessor(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): CompactBlockProcessor {
|
||||||
return CompactBlockProcessor(application, converter, CACHE_DB_NAME, DATA_DB_NAME, logger = twigger)
|
return CompactBlockProcessor(application, converter, SampleProperties.wallet.cacheDbName, SampleProperties.wallet.dataDbName, logger = twigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideRepository(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): TransactionRepository {
|
fun provideRepository(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): TransactionRepository {
|
||||||
return PollingTransactionRepository(application, DATA_DB_NAME, 10_000L, converter, twigger)
|
return PollingTransactionRepository(application, SampleProperties.wallet.dataDbName, 10_000L, converter, twigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideWallet(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): Wallet {
|
fun provideWallet(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): Wallet {
|
||||||
return Wallet(converter, application.getDatabasePath(DATA_DB_NAME).absolutePath, "${application.cacheDir.absolutePath}/params", seedProvider = SEED_PROVIDER, spendingKeyProvider = SPENDING_KEY_PROVIDER, logger = twigger)
|
return Wallet(converter, application.getDatabasePath(SampleProperties.wallet.dataDbName).absolutePath, "${application.cacheDir.absolutePath}/params", seedProvider = SampleProperties.wallet.seedProvider, spendingKeyProvider = SampleProperties.wallet.spendingKeyProvider, logger = twigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -91,55 +83,3 @@ internal object SynchronizerModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: load most of these properties in later, perhaps from settings
|
|
||||||
object Properties {
|
|
||||||
val COMPACT_BLOCK_SERVER = Servers.EMULATOR.host
|
|
||||||
const val COMPACT_BLOCK_PORT = 9067
|
|
||||||
const val CACHE_DB_NAME = "wallet_cache4821.db"
|
|
||||||
const val DATA_DB_NAME = "wallet_data4821.db"
|
|
||||||
val SEED_PROVIDER = SampleSeedProvider("dummyseed")
|
|
||||||
val SPENDING_KEY_PROVIDER = SampleSpendingKeyProvider("dummyseed")
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Servers(val host: String) {
|
|
||||||
EMULATOR("10.0.2.2"),
|
|
||||||
WLAN("10.0.0.26"),
|
|
||||||
BOLT_TESTNET("ec2-34-228-10-162.compute-1.amazonaws.com"),
|
|
||||||
ZCASH_TESTNET("lightwalletd.z.cash")
|
|
||||||
}
|
|
||||||
class SampleImportedSeedProvider(private val seedHex: String) : ReadOnlyProperty<Any?, ByteArray> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): ByteArray {
|
|
||||||
val bytes = ByteString.decodeHex(seedHex).toByteArray()
|
|
||||||
val stringBytes = String(bytes, Charset.forName("UTF-8"))
|
|
||||||
Log.e("TWIG-x", "byteString: $stringBytes")
|
|
||||||
return decodeHex(seedHex).also { Log.e("TWIG-x", "$it") }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun decodeHex(hex: String): ByteArray {
|
|
||||||
val result = ByteArray(hex.length / 2)
|
|
||||||
for (i in result.indices) {
|
|
||||||
val d1 = decodeHexDigit(hex[i * 2]) shl 4
|
|
||||||
val d2 = decodeHexDigit(hex[i * 2 + 1])
|
|
||||||
result[i] = (d1 + d2).toByte()
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
private fun decodeHexDigit(c: Char): Int {
|
|
||||||
if (c in '0'..'9') return c - '0'
|
|
||||||
if (c in 'a'..'f') return c - 'a' + 10
|
|
||||||
if (c in 'A'..'F') return c - 'A' + 10
|
|
||||||
throw IllegalArgumentException("Unexpected hex digit: $c")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class SampleSpendingKeyProvider2(private val seedValue: String) : ReadOnlyProperty<Any?, String> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
|
||||||
// dynamically generating keyes, based on seed is out of scope for this sample
|
|
||||||
return "secret-extended-key-test1q0ks5jkcqqqqpqywf2mh5g2aw5smt252mqscphjr8svrqyvgtgss0av3jh37jc05pngstr6qcqu5x64zuk8entc97pfla68jd7g9fyhwv5l8pdey662qy3lr07w9yddpgwdlwt3tjgzhpszatyw90kpn4zs7feu5cudwnxcpts5k0za96xy0wt59nu7hg3ntalck7gwhn0nuyztmf8yceuhp0fn3wmrtr9mk9v6fhg8hwvsxp0thr4cn9r8pc0w3zh45czmnr7e3mrctlzaq7"
|
|
||||||
// return "secret-extended-key-test1q0f0urnmqqqqpqxlree5urprcmg9pdgvr2c88qhm862etv65eu84r9zwannpz4g88299xyhv7wf9xkecag653jlwwwyxrymfraqsnz8qfgds70qjammscxxyl7s7p9xz9w906epdpy8ztsjd7ez7phcd5vj7syx68sjskqs8j9lef2uuacghsh8puuvsy9u25pfvcdznta33qe6xh5lrlnhdkgymnpdug4jm6tpf803cad6tqa9c0ewq9l03fqxatevm97jmuv8u0ccxjews5"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package cash.z.android.wallet.sample
|
||||||
|
|
||||||
|
import cash.z.wallet.sdk.data.SampleSeedProvider
|
||||||
|
|
||||||
|
object AliceWallet {
|
||||||
|
const val name = "test.reference.alice"
|
||||||
|
val seedProvider = SampleSeedProvider(name)
|
||||||
|
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||||
|
const val cacheDbName = "testalice_cache.db"
|
||||||
|
const val dataDbName = "testalice_data.db"
|
||||||
|
}
|
||||||
|
|
||||||
|
object BobWallet {
|
||||||
|
const val name = "test.reference.bob"
|
||||||
|
val seedProvider =
|
||||||
|
SampleSeedProvider(name)
|
||||||
|
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||||
|
const val cacheDbName = "testalice_cache.db"
|
||||||
|
const val dataDbName = "testalice_data.db"
|
||||||
|
}
|
||||||
|
|
||||||
|
object MyWallet {
|
||||||
|
const val name = "mine"
|
||||||
|
val seedProvider =
|
||||||
|
SampleImportedSeedProvider("295761fce7fdc89fa1095259f5be6375c4a36f7a214767d668f9ef6e17aa6314")
|
||||||
|
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||||
|
const val cacheDbName = "wallet_cache1202.db"
|
||||||
|
const val dataDbName = "wallet_data1202.db"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Servers(val host: String) {
|
||||||
|
EMULATOR("10.0.2.2"),
|
||||||
|
WLAN("10.0.0.26"),
|
||||||
|
BOLT_TESTNET("ec2-34-228-10-162.compute-1.amazonaws.com"),
|
||||||
|
ZCASH_TESTNET("lightwalletd.z.cash")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: load most of these properties in later, perhaps from settings
|
||||||
|
object SampleProperties {
|
||||||
|
val COMPACT_BLOCK_SERVER = Servers.EMULATOR.host
|
||||||
|
const val COMPACT_BLOCK_PORT = 9067
|
||||||
|
val wallet = AliceWallet
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package cash.z.android.wallet.sample
|
||||||
|
|
||||||
|
import android.preference.PreferenceManager
|
||||||
|
import android.util.Log
|
||||||
|
import cash.z.android.wallet.ZcashWalletApplication
|
||||||
|
import okio.ByteString
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import android.R.id.edit
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
|
@Deprecated(message = InsecureWarning.message)
|
||||||
|
class SampleImportedSeedProvider(private val seedHex: String) : ReadOnlyProperty<Any?, ByteArray> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): ByteArray {
|
||||||
|
val bytes = ByteString.decodeHex(seedHex).toByteArray()
|
||||||
|
val stringBytes = String(bytes, Charset.forName("UTF-8"))
|
||||||
|
Log.e("TWIG-x", "byteString: $stringBytes")
|
||||||
|
return decodeHex(seedHex).also { Log.e("TWIG-x", "$it") }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decodeHex(hex: String): ByteArray {
|
||||||
|
val result = ByteArray(hex.length / 2)
|
||||||
|
for (i in result.indices) {
|
||||||
|
val d1 = decodeHexDigit(hex[i * 2]) shl 4
|
||||||
|
val d2 = decodeHexDigit(hex[i * 2 + 1])
|
||||||
|
result[i] = (d1 + d2).toByte()
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decodeHexDigit(c: Char): Int {
|
||||||
|
if (c in '0'..'9') return c - '0'
|
||||||
|
if (c in 'a'..'f') return c - 'a' + 10
|
||||||
|
if (c in 'A'..'F') return c - 'A' + 10
|
||||||
|
throw IllegalArgumentException("Unexpected hex digit: $c")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(message = InsecureWarning.message)
|
||||||
|
class SampleSpendingKeySharedPref(private val fileName: String) : ReadWriteProperty<Any?, String> {
|
||||||
|
|
||||||
|
private fun getPrefs() = ZcashWalletApplication.instance
|
||||||
|
.getSharedPreferences(fileName, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||||
|
val preferences = getPrefs()
|
||||||
|
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(ZcashWalletApplication.instance)
|
||||||
|
return preferences.getString("spending", null)
|
||||||
|
?: throw IllegalStateException(
|
||||||
|
"Spending key was not there when we needed it! Make sure it was saved " +
|
||||||
|
"during the first run of the app, when accounts were created!"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||||
|
Log.e("TWIG", "Spending key is being stored")
|
||||||
|
val preferences = getPrefs()
|
||||||
|
val editor = preferences.edit()
|
||||||
|
editor.putString("spending", value)
|
||||||
|
editor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object InsecureWarning {
|
||||||
|
const val message = "Do not use this because it is insecure and only intended for test code and samples. " +
|
||||||
|
"Instead, use the Android Keystore system or a 3rd party library that leverages it."
|
||||||
|
}
|
|
@ -3,21 +3,23 @@ package cash.z.android.wallet.ui.fragment
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import cash.z.android.wallet.R
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import cash.z.android.wallet.R
|
||||||
|
import cash.z.android.wallet.databinding.FragmentHistoryBinding
|
||||||
|
import cash.z.android.wallet.ui.adapter.TransactionAdapter
|
||||||
import cash.z.android.wallet.ui.presenter.HistoryPresenter
|
import cash.z.android.wallet.ui.presenter.HistoryPresenter
|
||||||
|
import cash.z.android.wallet.ui.util.AlternatingRowColorDecoration
|
||||||
|
import cash.z.wallet.sdk.dao.WalletTransaction
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import cash.z.android.wallet.databinding.FragmentHistoryBinding
|
|
||||||
import cash.z.wallet.sdk.dao.WalletTransaction
|
|
||||||
|
|
||||||
|
|
||||||
class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
|
class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
|
||||||
|
|
||||||
|
|
||||||
override val titleResId: Int get() = R.string.destination_title_history
|
|
||||||
lateinit var historyPresenter: HistoryPresenter
|
lateinit var historyPresenter: HistoryPresenter
|
||||||
lateinit var binding: FragmentHistoryBinding
|
lateinit var binding: FragmentHistoryBinding
|
||||||
|
|
||||||
|
@ -28,6 +30,25 @@ class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
|
||||||
.root
|
.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
mainActivity.let { mainActivity ->
|
||||||
|
mainActivity.setSupportActionBar(view.findViewById(R.id.toolbar))
|
||||||
|
mainActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
mainActivity.supportActionBar?.setTitle(R.string.destination_title_history)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
historyPresenter = HistoryPresenter(this, mainActivity.synchronizer)
|
||||||
|
binding.recyclerTransactionsHistory.apply {
|
||||||
|
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
|
||||||
|
adapter = TransactionAdapter()
|
||||||
|
addItemDecoration(AlternatingRowColorDecoration())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
launch {
|
launch {
|
||||||
|
@ -41,7 +62,8 @@ class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setTransactions(transactions: List<WalletTransaction>) {
|
override fun setTransactions(transactions: List<WalletTransaction>) {
|
||||||
}
|
(binding.recyclerTransactionsHistory.adapter as TransactionAdapter).submitList(transactions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.text.SpannableString
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.AccelerateInterpolator
|
import android.view.animation.AccelerateInterpolator
|
||||||
|
@ -44,6 +45,7 @@ import kotlinx.android.synthetic.main.include_home_header.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.nextLong
|
import kotlin.random.nextLong
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,7 +119,11 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
||||||
}
|
}
|
||||||
|
|
||||||
launch {
|
launch {
|
||||||
setFirstRunShown(mainActivity.synchronizer.isFirstRun())
|
Log.e("TWIG", "deciding whether to show first run")
|
||||||
|
val extraDelay = measureTimeMillis {
|
||||||
|
setFirstRunShown(mainActivity.synchronizer.isFirstRun() || mainActivity.synchronizer.isOutOfSync())
|
||||||
|
}
|
||||||
|
Log.e("TWIG", "done deciding whether to show first run in $extraDelay ms. Was that worth it? Or should we toggle a boolean in the application class?")
|
||||||
}
|
}
|
||||||
|
|
||||||
header_active_transaction.visibility = View.GONE
|
header_active_transaction.visibility = View.GONE
|
||||||
|
@ -161,7 +167,11 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
||||||
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
|
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
|
||||||
adapter = TransactionAdapter().also { transactionAdapter = it }
|
adapter = TransactionAdapter().also { transactionAdapter = it }
|
||||||
addItemDecoration(AlternatingRowColorDecoration())
|
addItemDecoration(AlternatingRowColorDecoration())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// recycler_transactions.setOnClickListener {
|
||||||
|
// mainActivity.navController.navigate(R.id.nav_history_fragment)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,7 +208,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
||||||
// var hasEmptyViews = group_empty_view_items.visibility == View.VISIBLE
|
// var hasEmptyViews = group_empty_view_items.visibility == View.VISIBLE
|
||||||
// if(!viewsInitialized) toggleViews(true)
|
// if(!viewsInitialized) toggleViews(true)
|
||||||
//
|
//
|
||||||
val message = if(progress >= 100) "Download complete! Processing blocks..." else "Downloading blocks ($progress%)"
|
val message = if(progress >= 100) "Download complete! Processing blocks..." else "Downloading remaining blocks ($progress%)"
|
||||||
// text_wallet_message.text = message
|
// text_wallet_message.text = message
|
||||||
|
|
||||||
if (snackbar == null && progress <= 50) {
|
if (snackbar == null && progress <= 50) {
|
||||||
|
@ -209,7 +219,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
|
||||||
snackbar?.show()
|
snackbar?.show()
|
||||||
} else {
|
} else {
|
||||||
snackbar?.setText(message)
|
snackbar?.setText(message)
|
||||||
if(progress == 100 && snackbar?.isShownOrQueued != true) snackbar?.show()
|
if(snackbar?.isShownOrQueued != true) snackbar?.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ class ReceiveFragment : BaseFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onAddressLoaded(address: String) {
|
private fun onAddressLoaded(address: String) {
|
||||||
|
Log.e("TWIG", "onAddressLoaded: $address")
|
||||||
qrecycler.load(address)
|
qrecycler.load(address)
|
||||||
.withQuietZoneSize(3)
|
.withQuietZoneSize(3)
|
||||||
.withCorrectionLevel(QRecycler.CorrectionLevel.MEDIUM)
|
.withCorrectionLevel(QRecycler.CorrectionLevel.MEDIUM)
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package cash.z.android.wallet.ui.presenter
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import cash.z.android.wallet.ui.presenter.Presenter.PresenterView
|
||||||
|
import cash.z.wallet.sdk.dao.WalletTransaction
|
||||||
|
import cash.z.wallet.sdk.data.ActiveSendTransaction
|
||||||
|
import cash.z.wallet.sdk.data.ActiveTransaction
|
||||||
|
import cash.z.wallet.sdk.data.Synchronizer
|
||||||
|
import cash.z.wallet.sdk.data.TransactionState
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
|
import kotlinx.coroutines.channels.ReceiveChannel
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class HistoryPresenter(
|
||||||
|
private val view: HistoryView,
|
||||||
|
private val synchronizer: Synchronizer
|
||||||
|
) : Presenter, CoroutineScope {
|
||||||
|
|
||||||
|
private val job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
|
||||||
|
|
||||||
|
interface HistoryView : PresenterView {
|
||||||
|
fun setTransactions(transactions: List<WalletTransaction>)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun start() {
|
||||||
|
Log.e("@TWIG", "historyPresenter starting!")
|
||||||
|
launchTransactionBinder(synchronizer.repository.allTransactions())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
Log.e("@TWIG", "historyPresenter stopping!")
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CoroutineScope.launchTransactionBinder(channel: ReceiveChannel<List<WalletTransaction>>) = launch {
|
||||||
|
Log.e("@TWIG", "transaction binder starting!")
|
||||||
|
for (walletTransactionList in channel) {
|
||||||
|
Log.e("@TWIG", "received ${walletTransactionList.size} transactions for presenting")
|
||||||
|
bind(walletTransactionList)
|
||||||
|
}
|
||||||
|
Log.e("@TWIG", "transaction binder exiting!")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// View Callbacks on Main Thread
|
||||||
|
//
|
||||||
|
|
||||||
|
private fun bind(transactions: List<WalletTransaction>) {
|
||||||
|
Log.e("@TWIG", "binding ${transactions.size} walletTransactions")
|
||||||
|
view.setTransactions(transactions)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -82,22 +82,23 @@ class HomePresenter(
|
||||||
//
|
//
|
||||||
|
|
||||||
private fun bind(old: Long?, new: Long) = onMain {
|
private fun bind(old: Long?, new: Long) = onMain {
|
||||||
Log.e("@TWIG-t", "binding balance of $new")
|
Log.e("@TWIG-b", "binding balance of $new")
|
||||||
view.updateBalance(old ?: 0L, new)
|
view.updateBalance(old ?: 0L, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun bind(transactions: List<WalletTransaction>) = onMain {
|
private fun bind(transactions: List<WalletTransaction>) = onMain {
|
||||||
Log.e("@TWIG-t", "binding ${transactions.size} walletTransactions")
|
Log.e("@TWIG-b", "binding ${transactions.size} walletTransactions")
|
||||||
view.setTransactions(transactions)
|
view.setTransactions(transactions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bind(progress: Int) = onMain {
|
private fun bind(progress: Int) = onMain {
|
||||||
|
Log.e("@TWIG-b", "binding progress of $progress")
|
||||||
view.showProgress(progress)
|
view.showProgress(progress)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) = onMain {
|
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) = onMain {
|
||||||
Log.e("@TWIG-v", "binding a.t. map of size ${activeTransactionMap.size}")
|
Log.e("@TWIG-b", "binding a.t. map of size ${activeTransactionMap.size}")
|
||||||
if (activeTransactionMap.isNotEmpty()) view.setActiveTransactions(activeTransactionMap)
|
if (activeTransactionMap.isNotEmpty()) view.setActiveTransactions(activeTransactionMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<!-- Transactions -->
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_transactions_history"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="72dp"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appbar"
|
||||||
|
tools:itemCount="15"
|
||||||
|
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_transaction_history"
|
||||||
|
tools:orientation="vertical" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/include_app_bar"
|
||||||
|
tools:ignore="MissingConstraints" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</layout>
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/container_transaction"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/home_transaction_item_background"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:elevation="1dp"
|
||||||
|
tools:ignore="RtlSymmetry">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/view_transaction_status"
|
||||||
|
android:layout_width="6dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="1dp"
|
||||||
|
android:layout_marginBottom="1dp"
|
||||||
|
android:background="@color/colorPrimary"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_transaction_timestamp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_transaction_timestamp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_transaction_timestamp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
tools:text="8/23 3:24pm"
|
||||||
|
android:textSize="@dimen/text_size_body_2"
|
||||||
|
android:textColor="@color/text_dark_dimmed"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/view_transaction_status"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_transaction_amount"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="+ 4.244"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textSize="@dimen/text_size_body_2"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue