settings: added functionality to persist settings changes
also removed the request section of the app and put history in its place.
This commit is contained in:
parent
f37da93adc
commit
49017cb1d1
|
@ -14,8 +14,8 @@ android {
|
|||
applicationId "cash.z.android.wallet"
|
||||
minSdkVersion buildConfig.minSdkVersion
|
||||
targetSdkVersion buildConfig.targetSdkVersion
|
||||
versionCode 18 // todo: change this to 1_00_04 format, once we graduate beyond zero for the major version number because leading zeros indicate on octal number.
|
||||
versionName "0.5.0-alpha"
|
||||
versionCode 19 // todo: change this to 1_00_04 format, once we graduate beyond zero for the major version number because leading zeros indicate on octal number.
|
||||
versionName "0.5.1-alpha"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
multiDexEnabled true
|
||||
|
|
Binary file not shown.
|
@ -1,15 +1,20 @@
|
|||
package cash.z.android.wallet.di.module
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import cash.z.android.wallet.BuildConfig
|
||||
import cash.z.android.wallet.ZcashWalletApplication
|
||||
import cash.z.android.wallet.sample.SampleProperties
|
||||
import cash.z.android.wallet.sample.*
|
||||
import cash.z.android.wallet.sample.SampleProperties.COMPACT_BLOCK_PORT
|
||||
import cash.z.android.wallet.sample.SampleProperties.COMPACT_BLOCK_SERVER
|
||||
import cash.z.android.wallet.sample.SampleProperties.PREFS_SERVER_NAME
|
||||
import cash.z.android.wallet.sample.SampleProperties.PREFS_WALLET_DISPLAY_NAME
|
||||
import cash.z.wallet.sdk.data.*
|
||||
import cash.z.wallet.sdk.jni.JniConverter
|
||||
import cash.z.wallet.sdk.secure.Wallet
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
|
@ -19,6 +24,40 @@ import javax.inject.Singleton
|
|||
@Module
|
||||
internal object SynchronizerModule {
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providePrefs(): SharedPreferences {
|
||||
return PreferenceManager.getDefaultSharedPreferences(ZcashWalletApplication.instance)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideWalletConfig(prefs: SharedPreferences): WalletConfig {
|
||||
val walletName = prefs.getString(PREFS_WALLET_DISPLAY_NAME, null)
|
||||
twig("FOUND WALLET DISPLAY NAME : $walletName")
|
||||
return when(walletName) {
|
||||
AliceWallet.displayName -> AliceWallet
|
||||
BobWallet.displayName, null -> BobWallet // Default wallet
|
||||
CarolWallet.displayName -> CarolWallet
|
||||
DaveWallet.displayName -> DaveWallet
|
||||
else -> WalletConfig.create(walletName)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named(PREFS_SERVER_NAME)
|
||||
fun provideServer(prefs: SharedPreferences): String {
|
||||
val serverName = prefs.getString(PREFS_SERVER_NAME, null)
|
||||
// in theory, the actual stored value itself could be null so provide the default this way to be safe
|
||||
val server = Servers.values().firstOrNull { it.displayName == serverName }?.host ?: COMPACT_BLOCK_SERVER //TODO: validate that this is a hostname or IP. For now use default, instead
|
||||
twig("FOUND SERVER DISPLAY NAME : $serverName ($server)")
|
||||
return server
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
|
@ -27,35 +66,35 @@ internal object SynchronizerModule {
|
|||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDownloader(twigger: Twig): CompactBlockStream {
|
||||
return CompactBlockStream(COMPACT_BLOCK_SERVER, COMPACT_BLOCK_PORT, twigger)
|
||||
fun provideDownloader(@Named(PREFS_SERVER_NAME) server: String, twigger: Twig): CompactBlockStream {
|
||||
return CompactBlockStream(server, COMPACT_BLOCK_PORT, twigger)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideProcessor(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): CompactBlockProcessor {
|
||||
return CompactBlockProcessor(application, converter, SampleProperties.wallet.cacheDbName, SampleProperties.wallet.dataDbName, logger = twigger)
|
||||
fun provideProcessor(application: ZcashWalletApplication, converter: JniConverter, walletConfig: WalletConfig, twigger: Twig): CompactBlockProcessor {
|
||||
return CompactBlockProcessor(application, converter, walletConfig.cacheDbName, walletConfig.dataDbName, logger = twigger)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRepository(application: ZcashWalletApplication, converter: JniConverter): TransactionRepository {
|
||||
return PollingTransactionRepository(application, SampleProperties.wallet.dataDbName, 10_000L)
|
||||
fun provideRepository(application: ZcashWalletApplication, walletConfig: WalletConfig, converter: JniConverter): TransactionRepository {
|
||||
return PollingTransactionRepository(application, walletConfig.dataDbName, 10_000L)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideWallet(application: ZcashWalletApplication, converter: JniConverter): Wallet {
|
||||
fun provideWallet(application: ZcashWalletApplication, walletConfig: WalletConfig, converter: JniConverter): Wallet {
|
||||
return Wallet(
|
||||
context = application,
|
||||
converter = converter,
|
||||
dataDbPath = application.getDatabasePath(SampleProperties.wallet.dataDbName).absolutePath,
|
||||
dataDbPath = application.getDatabasePath(walletConfig.dataDbName).absolutePath,
|
||||
paramDestinationDir = "${application.cacheDir.absolutePath}/params",
|
||||
seedProvider = SampleProperties.wallet.seedProvider,
|
||||
spendingKeyProvider = SampleProperties.wallet.spendingKeyProvider
|
||||
seedProvider = walletConfig.seedProvider,
|
||||
spendingKeyProvider = walletConfig.spendingKeyProvider
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,71 +1,116 @@
|
|||
package cash.z.android.wallet.sample
|
||||
|
||||
import android.provider.Settings
|
||||
import cash.z.wallet.sdk.data.SampleSeedProvider
|
||||
import java.math.BigDecimal
|
||||
import java.math.MathContext
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
|
||||
object AliceWallet {
|
||||
const val name = "test.reference.alice"
|
||||
val seedProvider = SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testalice_cache_emulator7.db"
|
||||
const val dataDbName = "testalice_data_emulator7.db"
|
||||
const val defaultSendAddress = "ztestsapling1wcp9fu5d3q945nwwyqxtf0dtn6pv22hmjxa39z0034ap734mvxkqz8kug4r2u2df2keekcne322" // bob's address
|
||||
interface WalletConfig {
|
||||
val displayName: String
|
||||
val seedName: String
|
||||
val seedProvider: ReadOnlyProperty<kotlin.Any?, kotlin.ByteArray>
|
||||
val spendingKeyProvider: ReadWriteProperty<Any?, String>
|
||||
val cacheDbName: String
|
||||
val dataDbName: String
|
||||
val defaultSendAddress: String
|
||||
|
||||
companion object {
|
||||
fun create(name: String): WalletConfig {
|
||||
return object : WalletConfig {
|
||||
override val displayName = name
|
||||
override val seedName = "test.reference.${name}_${Settings.Secure.ANDROID_ID}".sanitizeName()
|
||||
override val seedProvider = SampleSeedProvider(seedName)
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${name.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${name.sanitizeName()}.db"
|
||||
override val defaultSendAddress = BobWallet.defaultSendAddress // send to Alice by default, in other words, behave like Bob, which is the default wallet
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object BobWallet {
|
||||
const val name = "test.reference.bob"
|
||||
val seedProvider =
|
||||
SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testbob_cache_pixel1.db"
|
||||
const val dataDbName = "testbob_data_pixel1.db"
|
||||
const val defaultSendAddress = "ztestsapling1yv696xtjn3jykdej2pqx0999eydvvyfphnw97ddk2h5luyedpqzud3r87aq0d7qna3jzjqqdcvw" // alice's address
|
||||
internal inline fun String.sanitizeName(): String {
|
||||
return this.toLowerCase().filter {
|
||||
it in 'a'..'z' || it in '0'..'9'
|
||||
}
|
||||
}
|
||||
|
||||
object CarolWallet {
|
||||
const val name = "test.reference.carol"
|
||||
val seedProvider =
|
||||
SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testcarol_cache1.db"
|
||||
const val dataDbName = "testcarol_data1.db"
|
||||
const val defaultSendAddress = "ztestsapling1jq4dz0uurs494g0n8nywuurhyy68d6g9na8th7muuvznlux3kmsyehl89xjtu0gx58u26f4xv3d" // dave's address
|
||||
object AliceWallet : WalletConfig {
|
||||
override val displayName = "Alice"
|
||||
override val seedName = "test.reference.$displayName".sanitizeName()
|
||||
override val seedProvider = SampleSeedProvider(seedName)
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${displayName.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${displayName.sanitizeName()}.db"
|
||||
override val defaultSendAddress =
|
||||
"ztestsapling1wrjqt8et9elq7p0ejlgfpt4j9m7r7d4qlt7cke7ppp7dwrpev3yln30c37mrnzzekceajk66h0n" // bob's address
|
||||
}
|
||||
|
||||
object DaveWallet {
|
||||
const val name = "test.reference.dave"
|
||||
val seedProvider =
|
||||
SampleSeedProvider(name)
|
||||
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
|
||||
const val cacheDbName = "testdave_cache.db"
|
||||
const val dataDbName = "testdave_data.db"
|
||||
const val defaultSendAddress = "ztestsapling1gl8rn5u3p0j9xk2vulre5fhe4rq58p4euzuxdqpgrlv7f0qxgtt2lkzd2gzqjnuhmj9yzmpp270" // carol's address
|
||||
object BobWallet : WalletConfig {
|
||||
override val displayName = "Bob"
|
||||
override val seedName = "test.reference.$displayName".sanitizeName()
|
||||
override val seedProvider = SampleSeedProvider(seedName)
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${displayName.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${displayName.sanitizeName()}.db"
|
||||
override val defaultSendAddress =
|
||||
"ztestsapling12pxv67r0kdw58q8tcn8kxhfy9n4vgaa7q8vp0dg24aueuz2mpgv2x7mw95yetcc37efc6q3hewn" // alice's address
|
||||
}
|
||||
|
||||
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"
|
||||
const val defaultSendAddress = "ztestsapling1snmqdnfqnc407pvqw7sld8w5zxx6nd0523kvlj4jf39uvxvh7vn0hs3q38n07806dwwecqwke3t" // dummyseed
|
||||
object CarolWallet : WalletConfig {
|
||||
override val displayName = "Carol"
|
||||
override val seedName = "test.reference.$displayName".sanitizeName()
|
||||
override val seedProvider = SampleSeedProvider(seedName)
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${displayName.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${displayName.sanitizeName()}.db"
|
||||
override val defaultSendAddress =
|
||||
"ztestsapling1y480yqw6h7lwmvw9wsn3h2xxg0np93cv8nq0j3m6g8edc79faevq5adrtzyxgsmu9jfc2hdf6al" // dave's address
|
||||
}
|
||||
|
||||
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")
|
||||
object DaveWallet : WalletConfig {
|
||||
override val displayName = "Dave"
|
||||
override val seedName = "test.reference.$displayName".sanitizeName()
|
||||
override val seedProvider = SampleSeedProvider(seedName)
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${displayName.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${displayName.sanitizeName()}.db"
|
||||
override val defaultSendAddress =
|
||||
"ztestsapling1efxqj5256ywqdc3zntfa0hw6yn4f83k2h7fgngwmxr3h3w7zydlencvh30730ez6p8fwg56htgz" // carol's address
|
||||
}
|
||||
|
||||
object MyWallet : WalletConfig {
|
||||
override val displayName = "MyWallet"
|
||||
override val seedName = "test.reference.$displayName".sanitizeName()
|
||||
override val seedProvider = SampleImportedSeedProvider("295761fce7fdc89fa1095259f5be6375c4a36f7a214767d668f9ef6e17aa6314")
|
||||
override val spendingKeyProvider = SampleSpendingKeySharedPref(seedName)
|
||||
override val cacheDbName = "test_cache_${displayName.sanitizeName()}.db"
|
||||
override val dataDbName = "test_data_${displayName.sanitizeName()}.db"
|
||||
override val defaultSendAddress =
|
||||
"ztestsapling1snmqdnfqnc407pvqw7sld8w5zxx6nd0523kvlj4jf39uvxvh7vn0hs3q38n07806dwwecqwke3t" // dummyseed
|
||||
}
|
||||
|
||||
enum class Servers(val host: String, val displayName: String) {
|
||||
EMULATOR("10.0.2.2", "Localhost"),
|
||||
// WLAN("10.0.0.26"),
|
||||
WLAN1("10.0.2.24", "WLAN Conference"),
|
||||
WLAN2("192.168.1.235", "WLAN Office"),
|
||||
BOLT_TESTNET("ec2-34-228-10-162.compute-1.amazonaws.com", "Bolt Labs Testnet"),
|
||||
ZCASH_TESTNET("lightwalletd.z.cash", "Zcash Testnet")
|
||||
}
|
||||
|
||||
|
||||
// TODO: load most of these properties in later, perhaps from settings
|
||||
object SampleProperties {
|
||||
|
||||
const val PREFS_WALLET_DISPLAY_NAME = "prefs_wallet_name"
|
||||
const val PREFS_SERVER_NAME = "prefs_server_name"
|
||||
|
||||
val COMPACT_BLOCK_SERVER = Servers.ZCASH_TESTNET.host
|
||||
const val COMPACT_BLOCK_PORT = 9067
|
||||
val wallet = DaveWallet
|
||||
// TODO: placeholder until we have a network service for this
|
||||
val USD_PER_ZEC = BigDecimal("49.07", MathContext.DECIMAL128)
|
||||
val USD_PER_ZEC = BigDecimal("52.86", MathContext.DECIMAL128)
|
||||
}
|
|
@ -48,8 +48,6 @@ class SampleSpendingKeySharedPref(private val fileName: String) : ReadWritePrope
|
|||
|
||||
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 " +
|
||||
|
|
|
@ -30,6 +30,7 @@ import cash.z.android.wallet.BuildConfig
|
|||
import cash.z.android.wallet.R
|
||||
import cash.z.android.wallet.ZcashWalletApplication
|
||||
import cash.z.android.wallet.databinding.ActivityMainBinding
|
||||
import cash.z.android.wallet.sample.WalletConfig
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import dagger.android.support.DaggerAppCompatActivity
|
||||
|
@ -50,6 +51,9 @@ class MainActivity : BaseActivity() {
|
|||
@Inject
|
||||
lateinit var synchronizer: Synchronizer
|
||||
|
||||
@Inject
|
||||
lateinit var walletConfig: WalletConfig
|
||||
|
||||
lateinit var binding: ActivityMainBinding
|
||||
lateinit var loadMessages: List<String>
|
||||
|
||||
|
@ -126,7 +130,7 @@ class MainActivity : BaseActivity() {
|
|||
binding.navView.itemIconTintList = null
|
||||
|
||||
binding.navView.doOnLayout {
|
||||
binding.navView.findViewById<TextView>(R.id.text_nav_header_subtitle).text = "Version ${BuildConfig.VERSION_NAME}"
|
||||
binding.navView.findViewById<TextView>(R.id.text_nav_header_subtitle).text = "Version ${BuildConfig.VERSION_NAME} (${walletConfig.displayName})"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -203,15 +203,16 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
|
|||
toggleViews(!isShown)
|
||||
}
|
||||
|
||||
private val stopAnimation = Runnable {
|
||||
setRefreshAnimationPlaying(false).also { twig("refresh false from onRefresh") }
|
||||
}
|
||||
override fun onRefresh() {
|
||||
setRefreshAnimationPlaying(true).also { twig("refresh true from onRefresh") }
|
||||
|
||||
with(binding.includeContent.refreshLayout) {
|
||||
isRefreshing = false
|
||||
val fauxRefresh = Random.nextLong(750L..3000L)
|
||||
postDelayed({
|
||||
setRefreshAnimationPlaying(false).also { twig("refresh false from onRefresh") }
|
||||
}, fauxRefresh)
|
||||
postDelayed(stopAnimation, fauxRefresh)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +280,7 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
|
|||
binding.includeContent.lottieActiveTransaction.setAnimation(R.raw.lottie_send_success)
|
||||
binding.includeContent.lottieActiveTransaction.playAnimation()
|
||||
title = "ZEC Sent"
|
||||
subtitle = "awaiting network confirmation..."
|
||||
subtitle = "Waiting to be mined..."
|
||||
binding.includeContent.textActiveTransactionValue.text = transaction.value.convertZatoshiToZecString(3)
|
||||
binding.includeContent.textActiveTransactionValue.visibility = View.VISIBLE
|
||||
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
|
||||
|
@ -341,6 +342,9 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
|
|||
Toaster.short("Error: unable to find transaction to cancel!")
|
||||
}
|
||||
}
|
||||
binding.lottieZcashBadge.setOnClickListener {
|
||||
binding.lottieZcashBadge.playAnimation()
|
||||
}
|
||||
|
||||
binding.includeContent.refreshLayout.setProgressViewEndTarget(false, (38f * resources.displayMetrics.density).toInt())
|
||||
|
||||
|
@ -514,12 +518,19 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
|
|||
@IdRes val destination:Int
|
||||
) {
|
||||
/* ordered by when they need to be added to the speed dial (i.e. reverse display order) */
|
||||
REQUEST(
|
||||
R.id.fab_request,
|
||||
R.drawable.ic_receipt_24dp,
|
||||
// REQUEST(
|
||||
// R.id.fab_request,
|
||||
// R.drawable.ic_receipt_24dp,
|
||||
// R.color.icon_request,
|
||||
// R.string.destination_menu_label_request,
|
||||
// R.id.nav_request_fragment
|
||||
// ),
|
||||
HISTORY(
|
||||
R.id.fab_history,
|
||||
R.drawable.ic_history_24dp,
|
||||
R.color.icon_request,
|
||||
R.string.destination_menu_label_request,
|
||||
R.id.nav_request_fragment
|
||||
R.string.destination_menu_label_history,
|
||||
R.id.nav_history_fragment
|
||||
),
|
||||
RECEIVE(
|
||||
R.id.fab_receive,
|
||||
|
|
|
@ -1,19 +1,28 @@
|
|||
package cash.z.android.wallet.ui.fragment
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import cash.z.android.wallet.R
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import cash.z.android.wallet.databinding.FragmentSettingsBinding
|
||||
import cash.z.android.wallet.extention.Toaster
|
||||
import cash.z.android.wallet.extention.alert
|
||||
import cash.z.android.wallet.sample.SampleProperties
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class SettingsFragment : BaseFragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var prefs: SharedPreferences
|
||||
lateinit var binding: FragmentSettingsBinding
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
|
@ -25,7 +34,7 @@ class SettingsFragment : BaseFragment() {
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
mainActivity?.setToolbarShown(true)
|
||||
mainActivity?.setToolbarShown(false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
@ -36,11 +45,65 @@ class SettingsFragment : BaseFragment() {
|
|||
mainActivity?.navController?.navigateUp()
|
||||
}
|
||||
}
|
||||
binding.includeToolbar.toolbarApplyOrClose.findViewById<ImageView>(R.id.image_close).apply {
|
||||
setOnClickListener {
|
||||
mainActivity?.navController?.navigateUp()
|
||||
}
|
||||
}
|
||||
binding.includeToolbar.toolbarApplyOrClose.findViewById<ImageView>(R.id.image_apply).apply {
|
||||
setOnClickListener {
|
||||
val userName = binding.spinnerDemoUser.selectedItem.toString()
|
||||
val server = binding.spinnerServers.selectedItem.toString()
|
||||
view.context.alert("Are you sure you want to apply these changes?\n\nUser: $userName\nServer: $server\n\nTHIS WILL EXIT THE APP.") {
|
||||
onApplySettings(userName, server)
|
||||
view.postDelayed({ mainActivity?.finish() }, 2000L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
binding.spinnerServers.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
setCustomServerUiShown(false)
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
val item = binding.spinnerDemoUser.selectedItem.toString()
|
||||
setCustomServerUiShown(item.startsWith("Custom"))
|
||||
}
|
||||
}
|
||||
|
||||
binding.spinnerDemoUser.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
setCustomUserUiShown(false)
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
val item = binding.spinnerDemoUser.selectedItem.toString()
|
||||
setCustomUserUiShown(item.startsWith("Custom"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCustomServerUiShown(isShown: Boolean) {
|
||||
if (isShown) Toaster.short("Custom servers are not yet implemented")
|
||||
}
|
||||
|
||||
private fun setCustomUserUiShown(isShown: Boolean) {
|
||||
if (isShown) Toaster.short("Custom users are not yet implemented")
|
||||
}
|
||||
|
||||
private fun onApplySettings(userName: String, server: String) {
|
||||
AlertDialog.Builder(mainActivity!!).setMessage("Changing everything...").show()
|
||||
prefs.edit().apply {
|
||||
putString(SampleProperties.PREFS_SERVER_NAME, server)
|
||||
putString(SampleProperties.PREFS_WALLET_DISPLAY_NAME, userName)
|
||||
}.apply()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Module
|
||||
@Module
|
||||
abstract class SettingsFragmentModule {
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributeSettingsFragment(): SettingsFragment
|
||||
|
|
|
@ -5,20 +5,23 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.transition.TransitionInflater
|
||||
import cash.z.android.wallet.BuildConfig
|
||||
import cash.z.android.wallet.R
|
||||
import cash.z.android.wallet.databinding.FragmentWelcomeBinding
|
||||
import cash.z.android.wallet.sample.WalletConfig
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class WelcomeFragment : ProgressFragment(R.id.progress_welcome) {
|
||||
|
||||
@Inject
|
||||
lateinit var walletConfig: WalletConfig
|
||||
private lateinit var binding: FragmentWelcomeBinding
|
||||
|
||||
//
|
||||
|
@ -40,8 +43,10 @@ class WelcomeFragment : ProgressFragment(R.id.progress_welcome) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val userName = walletConfig.displayName.substringAfterLast('.').capitalize()
|
||||
val network = if (resources.getBoolean(R.bool.is_testnet)) "Testnet 2.0.1" else "Mainnet 2.0.1"
|
||||
var buildInfo = "PoC v${BuildConfig.VERSION_NAME} $network\nZcash Company - For demo purposes only"
|
||||
var buildInfo = "PoC v${BuildConfig.VERSION_NAME} $network\n" +
|
||||
"Zcash Company - For demo purposes only\nUser: $userName"
|
||||
binding.textWelcomeBuildInfo.text = buildInfo
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class SendPresenter @Inject constructor(
|
|||
*/
|
||||
private val minersFee = 10_000L
|
||||
private var balanceJob: Job? = null
|
||||
private var requiresValidation = true
|
||||
private var requiresValidation = false
|
||||
var sendUiModel = SendUiModel()
|
||||
|
||||
// TODO: find the best set of characters here. Possibly add something to the rust layer to help with this.
|
||||
|
|
|
@ -22,7 +22,7 @@ class LottieLooper(private val lottie: LottieAnimationView, private val loopRang
|
|||
progress = 0f
|
||||
repeatCount = 0
|
||||
addAnimatorListener(this@LottieLooper)
|
||||
playAnimation()
|
||||
lottie.post { playAnimation() }
|
||||
}
|
||||
isPlaying = true
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class LottieLooper(private val lottie: LottieAnimationView, private val loopRang
|
|||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animator?) {
|
||||
onAnimationEnd(animation)
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
|
@ -81,7 +82,8 @@ class LottieLooper(private val lottie: LottieAnimationView, private val loopRang
|
|||
lottie.progress = 1.0f
|
||||
// wait around a bit to see if my listeners detect any movement, then quietly make my getaway
|
||||
lottie.postDelayed({
|
||||
lottie.removeAnimatorListener(this)
|
||||
lottie.removeAllAnimatorListeners()
|
||||
// lottie.removeAnimatorListener(this)
|
||||
lottie.setMinAndMaxFrame(1, lastFrame)
|
||||
}, 500L)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
|
@ -4,6 +4,6 @@
|
|||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillColor="@color/zcashBlue"
|
||||
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||
</vector>
|
||||
|
|
|
@ -109,8 +109,8 @@
|
|||
android:text="@string/cancel"
|
||||
android:textColor="@color/zcashRed"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="@id/transition_active_transaction_bg"
|
||||
app:layout_constraintTop_toBottomOf="@id/transition_active_transaction_bg" />
|
||||
app:layout_constraintEnd_toEndOf="@+id/camera_placeholder"
|
||||
app:layout_constraintTop_toBottomOf="@+id/camera_placeholder" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_amount_background"
|
||||
|
@ -349,8 +349,8 @@
|
|||
android:id="@+id/camera_placeholder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/transition_active_transaction_bg"
|
||||
app:layout_constraintEnd_toEndOf="@id/transition_active_transaction_bg"
|
||||
app:layout_constraintBottom_toBottomOf="@id/input_zcash_address"
|
||||
app:layout_constraintEnd_toEndOf="@id/input_zcash_address"
|
||||
app:layout_constraintStart_toStartOf="@id/transition_active_transaction_bg"
|
||||
app:layout_constraintTop_toTopOf="@id/transition_active_transaction_bg"
|
||||
tools:visibility="gone" />
|
||||
|
@ -498,7 +498,13 @@
|
|||
text_dollar_symbol_header,
|
||||
text_amount_background,
|
||||
text_value_header,
|
||||
image_swap_currency" />
|
||||
image_swap_currency,
|
||||
text_to_label,
|
||||
input_zcash_address,
|
||||
text_address_error,
|
||||
image_address_shortcut,
|
||||
text_value_error,
|
||||
image_scan_qr" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -9,9 +9,8 @@
|
|||
android:background="@color/fragment_history_background">
|
||||
|
||||
<include
|
||||
android:id="@+id/main_app_bar"
|
||||
layout="@layout/include_main_app_bar"
|
||||
android:visibility="invisible"
|
||||
android:id="@+id/include_toolbar"
|
||||
layout="@layout/include_apply_or_close_app_bar"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<!-- -->
|
||||
|
@ -42,7 +41,7 @@
|
|||
android:textSize="@dimen/text_size_caption"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="@id/guideline_content_start"
|
||||
app:layout_constraintTop_toBottomOf="@id/main_app_bar" />
|
||||
app:layout_constraintTop_toBottomOf="@id/include_toolbar" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/spinner_demo_user"
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/main_app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/ZcashTheme.AppBarOverlay"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar_apply_or_close"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp"
|
||||
app:popupTheme="@style/ZcashTheme.PopupOverlay">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_close"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_close_black_24dp"
|
||||
android:tint="@color/zcashWhite" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_apply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_check_black_24dp"
|
||||
android:layout_gravity="right"
|
||||
android:foregroundGravity="right"
|
||||
android:tint="@color/zcashWhite" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</layout>
|
|
@ -14,19 +14,20 @@
|
|||
android:id="@+id/nav_receive_fragment"
|
||||
android:icon="@drawable/ic_qrcode_24dp"
|
||||
android:title="@string/destination_menu_label_receive" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_request_fragment"
|
||||
android:icon="@drawable/ic_receipt_24dp"
|
||||
android:title="@string/destination_menu_label_request" />
|
||||
android:id="@+id/nav_history_fragment"
|
||||
android:icon="@drawable/ic_history_24dp"
|
||||
android:title="@string/destination_menu_label_history" />
|
||||
<!--<item-->
|
||||
<!--android:id="@+id/nav_request_fragment"-->
|
||||
<!--android:icon="@drawable/ic_receipt_24dp"-->
|
||||
<!--android:title="@string/destination_menu_label_request" />-->
|
||||
</group>
|
||||
|
||||
<group
|
||||
android:id="@+id/misc_actions"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_history_fragment"
|
||||
android:icon="@drawable/ic_history_24dp"
|
||||
android:title="@string/destination_menu_label_history" />
|
||||
<item
|
||||
android:id="@+id/nav_about_fragment"
|
||||
android:icon="@drawable/ic_chat_24dp"
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
<resources>
|
||||
<item name="fab_send" type="id"/>
|
||||
<item name="fab_receive" type="id" />
|
||||
<item name="fab_request" type="id" />
|
||||
<item name="fab_history" type="id" />
|
||||
<!--<item name="fab_request" type="id" />-->
|
||||
</resources>
|
|
@ -98,10 +98,16 @@
|
|||
<string-array name="demo_user_names">
|
||||
<item>Alice</item>
|
||||
<item>Bob</item>
|
||||
<item>Carol</item>
|
||||
<item>Dave</item>
|
||||
<item>Custom...</item>
|
||||
</string-array>
|
||||
<string-array name="server_names">
|
||||
<item>Localhost</item>
|
||||
<item>Zcash Testnet</item>
|
||||
<item>Bolt Labs Testnet</item>
|
||||
<item>WLAN Office</item>
|
||||
<item>WLAN Conference</item>
|
||||
<item>Localhost</item>
|
||||
<item>Custom...</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
|
@ -15,8 +15,8 @@ import javax.inject.Singleton
|
|||
@Module
|
||||
internal object SynchronizerModule {
|
||||
|
||||
// const val MOCK_LOAD_DURATION = 3_000L
|
||||
const val MOCK_LOAD_DURATION = 12_000L
|
||||
const val MOCK_LOAD_DURATION = 3_000L
|
||||
// const val MOCK_LOAD_DURATION = 12_000L
|
||||
const val MOCK_TX_INTERVAL = 20_000L
|
||||
// const val MOCK_TX_INTERVAL = 5_000L
|
||||
const val MOCK_ACTIVE_TX_STATE_CHANGE_INTERVAL = 7_000L
|
||||
|
|
Loading…
Reference in New Issue