* #814 Compose back handler Closes #814 * #814 Test hotfixes Closes #814 * Back handling for onboarding Closes #814 * [#814] Changelog update Closes #814 --------- Co-authored-by: Milan Cerovsky <milan.cerovsky@leeaf.life>
This commit is contained in:
parent
508552f0fa
commit
42deed3391
|
@ -9,6 +9,9 @@ directly impact users rather than highlighting other key architectural updates.*
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- The app navigation has been improved to always behave the same for system, gesture, or top app bar back navigation actions.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Proper ZEC amount abbreviation has been added across the entire app as described by the design document
|
- Proper ZEC amount abbreviation has been added across the entire app as described by the design document
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
|
||||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
import cash.z.ecc.android.sdk.fixture.WalletBalanceFixture
|
import cash.z.ecc.android.sdk.fixture.WalletBalanceFixture
|
||||||
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
||||||
|
@ -69,11 +68,6 @@ class SendViewTestSetup(
|
||||||
return lastZecSend
|
return lastZecSend
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLastSendStage(): SendStage? {
|
|
||||||
composeTestRule.waitForIdle()
|
|
||||||
return lastSendStage
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("TestFunctionName")
|
@Suppress("TestFunctionName")
|
||||||
fun DefaultContent() {
|
fun DefaultContent() {
|
||||||
|
@ -111,7 +105,6 @@ class SendViewTestSetup(
|
||||||
balanceState = BalanceStateFixture.new(),
|
balanceState = BalanceStateFixture.new(),
|
||||||
sendStage = sendStage,
|
sendStage = sendStage,
|
||||||
onCreateZecSend = setZecSend,
|
onCreateZecSend = setZecSend,
|
||||||
focusManager = LocalFocusManager.current,
|
|
||||||
onBack = onBackAction,
|
onBack = onBackAction,
|
||||||
onSettings = { onSettingsCount.incrementAndGet() },
|
onSettings = { onSettingsCount.incrementAndGet() },
|
||||||
onQrScannerOpen = {
|
onQrScannerOpen = {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package co.electriccoin.zcash.ui.screen.send.integration
|
package co.electriccoin.zcash.ui.screen.send.integration
|
||||||
|
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
|
||||||
import androidx.compose.ui.test.junit4.StateRestorationTester
|
import androidx.compose.ui.test.junit4.StateRestorationTester
|
||||||
import androidx.compose.ui.test.junit4.createComposeRule
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
import androidx.compose.ui.test.onNodeWithText
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
@ -71,7 +70,6 @@ class SendViewIntegrationTest {
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
walletSnapshot = walletSnapshot,
|
walletSnapshot = walletSnapshot,
|
||||||
spendingKey = spendingKey,
|
spendingKey = spendingKey,
|
||||||
focusManager = LocalFocusManager.current,
|
|
||||||
goToQrScanner = {},
|
goToQrScanner = {},
|
||||||
goBack = {},
|
goBack = {},
|
||||||
goBalances = {},
|
goBalances = {},
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package co.electriccoin.zcash.ui.screen.update.view
|
package co.electriccoin.zcash.ui.screen.update.view
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.screen.update.WrapUpdate
|
import co.electriccoin.zcash.ui.screen.update.WrapUpdate
|
||||||
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
|
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
|
||||||
|
@ -13,10 +15,11 @@ class UpdateViewAndroidTestSetup(
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("TestFunctionName")
|
@Suppress("TestFunctionName")
|
||||||
fun DefaultContent() {
|
fun DefaultContent() {
|
||||||
WrapUpdate(
|
CompositionLocalProvider(LocalActivity provides composeTestRule.activity) {
|
||||||
composeTestRule.activity,
|
WrapUpdate(
|
||||||
updateInfo
|
updateInfo
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDefaultContent() {
|
fun setDefaultContent() {
|
||||||
|
|
|
@ -13,7 +13,6 @@ import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavOptionsBuilder
|
import androidx.navigation.NavOptionsBuilder
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.model.ZecSend
|
import cash.z.ecc.android.sdk.model.ZecSend
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
|
@ -36,6 +35,7 @@ import co.electriccoin.zcash.ui.NavigationTargets.SEED_RECOVERY
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets.SEND_CONFIRMATION
|
import co.electriccoin.zcash.ui.NavigationTargets.SEND_CONFIRMATION
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS
|
import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS
|
||||||
import co.electriccoin.zcash.ui.NavigationTargets.SUPPORT
|
import co.electriccoin.zcash.ui.NavigationTargets.SUPPORT
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalNavController
|
||||||
import co.electriccoin.zcash.ui.common.model.SerializableAddress
|
import co.electriccoin.zcash.ui.common.model.SerializableAddress
|
||||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||||
import co.electriccoin.zcash.ui.configuration.RemoteConfig
|
import co.electriccoin.zcash.ui.configuration.RemoteConfig
|
||||||
|
@ -74,10 +74,7 @@ import kotlinx.serialization.json.Json
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
internal fun MainActivity.Navigation() {
|
internal fun MainActivity.Navigation() {
|
||||||
val navController =
|
val navController = LocalNavController.current
|
||||||
rememberNavController().also {
|
|
||||||
navControllerForTesting = it
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper properties for triggering the system security UI from callbacks
|
// Helper properties for triggering the system security UI from callbacks
|
||||||
val (exportPrivateDataAuthentication, setExportPrivateDataAuthentication) =
|
val (exportPrivateDataAuthentication, setExportPrivateDataAuthentication) =
|
||||||
|
@ -268,7 +265,6 @@ private fun MainActivity.NavigationHome(
|
||||||
backStack: NavBackStackEntry
|
backStack: NavBackStackEntry
|
||||||
) {
|
) {
|
||||||
WrapHome(
|
WrapHome(
|
||||||
goBack = { finish() },
|
|
||||||
goScan = { navController.navigateJustOnce(SCAN) },
|
goScan = { navController.navigateJustOnce(SCAN) },
|
||||||
goSendConfirmation = { zecSend ->
|
goSendConfirmation = { zecSend ->
|
||||||
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
|
navController.currentBackStackEntry?.savedStateHandle?.let { handle ->
|
||||||
|
|
|
@ -5,13 +5,15 @@ import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
import cash.z.ecc.android.sdk.ext.collectWith
|
import cash.z.ecc.android.sdk.ext.collectWith
|
||||||
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
import co.electriccoin.zcash.spackle.EmulatorWtfUtil
|
||||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||||
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ComponentActivity.BindCompLocalProvider(content: @Composable () -> Unit) {
|
fun MainActivity.BindCompLocalProvider(content: @Composable () -> Unit) {
|
||||||
val screenSecurity = ScreenSecurity()
|
val screenSecurity = ScreenSecurity()
|
||||||
observeScreenSecurityFlag(screenSecurity)
|
observeScreenSecurityFlag(screenSecurity)
|
||||||
|
|
||||||
|
@ -20,10 +22,18 @@ fun ComponentActivity.BindCompLocalProvider(content: @Composable () -> Unit) {
|
||||||
|
|
||||||
val screenTimeout = ScreenTimeout()
|
val screenTimeout = ScreenTimeout()
|
||||||
observeScreenTimeoutFlag(screenTimeout)
|
observeScreenTimeoutFlag(screenTimeout)
|
||||||
|
|
||||||
|
val navController =
|
||||||
|
rememberNavController().also {
|
||||||
|
navControllerForTesting = it
|
||||||
|
}
|
||||||
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalScreenSecurity provides screenSecurity,
|
LocalScreenSecurity provides screenSecurity,
|
||||||
LocalScreenBrightness provides screenBrightness,
|
LocalScreenBrightness provides screenBrightness,
|
||||||
LocalScreenTimeout provides screenTimeout,
|
LocalScreenTimeout provides screenTimeout,
|
||||||
|
LocalNavController provides navController,
|
||||||
|
LocalActivity provides this,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.compose
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
|
|
||||||
|
@Suppress("CompositionLocalAllowlist")
|
||||||
|
val LocalActivity =
|
||||||
|
compositionLocalOf<ComponentActivity> {
|
||||||
|
error("Activity not provided")
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.compose
|
||||||
|
|
||||||
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
|
||||||
|
@Suppress("CompositionLocalAllowlist")
|
||||||
|
val LocalNavController =
|
||||||
|
compositionLocalOf<NavHostController> {
|
||||||
|
error("NavController not provided")
|
||||||
|
}
|
|
@ -9,8 +9,6 @@ import co.electriccoin.zcash.preference.model.entry.BooleanPreferenceDefault
|
||||||
import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT
|
import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT
|
||||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
||||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
|
import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
|
||||||
import co.electriccoin.zcash.ui.screen.home.HomeScreenIndex
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.WhileSubscribed
|
import kotlinx.coroutines.flow.WhileSubscribed
|
||||||
|
@ -20,11 +18,6 @@ import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
/**
|
|
||||||
* Current Home sub-screen index in flow.
|
|
||||||
*/
|
|
||||||
val screenIndex: MutableStateFlow<HomeScreenIndex> = MutableStateFlow(HomeScreenIndex.ACCOUNT)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flow of whether background sync is enabled
|
* A flow of whether background sync is enabled
|
||||||
*/
|
*/
|
||||||
|
@ -37,12 +30,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
val isKeepScreenOnWhileSyncing: StateFlow<Boolean?> =
|
val isKeepScreenOnWhileSyncing: StateFlow<Boolean?> =
|
||||||
booleanStateFlow(StandardPreferenceKeys.IS_KEEP_SCREEN_ON_DURING_SYNC)
|
booleanStateFlow(StandardPreferenceKeys.IS_KEEP_SCREEN_ON_DURING_SYNC)
|
||||||
|
|
||||||
/**
|
|
||||||
* A flow of whether the app uses simple or detailed block synchronization status information for the UI
|
|
||||||
*/
|
|
||||||
val isDetailedSyncStatus: StateFlow<Boolean?> =
|
|
||||||
booleanStateFlow(StandardPreferenceKeys.IS_DETAILED_SYNC_STATUS)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flow of whether the app presented the user with an initial restoring dialog
|
* A flow of whether the app presented the user with an initial restoring dialog
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
package co.electriccoin.zcash.ui.screen.about
|
package co.electriccoin.zcash.ui.screen.about
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -12,9 +12,8 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.about.util.WebBrowserUtil
|
import co.electriccoin.zcash.ui.screen.about.util.WebBrowserUtil
|
||||||
|
@ -24,24 +23,17 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MainActivity.WrapAbout(goBack: () -> Unit) {
|
internal fun WrapAbout(goBack: () -> Unit) {
|
||||||
val walletViewModel by viewModels<WalletViewModel>()
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
WrapAbout(
|
BackHandler {
|
||||||
activity = this,
|
goBack()
|
||||||
goBack = goBack,
|
}
|
||||||
topAppBarSubTitleState = walletState
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun WrapAbout(
|
|
||||||
activity: ComponentActivity,
|
|
||||||
goBack: () -> Unit,
|
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
) {
|
|
||||||
val configInfo = ConfigInfo.new(AndroidConfigurationFactory.getInstance(activity.applicationContext))
|
val configInfo = ConfigInfo.new(AndroidConfigurationFactory.getInstance(activity.applicationContext))
|
||||||
val versionInfo = VersionInfo.new(activity.applicationContext)
|
val versionInfo = VersionInfo.new(activity.applicationContext)
|
||||||
|
|
||||||
|
@ -66,7 +58,7 @@ internal fun WrapAbout(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
snackbarHostState = snackbarHostState,
|
snackbarHostState = snackbarHostState,
|
||||||
topAppBarSubTitleState = topAppBarSubTitleState,
|
topAppBarSubTitleState = walletState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,20 @@
|
||||||
package co.electriccoin.zcash.ui.screen.account
|
package co.electriccoin.zcash.ui.screen.account
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.internal.Twig
|
import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -33,10 +34,11 @@ import org.jetbrains.annotations.VisibleForTesting
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapAccount(
|
internal fun WrapAccount(
|
||||||
activity: ComponentActivity,
|
|
||||||
goBalances: () -> Unit,
|
goBalances: () -> Unit,
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>()
|
val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>()
|
||||||
|
@ -59,7 +61,6 @@ internal fun WrapAccount(
|
||||||
|
|
||||||
WrapAccount(
|
WrapAccount(
|
||||||
balanceState = balanceState,
|
balanceState = balanceState,
|
||||||
context = activity.applicationContext,
|
|
||||||
goBalances = goBalances,
|
goBalances = goBalances,
|
||||||
goSettings = goSettings,
|
goSettings = goSettings,
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
|
@ -79,7 +80,6 @@ internal fun WrapAccount(
|
||||||
@Suppress("LongParameterList", "LongMethod")
|
@Suppress("LongParameterList", "LongMethod")
|
||||||
internal fun WrapAccount(
|
internal fun WrapAccount(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
context: Context,
|
|
||||||
goBalances: () -> Unit,
|
goBalances: () -> Unit,
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
transactionsUiState: TransactionUiState,
|
transactionsUiState: TransactionUiState,
|
||||||
|
@ -89,6 +89,8 @@ internal fun WrapAccount(
|
||||||
walletRestoringState: WalletRestoringState,
|
walletRestoringState: WalletRestoringState,
|
||||||
walletSnapshot: WalletSnapshot?
|
walletSnapshot: WalletSnapshot?
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
|
|
|
@ -19,9 +19,9 @@ import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -45,10 +45,11 @@ import org.jetbrains.annotations.VisibleForTesting
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapBalances(
|
internal fun WrapBalances(
|
||||||
activity: MainActivity,
|
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
goMultiTrxSubmissionFailure: () -> Unit,
|
goMultiTrxSubmissionFailure: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val createTransactionsViewModel by activity.viewModels<CreateTransactionsViewModel>()
|
val createTransactionsViewModel by activity.viewModels<CreateTransactionsViewModel>()
|
||||||
|
@ -89,9 +90,9 @@ internal fun WrapBalances(
|
||||||
|
|
||||||
const val DEFAULT_SHIELDING_THRESHOLD = 100000L
|
const val DEFAULT_SHIELDING_THRESHOLD = 100000L
|
||||||
|
|
||||||
|
// This function should be refactored into smaller chunks
|
||||||
@Composable
|
@Composable
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
// This function should be refactored into smaller chunks
|
|
||||||
@Suppress("LongParameterList", "LongMethod", "CyclomaticComplexMethod")
|
@Suppress("LongParameterList", "LongMethod", "CyclomaticComplexMethod")
|
||||||
internal fun WrapBalances(
|
internal fun WrapBalances(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.exportdata
|
package co.electriccoin.zcash.ui.screen.exportdata
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
|
@ -15,6 +14,7 @@ import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.sdk.type.fromResources
|
import cash.z.ecc.sdk.type.fromResources
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.MainActivity
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
|
@ -38,7 +38,6 @@ internal fun MainActivity.WrapExportPrivateData(
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
WrapExportPrivateData(
|
WrapExportPrivateData(
|
||||||
this,
|
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
onShare = onConfirm,
|
onShare = onConfirm,
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
|
@ -48,12 +47,13 @@ internal fun MainActivity.WrapExportPrivateData(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapExportPrivateData(
|
internal fun WrapExportPrivateData(
|
||||||
activity: ComponentActivity,
|
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onShare: () -> Unit,
|
onShare: () -> Unit,
|
||||||
synchronizer: Synchronizer?,
|
synchronizer: Synchronizer?,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
topAppBarSubTitleState: TopAppBarSubTitleState,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,23 @@ package co.electriccoin.zcash.ui.screen.home
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.model.ZecSend
|
import cash.z.ecc.android.sdk.model.ZecSend
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.compose.RestoreScreenBrightness
|
import co.electriccoin.zcash.ui.common.compose.RestoreScreenBrightness
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -30,25 +35,23 @@ import co.electriccoin.zcash.ui.screen.receive.WrapReceive
|
||||||
import co.electriccoin.zcash.ui.screen.send.WrapSend
|
import co.electriccoin.zcash.ui.screen.send.WrapSend
|
||||||
import co.electriccoin.zcash.ui.screen.send.model.SendArguments
|
import co.electriccoin.zcash.ui.screen.send.model.SendArguments
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal fun MainActivity.WrapHome(
|
internal fun WrapHome(
|
||||||
goBack: () -> Unit,
|
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
goMultiTrxSubmissionFailure: () -> Unit,
|
goMultiTrxSubmissionFailure: () -> Unit,
|
||||||
goScan: () -> Unit,
|
goScan: () -> Unit,
|
||||||
goSendConfirmation: (ZecSend) -> Unit,
|
goSendConfirmation: (ZecSend) -> Unit,
|
||||||
sendArguments: SendArguments
|
sendArguments: SendArguments
|
||||||
) {
|
) {
|
||||||
val homeViewModel by viewModels<HomeViewModel>()
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val walletViewModel by viewModels<WalletViewModel>()
|
val homeViewModel by activity.viewModels<HomeViewModel>()
|
||||||
|
|
||||||
val homeScreenIndex = homeViewModel.screenIndex.collectAsStateWithLifecycle().value
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val isKeepScreenOnWhileSyncing = homeViewModel.isKeepScreenOnWhileSyncing.collectAsStateWithLifecycle().value
|
val isKeepScreenOnWhileSyncing = homeViewModel.isKeepScreenOnWhileSyncing.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
|
@ -82,56 +85,58 @@ internal fun MainActivity.WrapHome(
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapHome(
|
WrapHome(
|
||||||
this,
|
|
||||||
goBack = goBack,
|
|
||||||
goScan = goScan,
|
goScan = goScan,
|
||||||
goSendConfirmation = goSendConfirmation,
|
goSendConfirmation = goSendConfirmation,
|
||||||
goSettings = goSettings,
|
goSettings = goSettings,
|
||||||
goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure,
|
goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure,
|
||||||
homeScreenIndex = homeScreenIndex,
|
|
||||||
isKeepScreenOnWhileSyncing = isKeepScreenOnWhileSyncing,
|
isKeepScreenOnWhileSyncing = isKeepScreenOnWhileSyncing,
|
||||||
isShowingRestoreInitDialog = isShowingRestoreInitDialog,
|
isShowingRestoreInitDialog = isShowingRestoreInitDialog,
|
||||||
onPageChange = {
|
|
||||||
homeViewModel.screenIndex.value = it
|
|
||||||
},
|
|
||||||
sendArguments = sendArguments,
|
sendArguments = sendArguments,
|
||||||
setShowingRestoreInitDialog = setShowingRestoreInitDialog,
|
setShowingRestoreInitDialog = setShowingRestoreInitDialog,
|
||||||
walletSnapshot = walletSnapshot
|
walletSnapshot = walletSnapshot
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Suppress("LongParameterList", "LongMethod")
|
@Suppress("LongParameterList", "LongMethod")
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapHome(
|
internal fun WrapHome(
|
||||||
activity: MainActivity,
|
|
||||||
goBack: () -> Unit,
|
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
goMultiTrxSubmissionFailure: () -> Unit,
|
goMultiTrxSubmissionFailure: () -> Unit,
|
||||||
goScan: () -> Unit,
|
goScan: () -> Unit,
|
||||||
goSendConfirmation: (ZecSend) -> Unit,
|
goSendConfirmation: (ZecSend) -> Unit,
|
||||||
homeScreenIndex: HomeScreenIndex,
|
|
||||||
isKeepScreenOnWhileSyncing: Boolean?,
|
isKeepScreenOnWhileSyncing: Boolean?,
|
||||||
isShowingRestoreInitDialog: Boolean,
|
isShowingRestoreInitDialog: Boolean,
|
||||||
onPageChange: (HomeScreenIndex) -> Unit,
|
|
||||||
sendArguments: SendArguments,
|
sendArguments: SendArguments,
|
||||||
setShowingRestoreInitDialog: () -> Unit,
|
setShowingRestoreInitDialog: () -> Unit,
|
||||||
walletSnapshot: WalletSnapshot?,
|
walletSnapshot: WalletSnapshot?,
|
||||||
) {
|
) {
|
||||||
// Flow for propagating the new page index to the pager in the view layer
|
val focusManager = LocalFocusManager.current
|
||||||
val forceHomePageIndexFlow: MutableSharedFlow<ForcePage?> =
|
|
||||||
MutableSharedFlow(
|
|
||||||
Int.MAX_VALUE,
|
|
||||||
Int.MAX_VALUE,
|
|
||||||
BufferOverflow.SUSPEND
|
|
||||||
)
|
|
||||||
val forceIndex = forceHomePageIndexFlow.collectAsState(initial = null).value
|
|
||||||
|
|
||||||
val homeGoBack: () -> Unit = {
|
val activity = LocalActivity.current
|
||||||
when (homeScreenIndex) {
|
|
||||||
HomeScreenIndex.ACCOUNT -> goBack()
|
val scope = rememberCoroutineScope()
|
||||||
HomeScreenIndex.SEND,
|
|
||||||
HomeScreenIndex.RECEIVE,
|
val pagerState =
|
||||||
HomeScreenIndex.BALANCES -> forceHomePageIndexFlow.tryEmit(ForcePage(HomeScreenIndex.ACCOUNT))
|
rememberPagerState(
|
||||||
|
initialPage = 0,
|
||||||
|
initialPageOffsetFraction = 0f,
|
||||||
|
pageCount = { 4 }
|
||||||
|
)
|
||||||
|
|
||||||
|
val homeGoBack: () -> Unit by remember(pagerState.currentPage, scope) {
|
||||||
|
derivedStateOf {
|
||||||
|
{
|
||||||
|
when (pagerState.currentPage) {
|
||||||
|
HomeScreenIndex.ACCOUNT.pageIndex -> activity.finish()
|
||||||
|
HomeScreenIndex.SEND.pageIndex,
|
||||||
|
HomeScreenIndex.RECEIVE.pageIndex,
|
||||||
|
HomeScreenIndex.BALANCES.pageIndex ->
|
||||||
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(HomeScreenIndex.ACCOUNT.pageIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +145,7 @@ internal fun WrapHome(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the screen brightness for all pages except Receive which maintain the screen brightness by itself
|
// Reset the screen brightness for all pages except Receive which maintain the screen brightness by itself
|
||||||
if (homeScreenIndex != HomeScreenIndex.RECEIVE) {
|
if (pagerState.currentPage != HomeScreenIndex.RECEIVE.pageIndex) {
|
||||||
RestoreScreenBrightness()
|
RestoreScreenBrightness()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +157,11 @@ internal fun WrapHome(
|
||||||
testTag = HomeTag.TAB_ACCOUNT,
|
testTag = HomeTag.TAB_ACCOUNT,
|
||||||
screenContent = {
|
screenContent = {
|
||||||
WrapAccount(
|
WrapAccount(
|
||||||
activity = activity,
|
goBalances = {
|
||||||
goBalances = { forceHomePageIndexFlow.tryEmit(ForcePage(HomeScreenIndex.BALANCES)) },
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(HomeScreenIndex.BALANCES.pageIndex)
|
||||||
|
}
|
||||||
|
},
|
||||||
goSettings = goSettings
|
goSettings = goSettings
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -164,10 +172,13 @@ internal fun WrapHome(
|
||||||
testTag = HomeTag.TAB_SEND,
|
testTag = HomeTag.TAB_SEND,
|
||||||
screenContent = {
|
screenContent = {
|
||||||
WrapSend(
|
WrapSend(
|
||||||
activity = activity,
|
|
||||||
goToQrScanner = goScan,
|
goToQrScanner = goScan,
|
||||||
goBack = homeGoBack,
|
goBack = homeGoBack,
|
||||||
goBalances = { forceHomePageIndexFlow.tryEmit(ForcePage(HomeScreenIndex.BALANCES)) },
|
goBalances = {
|
||||||
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(HomeScreenIndex.BALANCES.pageIndex)
|
||||||
|
}
|
||||||
|
},
|
||||||
goSendConfirmation = goSendConfirmation,
|
goSendConfirmation = goSendConfirmation,
|
||||||
goSettings = goSettings,
|
goSettings = goSettings,
|
||||||
sendArguments = sendArguments
|
sendArguments = sendArguments
|
||||||
|
@ -179,10 +190,7 @@ internal fun WrapHome(
|
||||||
title = stringResource(id = R.string.home_tab_receive),
|
title = stringResource(id = R.string.home_tab_receive),
|
||||||
testTag = HomeTag.TAB_RECEIVE,
|
testTag = HomeTag.TAB_RECEIVE,
|
||||||
screenContent = {
|
screenContent = {
|
||||||
WrapReceive(
|
WrapReceive(onSettings = goSettings)
|
||||||
activity = activity,
|
|
||||||
onSettings = goSettings
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
TabItem(
|
TabItem(
|
||||||
|
@ -191,7 +199,6 @@ internal fun WrapHome(
|
||||||
testTag = HomeTag.TAB_BALANCES,
|
testTag = HomeTag.TAB_BALANCES,
|
||||||
screenContent = {
|
screenContent = {
|
||||||
WrapBalances(
|
WrapBalances(
|
||||||
activity = activity,
|
|
||||||
goSettings = goSettings,
|
goSettings = goSettings,
|
||||||
goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure
|
goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure
|
||||||
)
|
)
|
||||||
|
@ -201,33 +208,27 @@ internal fun WrapHome(
|
||||||
|
|
||||||
Home(
|
Home(
|
||||||
subScreens = tabs,
|
subScreens = tabs,
|
||||||
forcePage = forceIndex,
|
|
||||||
isKeepScreenOnWhileSyncing = isKeepScreenOnWhileSyncing,
|
isKeepScreenOnWhileSyncing = isKeepScreenOnWhileSyncing,
|
||||||
isShowingRestoreInitDialog = isShowingRestoreInitDialog,
|
isShowingRestoreInitDialog = isShowingRestoreInitDialog,
|
||||||
onPageChange = onPageChange,
|
|
||||||
setShowingRestoreInitDialog = setShowingRestoreInitDialog,
|
setShowingRestoreInitDialog = setShowingRestoreInitDialog,
|
||||||
walletSnapshot = walletSnapshot
|
walletSnapshot = walletSnapshot,
|
||||||
|
pagerState = pagerState,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
LaunchedEffect(pagerState.currentPage) {
|
||||||
* Wrapper class used to pass forced pages index into the view layer
|
if (pagerState.currentPage != HomeScreenIndex.SEND.pageIndex) {
|
||||||
*/
|
focusManager.clearFocus(true)
|
||||||
class ForcePage(
|
}
|
||||||
val currentPage: HomeScreenIndex,
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of the Home screen sub-screens
|
* Enum of the Home screen sub-screens
|
||||||
*/
|
*/
|
||||||
enum class HomeScreenIndex {
|
@Suppress("MagicNumber")
|
||||||
// WARN: Be careful when re-ordering these, as the ordinal number states for their order
|
enum class HomeScreenIndex(val pageIndex: Int) {
|
||||||
ACCOUNT,
|
ACCOUNT(0),
|
||||||
SEND,
|
SEND(1),
|
||||||
RECEIVE,
|
RECEIVE(2),
|
||||||
BALANCES, ;
|
BALANCES(3)
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun fromIndex(index: Int) = entries[index]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,7 @@ import androidx.compose.material3.TabRow
|
||||||
import androidx.compose.material3.TabRowDefaults
|
import androidx.compose.material3.TabRowDefaults
|
||||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
@ -28,7 +25,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.constraintlayout.compose.ConstraintLayout
|
import androidx.constraintlayout.compose.ConstraintLayout
|
||||||
import androidx.constraintlayout.compose.Dimension
|
import androidx.constraintlayout.compose.Dimension
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.DisableScreenTimeout
|
import co.electriccoin.zcash.ui.common.compose.DisableScreenTimeout
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -37,24 +33,20 @@ import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
import co.electriccoin.zcash.ui.design.component.NavigationTabText
|
import co.electriccoin.zcash.ui.design.component.NavigationTabText
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||||
import co.electriccoin.zcash.ui.screen.home.ForcePage
|
|
||||||
import co.electriccoin.zcash.ui.screen.home.HomeScreenIndex
|
|
||||||
import co.electriccoin.zcash.ui.screen.home.model.TabItem
|
import co.electriccoin.zcash.ui.screen.home.model.TabItem
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Preview("Home")
|
@Preview("Home")
|
||||||
@Composable
|
@Composable
|
||||||
private fun ComposablePreview() {
|
private fun ComposablePreview() {
|
||||||
ZcashTheme(forceDarkMode = false) {
|
ZcashTheme(forceDarkMode = false) {
|
||||||
BlankSurface {
|
BlankSurface {
|
||||||
Home(
|
Home(
|
||||||
forcePage = null,
|
|
||||||
isKeepScreenOnWhileSyncing = false,
|
isKeepScreenOnWhileSyncing = false,
|
||||||
isShowingRestoreInitDialog = false,
|
isShowingRestoreInitDialog = false,
|
||||||
onPageChange = {},
|
|
||||||
setShowingRestoreInitDialog = {},
|
setShowingRestoreInitDialog = {},
|
||||||
subScreens = persistentListOf(),
|
subScreens = persistentListOf(),
|
||||||
walletSnapshot = WalletSnapshotFixture.new(),
|
walletSnapshot = WalletSnapshotFixture.new(),
|
||||||
|
@ -67,44 +59,18 @@ private fun ComposablePreview() {
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
fun Home(
|
fun Home(
|
||||||
forcePage: ForcePage?,
|
|
||||||
isKeepScreenOnWhileSyncing: Boolean?,
|
isKeepScreenOnWhileSyncing: Boolean?,
|
||||||
isShowingRestoreInitDialog: Boolean,
|
isShowingRestoreInitDialog: Boolean,
|
||||||
onPageChange: (HomeScreenIndex) -> Unit,
|
|
||||||
setShowingRestoreInitDialog: () -> Unit,
|
setShowingRestoreInitDialog: () -> Unit,
|
||||||
subScreens: ImmutableList<TabItem>,
|
subScreens: ImmutableList<TabItem>,
|
||||||
walletSnapshot: WalletSnapshot?,
|
walletSnapshot: WalletSnapshot?,
|
||||||
) {
|
pagerState: PagerState =
|
||||||
val pagerState =
|
|
||||||
rememberPagerState(
|
rememberPagerState(
|
||||||
initialPage = 0,
|
initialPage = 0,
|
||||||
initialPageOffsetFraction = 0f,
|
initialPageOffsetFraction = 0f,
|
||||||
pageCount = { subScreens.size }
|
pageCount = { subScreens.size }
|
||||||
)
|
)
|
||||||
|
) {
|
||||||
// Using [rememberUpdatedState] to ensure that always the latest lambda is captured
|
|
||||||
// And to avoid Detekt warning: Lambda parameters in a @Composable that are referenced directly inside of
|
|
||||||
// restarting effects can cause issues or unpredictable behavior.
|
|
||||||
val currentOnPageChange = rememberUpdatedState(newValue = onPageChange)
|
|
||||||
|
|
||||||
// Listening for the current page change
|
|
||||||
LaunchedEffect(pagerState, currentOnPageChange) {
|
|
||||||
snapshotFlow {
|
|
||||||
pagerState.currentPage
|
|
||||||
}.distinctUntilChanged()
|
|
||||||
.collect { page ->
|
|
||||||
Twig.info { "Current pager page: $page" }
|
|
||||||
currentOnPageChange.value(HomeScreenIndex.fromIndex(page))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force page change e.g. when system back navigation event detected
|
|
||||||
forcePage?.let {
|
|
||||||
LaunchedEffect(forcePage) {
|
|
||||||
pagerState.animateScrollToPage(forcePage.currentPage.ordinal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HomeContent(
|
HomeContent(
|
||||||
pagerState = pagerState,
|
pagerState = pagerState,
|
||||||
subScreens = subScreens,
|
subScreens = subScreens,
|
||||||
|
@ -124,7 +90,7 @@ fun Home(
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
fun HomeContent(
|
private fun HomeContent(
|
||||||
pagerState: PagerState,
|
pagerState: PagerState,
|
||||||
subScreens: ImmutableList<TabItem>
|
subScreens: ImmutableList<TabItem>
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
package co.electriccoin.zcash.ui.screen.newwalletrecovery
|
package co.electriccoin.zcash.ui.screen.newwalletrecovery
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import cash.z.ecc.android.sdk.model.PersistableWallet
|
import cash.z.ecc.android.sdk.model.PersistableWallet
|
||||||
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.screen.newwalletrecovery.view.NewWalletRecovery
|
import co.electriccoin.zcash.ui.screen.newwalletrecovery.view.NewWalletRecovery
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainActivity.WrapNewWalletRecovery(
|
fun WrapNewWalletRecovery(
|
||||||
persistableWallet: PersistableWallet,
|
persistableWallet: PersistableWallet,
|
||||||
onBackupComplete: () -> Unit
|
onBackupComplete: () -> Unit
|
||||||
) {
|
) {
|
||||||
WrapNewWalletRecovery(this, persistableWallet, onBackupComplete)
|
val activity = LocalActivity.current
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun WrapNewWalletRecovery(
|
|
||||||
activity: ComponentActivity,
|
|
||||||
persistableWallet: PersistableWallet,
|
|
||||||
onBackupComplete: () -> Unit
|
|
||||||
) {
|
|
||||||
val versionInfo = VersionInfo.new(activity.applicationContext)
|
val versionInfo = VersionInfo.new(activity.applicationContext)
|
||||||
|
|
||||||
NewWalletRecovery(
|
NewWalletRecovery(
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.onboarding
|
package co.electriccoin.zcash.ui.screen.onboarding
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
@ -15,7 +14,7 @@ import cash.z.ecc.android.sdk.model.SeedPhrase
|
||||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.sdk.type.fromResources
|
import cash.z.ecc.sdk.type.fromResources
|
||||||
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
import co.electriccoin.zcash.spackle.FirebaseTestLabUtil
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
import co.electriccoin.zcash.ui.common.model.OnboardingState
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
|
@ -25,14 +24,10 @@ import co.electriccoin.zcash.ui.screen.onboarding.view.Onboarding
|
||||||
import co.electriccoin.zcash.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
import co.electriccoin.zcash.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.restore.WrapRestore
|
import co.electriccoin.zcash.ui.screen.restore.WrapRestore
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun MainActivity.WrapOnboarding() {
|
|
||||||
WrapOnboarding(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapOnboarding(activity: ComponentActivity) {
|
internal fun WrapOnboarding() {
|
||||||
|
val activity = LocalActivity.current
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
val onboardingViewModel by activity.viewModels<OnboardingViewModel>()
|
val onboardingViewModel by activity.viewModels<OnboardingViewModel>()
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ package co.electriccoin.zcash.ui.screen.receive
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -16,6 +15,7 @@ import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
import co.electriccoin.zcash.spackle.getInternalCacheDirSuspend
|
import co.electriccoin.zcash.spackle.getInternalCacheDirSuspend
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.compose.ScreenBrightnessState
|
import co.electriccoin.zcash.ui.common.compose.ScreenBrightnessState
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
|
@ -31,10 +31,9 @@ import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapReceive(
|
internal fun WrapReceive(onSettings: () -> Unit) {
|
||||||
activity: ComponentActivity,
|
val activity = LocalActivity.current
|
||||||
onSettings: () -> Unit,
|
|
||||||
) {
|
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val brightnessViewModel by activity.viewModels<ScreenBrightnessViewModel>()
|
val brightnessViewModel by activity.viewModels<ScreenBrightnessViewModel>()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package co.electriccoin.zcash.ui.screen.restore.view
|
package co.electriccoin.zcash.ui.screen.restore.view
|
||||||
|
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
@ -229,6 +230,11 @@ fun RestoreWallet(
|
||||||
val currentStage = restoreState.current.collectAsStateWithLifecycle().value
|
val currentStage = restoreState.current.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
var isSeedValid by rememberSaveable { mutableStateOf(false) }
|
var isSeedValid by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
BackHandler {
|
||||||
|
onBack()
|
||||||
|
}
|
||||||
|
|
||||||
// To avoid unnecessary recompositions that this flow produces
|
// To avoid unnecessary recompositions that this flow produces
|
||||||
SideEffect {
|
SideEffect {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.scan
|
package co.electriccoin.zcash.ui.screen.scan
|
||||||
|
|
||||||
import android.content.Context
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -9,6 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.type.AddressType
|
import cash.z.ecc.android.sdk.type.AddressType
|
||||||
|
@ -33,8 +34,11 @@ internal fun MainActivity.WrapScanValidator(
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
|
BackHandler {
|
||||||
|
goBack()
|
||||||
|
}
|
||||||
|
|
||||||
WrapScan(
|
WrapScan(
|
||||||
context = this,
|
|
||||||
onScanValid = onScanValid,
|
onScanValid = onScanValid,
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
|
@ -44,12 +48,13 @@ internal fun MainActivity.WrapScanValidator(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WrapScan(
|
fun WrapScan(
|
||||||
context: Context,
|
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onScanValid: (address: SerializableAddress) -> Unit,
|
onScanValid: (address: SerializableAddress) -> Unit,
|
||||||
synchronizer: Synchronizer?,
|
synchronizer: Synchronizer?,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
topAppBarSubTitleState: TopAppBarSubTitleState,
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.scan.view
|
package co.electriccoin.zcash.ui.screen.scan.view
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
@ -696,7 +695,6 @@ fun ScanCameraView(
|
||||||
)
|
)
|
||||||
|
|
||||||
imageAnalysis.qrCodeFlow(
|
imageAnalysis.qrCodeFlow(
|
||||||
context = context,
|
|
||||||
framePosition = framePosition,
|
framePosition = framePosition,
|
||||||
).collectAsState(initial = null).value?.let {
|
).collectAsState(initial = null).value?.let {
|
||||||
onScanned(it)
|
onScanned(it)
|
||||||
|
@ -707,11 +705,10 @@ fun ScanCameraView(
|
||||||
// Using callbackFlow because QrCodeAnalyzer has a non-suspending callback which makes
|
// Using callbackFlow because QrCodeAnalyzer has a non-suspending callback which makes
|
||||||
// a basic flow builder not work here.
|
// a basic flow builder not work here.
|
||||||
@Composable
|
@Composable
|
||||||
fun ImageAnalysis.qrCodeFlow(
|
fun ImageAnalysis.qrCodeFlow(framePosition: FramePosition): Flow<String> {
|
||||||
context: Context,
|
val context = LocalContext.current
|
||||||
framePosition: FramePosition,
|
|
||||||
): Flow<String> =
|
return remember {
|
||||||
remember {
|
|
||||||
callbackFlow {
|
callbackFlow {
|
||||||
setAnalyzer(
|
setAnalyzer(
|
||||||
ContextCompat.getMainExecutor(context),
|
ContextCompat.getMainExecutor(context),
|
||||||
|
@ -732,3 +729,4 @@ fun ImageAnalysis.qrCodeFlow(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,31 +1,24 @@
|
||||||
package co.electriccoin.zcash.ui.screen.securitywarning
|
package co.electriccoin.zcash.ui.screen.securitywarning
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
import co.electriccoin.zcash.configuration.AndroidConfigurationFactory
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.screen.securitywarning.view.SecurityWarning
|
import co.electriccoin.zcash.ui.screen.securitywarning.view.SecurityWarning
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun MainActivity.WrapSecurityWarning(
|
|
||||||
onBack: () -> Unit,
|
|
||||||
onConfirm: () -> Unit
|
|
||||||
) {
|
|
||||||
WrapSecurityWarning(
|
|
||||||
this,
|
|
||||||
onBack = onBack,
|
|
||||||
onConfirm = onConfirm
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapSecurityWarning(
|
internal fun WrapSecurityWarning(
|
||||||
activity: ComponentActivity,
|
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onConfirm: () -> Unit
|
onConfirm: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
|
BackHandler {
|
||||||
|
onBack()
|
||||||
|
}
|
||||||
|
|
||||||
SecurityWarning(
|
SecurityWarning(
|
||||||
versionInfo = VersionInfo.new(activity.applicationContext),
|
versionInfo = VersionInfo.new(activity.applicationContext),
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package co.electriccoin.zcash.ui.screen.seedrecovery
|
package co.electriccoin.zcash.ui.screen.seedrecovery
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
import co.electriccoin.zcash.spackle.ClipboardManagerUtil
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.SecretState
|
import co.electriccoin.zcash.ui.common.viewmodel.SecretState
|
||||||
|
@ -17,11 +16,13 @@ import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||||
import co.electriccoin.zcash.ui.screen.seedrecovery.view.SeedRecovery
|
import co.electriccoin.zcash.ui.screen.seedrecovery.view.SeedRecovery
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MainActivity.WrapSeedRecovery(
|
internal fun WrapSeedRecovery(
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onDone: () -> Unit,
|
onDone: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val walletViewModel by viewModels<WalletViewModel>()
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
|
@ -30,7 +31,6 @@ internal fun MainActivity.WrapSeedRecovery(
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
WrapSeedRecovery(
|
WrapSeedRecovery(
|
||||||
activity = this,
|
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
onDone = onDone,
|
onDone = onDone,
|
||||||
secretState = secretState,
|
secretState = secretState,
|
||||||
|
@ -42,13 +42,14 @@ internal fun MainActivity.WrapSeedRecovery(
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
private fun WrapSeedRecovery(
|
private fun WrapSeedRecovery(
|
||||||
activity: ComponentActivity,
|
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
onDone: () -> Unit,
|
onDone: () -> Unit,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
topAppBarSubTitleState: TopAppBarSubTitleState,
|
||||||
synchronizer: Synchronizer?,
|
synchronizer: Synchronizer?,
|
||||||
secretState: SecretState,
|
secretState: SecretState,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
BackHandler {
|
BackHandler {
|
||||||
goBack()
|
goBack()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.send
|
package co.electriccoin.zcash.ui.screen.send
|
||||||
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.BackHandler
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
@ -12,9 +10,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.focus.FocusManager
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
||||||
|
@ -25,12 +21,11 @@ import cash.z.ecc.android.sdk.model.toZecString
|
||||||
import cash.z.ecc.android.sdk.type.AddressType
|
import cash.z.ecc.android.sdk.type.AddressType
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.HomeViewModel
|
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||||
import co.electriccoin.zcash.ui.screen.home.HomeScreenIndex
|
|
||||||
import co.electriccoin.zcash.ui.screen.send.ext.Saver
|
import co.electriccoin.zcash.ui.screen.send.ext.Saver
|
||||||
import co.electriccoin.zcash.ui.screen.send.model.AmountState
|
import co.electriccoin.zcash.ui.screen.send.model.AmountState
|
||||||
import co.electriccoin.zcash.ui.screen.send.model.MemoState
|
import co.electriccoin.zcash.ui.screen.send.model.MemoState
|
||||||
|
@ -44,7 +39,6 @@ import java.util.Locale
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
internal fun WrapSend(
|
internal fun WrapSend(
|
||||||
activity: ComponentActivity,
|
|
||||||
sendArguments: SendArguments?,
|
sendArguments: SendArguments?,
|
||||||
goToQrScanner: () -> Unit,
|
goToQrScanner: () -> Unit,
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
|
@ -52,6 +46,8 @@ internal fun WrapSend(
|
||||||
goSendConfirmation: (ZecSend) -> Unit,
|
goSendConfirmation: (ZecSend) -> Unit,
|
||||||
goSettings: () -> Unit,
|
goSettings: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val walletViewModel by activity.viewModels<WalletViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val hasCameraFeature = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
|
val hasCameraFeature = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
|
||||||
|
@ -62,15 +58,6 @@ internal fun WrapSend(
|
||||||
|
|
||||||
val spendingKey = walletViewModel.spendingKey.collectAsStateWithLifecycle().value
|
val spendingKey = walletViewModel.spendingKey.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
val homeViewModel by activity.viewModels<HomeViewModel>()
|
|
||||||
|
|
||||||
val focusManager = LocalFocusManager.current
|
|
||||||
|
|
||||||
if (homeViewModel.screenIndex.collectAsStateWithLifecycle().value != HomeScreenIndex.SEND) {
|
|
||||||
// Clear focus on Send Form text fields
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO [#1171]: Remove default MonetarySeparators locale
|
// TODO [#1171]: Remove default MonetarySeparators locale
|
||||||
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
|
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
|
||||||
val monetarySeparators = MonetarySeparators.current(Locale.US)
|
val monetarySeparators = MonetarySeparators.current(Locale.US)
|
||||||
|
@ -85,7 +72,6 @@ internal fun WrapSend(
|
||||||
synchronizer = synchronizer,
|
synchronizer = synchronizer,
|
||||||
walletSnapshot = walletSnapshot,
|
walletSnapshot = walletSnapshot,
|
||||||
spendingKey = spendingKey,
|
spendingKey = spendingKey,
|
||||||
focusManager = focusManager,
|
|
||||||
goToQrScanner = goToQrScanner,
|
goToQrScanner = goToQrScanner,
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
goBalances = goBalances,
|
goBalances = goBalances,
|
||||||
|
@ -102,7 +88,6 @@ internal fun WrapSend(
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapSend(
|
internal fun WrapSend(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
focusManager: FocusManager,
|
|
||||||
goToQrScanner: () -> Unit,
|
goToQrScanner: () -> Unit,
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
goBalances: () -> Unit,
|
goBalances: () -> Unit,
|
||||||
|
@ -188,10 +173,6 @@ internal fun WrapSend(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackHandler {
|
|
||||||
onBackAction()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null == synchronizer || null == walletSnapshot || null == spendingKey) {
|
if (null == synchronizer || null == walletSnapshot || null == spendingKey) {
|
||||||
// TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer
|
// TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer
|
||||||
// TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available
|
// TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available
|
||||||
|
@ -217,7 +198,6 @@ internal fun WrapSend(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
focusManager = focusManager,
|
|
||||||
onBack = onBackAction,
|
onBack = onBackAction,
|
||||||
onSettings = goSettings,
|
onSettings = goSettings,
|
||||||
recipientAddressState = recipientAddressState,
|
recipientAddressState = recipientAddressState,
|
||||||
|
|
|
@ -31,7 +31,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusDirection
|
import androidx.compose.ui.focus.FocusDirection
|
||||||
import androidx.compose.ui.focus.FocusManager
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.layout.positionInRoot
|
import androidx.compose.ui.layout.positionInRoot
|
||||||
|
@ -93,7 +92,6 @@ private fun PreviewSendForm() {
|
||||||
Send(
|
Send(
|
||||||
sendStage = SendStage.Form,
|
sendStage = SendStage.Form,
|
||||||
onCreateZecSend = {},
|
onCreateZecSend = {},
|
||||||
focusManager = LocalFocusManager.current,
|
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onSettings = {},
|
onSettings = {},
|
||||||
onQrScannerOpen = {},
|
onQrScannerOpen = {},
|
||||||
|
@ -119,7 +117,6 @@ private fun SendFormTransparentAddressPreview() {
|
||||||
Send(
|
Send(
|
||||||
sendStage = SendStage.Form,
|
sendStage = SendStage.Form,
|
||||||
onCreateZecSend = {},
|
onCreateZecSend = {},
|
||||||
focusManager = LocalFocusManager.current,
|
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onSettings = {},
|
onSettings = {},
|
||||||
onQrScannerOpen = {},
|
onQrScannerOpen = {},
|
||||||
|
@ -151,7 +148,6 @@ fun Send(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
sendStage: SendStage,
|
sendStage: SendStage,
|
||||||
onCreateZecSend: (ZecSend) -> Unit,
|
onCreateZecSend: (ZecSend) -> Unit,
|
||||||
focusManager: FocusManager,
|
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onSettings: () -> Unit,
|
onSettings: () -> Unit,
|
||||||
onQrScannerOpen: () -> Unit,
|
onQrScannerOpen: () -> Unit,
|
||||||
|
@ -176,7 +172,6 @@ fun Send(
|
||||||
balanceState = balanceState,
|
balanceState = balanceState,
|
||||||
walletSnapshot = walletSnapshot,
|
walletSnapshot = walletSnapshot,
|
||||||
onBack = onBack,
|
onBack = onBack,
|
||||||
focusManager = focusManager,
|
|
||||||
sendStage = sendStage,
|
sendStage = sendStage,
|
||||||
onCreateZecSend = onCreateZecSend,
|
onCreateZecSend = onCreateZecSend,
|
||||||
recipientAddressState = recipientAddressState,
|
recipientAddressState = recipientAddressState,
|
||||||
|
@ -232,7 +227,6 @@ private fun SendTopAppBar(
|
||||||
private fun SendMainContent(
|
private fun SendMainContent(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
walletSnapshot: WalletSnapshot,
|
walletSnapshot: WalletSnapshot,
|
||||||
focusManager: FocusManager,
|
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
goBalances: () -> Unit,
|
goBalances: () -> Unit,
|
||||||
onCreateZecSend: (ZecSend) -> Unit,
|
onCreateZecSend: (ZecSend) -> Unit,
|
||||||
|
@ -260,7 +254,6 @@ private fun SendMainContent(
|
||||||
memoState = memoState,
|
memoState = memoState,
|
||||||
setMemoState = setMemoState,
|
setMemoState = setMemoState,
|
||||||
onCreateZecSend = onCreateZecSend,
|
onCreateZecSend = onCreateZecSend,
|
||||||
focusManager = focusManager,
|
|
||||||
onQrScannerOpen = onQrScannerOpen,
|
onQrScannerOpen = onQrScannerOpen,
|
||||||
goBalances = goBalances,
|
goBalances = goBalances,
|
||||||
hasCameraFeature = hasCameraFeature,
|
hasCameraFeature = hasCameraFeature,
|
||||||
|
@ -286,7 +279,6 @@ private fun SendMainContent(
|
||||||
private fun SendForm(
|
private fun SendForm(
|
||||||
balanceState: BalanceState,
|
balanceState: BalanceState,
|
||||||
walletSnapshot: WalletSnapshot,
|
walletSnapshot: WalletSnapshot,
|
||||||
focusManager: FocusManager,
|
|
||||||
recipientAddressState: RecipientAddressState,
|
recipientAddressState: RecipientAddressState,
|
||||||
onRecipientAddressChange: (String) -> Unit,
|
onRecipientAddressChange: (String) -> Unit,
|
||||||
amountState: AmountState,
|
amountState: AmountState,
|
||||||
|
@ -329,7 +321,6 @@ private fun SendForm(
|
||||||
// TODO [#1256]: https://github.com/Electric-Coin-Company/zashi-android/issues/1256
|
// TODO [#1256]: https://github.com/Electric-Coin-Company/zashi-android/issues/1256
|
||||||
|
|
||||||
SendFormAddressTextField(
|
SendFormAddressTextField(
|
||||||
focusManager = focusManager,
|
|
||||||
hasCameraFeature = hasCameraFeature,
|
hasCameraFeature = hasCameraFeature,
|
||||||
onQrScannerOpen = onQrScannerOpen,
|
onQrScannerOpen = onQrScannerOpen,
|
||||||
recipientAddressState = recipientAddressState,
|
recipientAddressState = recipientAddressState,
|
||||||
|
@ -340,7 +331,6 @@ private fun SendForm(
|
||||||
|
|
||||||
SendFormAmountTextField(
|
SendFormAmountTextField(
|
||||||
amountSate = amountState,
|
amountSate = amountState,
|
||||||
focusManager = focusManager,
|
|
||||||
imeAction =
|
imeAction =
|
||||||
if (recipientAddressState.type == AddressType.Transparent) {
|
if (recipientAddressState.type == AddressType.Transparent) {
|
||||||
ImeAction.Done
|
ImeAction.Done
|
||||||
|
@ -358,7 +348,6 @@ private fun SendForm(
|
||||||
SendFormMemoTextField(
|
SendFormMemoTextField(
|
||||||
memoState = memoState,
|
memoState = memoState,
|
||||||
setMemoState = setMemoState,
|
setMemoState = setMemoState,
|
||||||
focusManager = focusManager,
|
|
||||||
isMemoFieldAvailable = (
|
isMemoFieldAvailable = (
|
||||||
recipientAddressState.address.isEmpty() ||
|
recipientAddressState.address.isEmpty() ||
|
||||||
recipientAddressState.type is AddressType.Invalid ||
|
recipientAddressState.type is AddressType.Invalid ||
|
||||||
|
@ -475,12 +464,13 @@ fun SendButton(
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
@Composable
|
@Composable
|
||||||
fun SendFormAddressTextField(
|
fun SendFormAddressTextField(
|
||||||
focusManager: FocusManager,
|
|
||||||
hasCameraFeature: Boolean,
|
hasCameraFeature: Boolean,
|
||||||
onQrScannerOpen: () -> Unit,
|
onQrScannerOpen: () -> Unit,
|
||||||
recipientAddressState: RecipientAddressState,
|
recipientAddressState: RecipientAddressState,
|
||||||
setRecipientAddress: (String) -> Unit,
|
setRecipientAddress: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
|
@ -560,13 +550,14 @@ fun SendFormAddressTextField(
|
||||||
@Composable
|
@Composable
|
||||||
fun SendFormAmountTextField(
|
fun SendFormAmountTextField(
|
||||||
amountSate: AmountState,
|
amountSate: AmountState,
|
||||||
focusManager: FocusManager,
|
|
||||||
imeAction: ImeAction,
|
imeAction: ImeAction,
|
||||||
isTransparentRecipient: Boolean,
|
isTransparentRecipient: Boolean,
|
||||||
monetarySeparators: MonetarySeparators,
|
monetarySeparators: MonetarySeparators,
|
||||||
setAmountState: (AmountState) -> Unit,
|
setAmountState: (AmountState) -> Unit,
|
||||||
walletSnapshot: WalletSnapshot,
|
walletSnapshot: WalletSnapshot,
|
||||||
) {
|
) {
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val zcashCurrency = ZcashCurrency.getLocalizedName(context)
|
val zcashCurrency = ZcashCurrency.getLocalizedName(context)
|
||||||
|
@ -580,6 +571,7 @@ fun SendFormAmountTextField(
|
||||||
stringResource(id = R.string.send_amount_invalid)
|
stringResource(id = R.string.send_amount_invalid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is AmountState.Valid -> {
|
is AmountState.Valid -> {
|
||||||
if (walletSnapshot.spendableBalance() < amountSate.zatoshi) {
|
if (walletSnapshot.spendableBalance() < amountSate.zatoshi) {
|
||||||
stringResource(id = R.string.send_amount_insufficient_balance)
|
stringResource(id = R.string.send_amount_insufficient_balance)
|
||||||
|
@ -651,13 +643,14 @@ fun SendFormAmountTextField(
|
||||||
@Suppress("LongMethod", "LongParameterList")
|
@Suppress("LongMethod", "LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
fun SendFormMemoTextField(
|
fun SendFormMemoTextField(
|
||||||
focusManager: FocusManager,
|
|
||||||
isMemoFieldAvailable: Boolean,
|
isMemoFieldAvailable: Boolean,
|
||||||
memoState: MemoState,
|
memoState: MemoState,
|
||||||
setMemoState: (MemoState) -> Unit,
|
setMemoState: (MemoState) -> Unit,
|
||||||
scrollState: ScrollState,
|
scrollState: ScrollState,
|
||||||
scrollTo: Int
|
scrollTo: Int
|
||||||
) {
|
) {
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package co.electriccoin.zcash.ui.screen.settings
|
package co.electriccoin.zcash.ui.screen.settings
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
|
||||||
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
import co.electriccoin.zcash.ui.common.model.VersionInfo
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
|
||||||
|
@ -17,42 +15,20 @@ import co.electriccoin.zcash.ui.screen.settings.view.Settings
|
||||||
import co.electriccoin.zcash.ui.screen.settings.viewmodel.SettingsViewModel
|
import co.electriccoin.zcash.ui.screen.settings.viewmodel.SettingsViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MainActivity.WrapSettings(
|
internal fun WrapSettings(
|
||||||
goAbout: () -> Unit,
|
goAbout: () -> Unit,
|
||||||
goAdvancedSettings: () -> Unit,
|
goAdvancedSettings: () -> Unit,
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
goFeedback: () -> Unit,
|
goFeedback: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val walletViewModel by viewModels<WalletViewModel>()
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val settingsViewModel by viewModels<SettingsViewModel>()
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
|
val settingsViewModel by activity.viewModels<SettingsViewModel>()
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
WrapSettings(
|
|
||||||
activity = this,
|
|
||||||
goAbout = goAbout,
|
|
||||||
goAdvancedSettings = goAdvancedSettings,
|
|
||||||
goBack = goBack,
|
|
||||||
goFeedback = goFeedback,
|
|
||||||
settingsViewModel = settingsViewModel,
|
|
||||||
topAppBarSubTitleState = walletState,
|
|
||||||
walletViewModel = walletViewModel,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Suppress("LongParameterList")
|
|
||||||
private fun WrapSettings(
|
|
||||||
activity: ComponentActivity,
|
|
||||||
goAbout: () -> Unit,
|
|
||||||
goAdvancedSettings: () -> Unit,
|
|
||||||
goBack: () -> Unit,
|
|
||||||
goFeedback: () -> Unit,
|
|
||||||
settingsViewModel: SettingsViewModel,
|
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
|
||||||
walletViewModel: WalletViewModel,
|
|
||||||
) {
|
|
||||||
val isBackgroundSyncEnabled = settingsViewModel.isBackgroundSync.collectAsStateWithLifecycle().value
|
val isBackgroundSyncEnabled = settingsViewModel.isBackgroundSync.collectAsStateWithLifecycle().value
|
||||||
val isKeepScreenOnWhileSyncing = settingsViewModel.isKeepScreenOnWhileSyncing.collectAsStateWithLifecycle().value
|
val isKeepScreenOnWhileSyncing = settingsViewModel.isKeepScreenOnWhileSyncing.collectAsStateWithLifecycle().value
|
||||||
val isAnalyticsEnabled = settingsViewModel.isAnalyticsEnabled.collectAsStateWithLifecycle().value
|
val isAnalyticsEnabled = settingsViewModel.isAnalyticsEnabled.collectAsStateWithLifecycle().value
|
||||||
|
@ -97,7 +73,7 @@ private fun WrapSettings(
|
||||||
onAnalyticsSettingsChanged = {
|
onAnalyticsSettingsChanged = {
|
||||||
settingsViewModel.setAnalyticsEnabled(it)
|
settingsViewModel.setAnalyticsEnabled(it)
|
||||||
},
|
},
|
||||||
topAppBarSubTitleState = topAppBarSubTitleState,
|
topAppBarSubTitleState = walletState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
package co.electriccoin.zcash.ui.screen.support
|
package co.electriccoin.zcash.ui.screen.support
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
@ -12,8 +13,8 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.support.model.SupportInfo
|
import co.electriccoin.zcash.ui.screen.support.model.SupportInfo
|
||||||
|
@ -24,30 +25,37 @@ import co.electriccoin.zcash.ui.util.EmailUtil
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MainActivity.WrapSupport(goBack: () -> Unit) {
|
internal fun WrapSupport(goBack: () -> Unit) {
|
||||||
val supportViewModel by viewModels<SupportViewModel>()
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val walletViewModel by viewModels<WalletViewModel>()
|
val supportViewModel by activity.viewModels<SupportViewModel>()
|
||||||
|
|
||||||
|
val walletViewModel by activity.viewModels<WalletViewModel>()
|
||||||
|
|
||||||
val supportInfo = supportViewModel.supportInfo.collectAsStateWithLifecycle().value
|
val supportInfo = supportViewModel.supportInfo.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
|
||||||
|
|
||||||
|
BackHandler {
|
||||||
|
goBack()
|
||||||
|
}
|
||||||
|
|
||||||
WrapSupport(
|
WrapSupport(
|
||||||
activity = this,
|
|
||||||
goBack = goBack,
|
goBack = goBack,
|
||||||
supportInfo = supportInfo,
|
supportInfo = supportInfo,
|
||||||
topAppBarSubTitleState = walletState
|
topAppBarSubTitleState = walletState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapSupport(
|
internal fun WrapSupport(
|
||||||
activity: ComponentActivity,
|
|
||||||
goBack: () -> Unit,
|
goBack: () -> Unit,
|
||||||
supportInfo: SupportInfo?,
|
supportInfo: SupportInfo?,
|
||||||
topAppBarSubTitleState: TopAppBarSubTitleState,
|
topAppBarSubTitleState: TopAppBarSubTitleState,
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current
|
||||||
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package co.electriccoin.zcash.ui.screen.update
|
package co.electriccoin.zcash.ui.screen.update
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
|
@ -11,8 +10,8 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import co.electriccoin.zcash.ui.MainActivity
|
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
|
import co.electriccoin.zcash.ui.common.compose.LocalActivity
|
||||||
import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel
|
import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel
|
||||||
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
|
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
|
||||||
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
|
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
|
||||||
|
@ -23,12 +22,9 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MainActivity.WrapCheckForUpdate() {
|
internal fun WrapCheckForUpdate() {
|
||||||
WrapCheckForUpdate(this)
|
val activity = LocalActivity.current
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
|
||||||
// TODO [#403]: Manual testing of already implemented in-app update mechanisms
|
// TODO [#403]: Manual testing of already implemented in-app update mechanisms
|
||||||
// TODO [#403]: https://github.com/Electric-Coin-Company/zashi-android/issues/403
|
// TODO [#403]: https://github.com/Electric-Coin-Company/zashi-android/issues/403
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
@ -43,7 +39,7 @@ private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
||||||
|
|
||||||
updateInfo?.let {
|
updateInfo?.let {
|
||||||
if (it.appUpdateInfo != null && it.state == UpdateState.Prepared) {
|
if (it.appUpdateInfo != null && it.state == UpdateState.Prepared) {
|
||||||
WrapUpdate(activity, updateInfo)
|
WrapUpdate(updateInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +52,9 @@ private fun WrapCheckForUpdate(activity: ComponentActivity) {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WrapUpdate(
|
internal fun WrapUpdate(inputUpdateInfo: UpdateInfo) {
|
||||||
activity: ComponentActivity,
|
val activity = LocalActivity.current
|
||||||
inputUpdateInfo: UpdateInfo
|
|
||||||
) {
|
|
||||||
val viewModel by activity.viewModels<UpdateViewModel> {
|
val viewModel by activity.viewModels<UpdateViewModel> {
|
||||||
UpdateViewModel.UpdateViewModelFactory(
|
UpdateViewModel.UpdateViewModelFactory(
|
||||||
activity.application,
|
activity.application,
|
||||||
|
@ -78,10 +73,12 @@ internal fun WrapUpdate(
|
||||||
// just return as we are already in Home compose
|
// just return as we are already in Home compose
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateState.Failed -> {
|
UpdateState.Failed -> {
|
||||||
// we need to refresh AppUpdateInfo object, as it can be used only once
|
// we need to refresh AppUpdateInfo object, as it can be used only once
|
||||||
viewModel.checkForAppUpdate()
|
viewModel.checkForAppUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateState.Prepared, UpdateState.Running -> {
|
UpdateState.Prepared, UpdateState.Running -> {
|
||||||
// valid stages
|
// valid stages
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue