diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93a9be0a..c542b8c6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,10 +11,14 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2
- Zashi app now supports Spanish language
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
+### Changed
+- The Not enough space and In-app udpate screens have been redesigned
+
### Fixed
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- The application now correctly navigates to the homepage after deleting the current wallet and creating a new or
recovering an older one
+- The in-app update logic has been fixed and is now correctly requested with every app launch
## [1.2.1 (760)] - 2024-10-22
diff --git a/docs/whatsNew/WHATS_NEW_EN.md b/docs/whatsNew/WHATS_NEW_EN.md
index 74ced6e6..b857e449 100644
--- a/docs/whatsNew/WHATS_NEW_EN.md
+++ b/docs/whatsNew/WHATS_NEW_EN.md
@@ -14,10 +14,14 @@ directly impact users rather than highlighting other key architectural updates.*
- Zashi app now supports Spanish language
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
+### Changed
+- The Not enough space and In-app udpate screens have been redesigned
+
### Fixed
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- The application now correctly navigates to the homepage after deleting the current wallet and creating a new or
recovering an older one
+- The in-app update logic has been fixed and is now correctly requested with every app launch
## [1.2.1 (760)] - 2024-10-22
diff --git a/docs/whatsNew/WHATS_NEW_ES.md b/docs/whatsNew/WHATS_NEW_ES.md
index 0b5d296c..813f1bdb 100644
--- a/docs/whatsNew/WHATS_NEW_ES.md
+++ b/docs/whatsNew/WHATS_NEW_ES.md
@@ -18,3 +18,7 @@ directly impact users rather than highlighting other key architectural updates.*
- Address book toast now correctly shows on send screen when adding both new and known addresses to text field
- The application now correctly navigates to the homepage after deleting the current wallet and creating a new or
recovering an older one
+- The in-app update logic has been fixed and is now correctly requested with every app launch
+
+### Changed
+- The Not enough space and In-app udpate screens have been redesigned
diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarBackNavigation.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarBackNavigation.kt
deleted file mode 100644
index bf4909ab..00000000
--- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarBackNavigation.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package co.electriccoin.zcash.ui.design.component
-
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.width
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
-import co.electriccoin.zcash.ui.design.R
-import co.electriccoin.zcash.ui.design.util.orDark
-
-@Composable
-fun ZashiTopAppBarBackNavigation(
- backContentDescriptionText: String = stringResource(R.string.back_navigation_content_description),
- painter: Painter =
- painterResource(
- R.drawable.ic_zashi_navigation_back orDark R.drawable.ic_zashi_navigation_back_dark
- ),
- onBack: () -> Unit
-) {
- Row {
- Spacer(modifier = Modifier.width(16.dp))
- IconButton(onClick = onBack) {
- Icon(
- painter = painter,
- contentDescription = backContentDescriptionText,
- )
- }
- }
-}
diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarNavigation.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarNavigation.kt
new file mode 100644
index 00000000..fe340b89
--- /dev/null
+++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiTopAppBarNavigation.kt
@@ -0,0 +1,71 @@
+package co.electriccoin.zcash.ui.design.component
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import co.electriccoin.zcash.ui.design.R
+import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
+
+@Composable
+fun ZashiTopAppBarBackNavigation(
+ onBack: () -> Unit,
+ modifier: Modifier = Modifier
+) = ZashiTopAppBarNavigation(
+ modifier = modifier,
+ backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
+ drawableRes = R.drawable.ic_zashi_navigation_back,
+ onBack = onBack
+)
+
+@Composable
+fun ZashiTopAppBarCloseNavigation(
+ onBack: () -> Unit,
+ modifier: Modifier = Modifier
+) = ZashiTopAppBarNavigation(
+ modifier = modifier,
+ backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
+ drawableRes = R.drawable.ic_navigation_close,
+ onBack = onBack,
+ tint = ZashiColors.Text.textPrimary
+)
+
+@Composable
+fun ZashiTopAppBarHamburgerNavigation(onBack: () -> Unit) =
+ ZashiTopAppBarNavigation(
+ backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
+ drawableRes = R.drawable.ic_navigation_hamburger,
+ onBack = onBack,
+ tint = ZashiColors.Text.textPrimary
+ )
+
+@Composable
+private fun ZashiTopAppBarNavigation(
+ backContentDescriptionText: String,
+ @DrawableRes drawableRes: Int,
+ onBack: () -> Unit,
+ modifier: Modifier = Modifier,
+ tint: Color? = null,
+) {
+ Row(
+ modifier = modifier,
+ ) {
+ Spacer(modifier = Modifier.width(16.dp))
+ IconButton(onClick = onBack) {
+ Icon(
+ painter = painterResource(drawableRes),
+ contentDescription = backContentDescriptionText,
+ tint = tint ?: LocalContentColor.current
+ )
+ }
+ }
+}
diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiVerticalGradient.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiVerticalGradient.kt
new file mode 100644
index 00000000..feb0a2ef
--- /dev/null
+++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/ZashiVerticalGradient.kt
@@ -0,0 +1,20 @@
+package co.electriccoin.zcash.ui.design.component
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
+import co.electriccoin.zcash.ui.design.util.orDark
+
+@Composable
+fun zashiVerticalGradient(
+ startColor: Color = ZashiColors.Utility.WarningYellow.utilityOrange100,
+ endColor: Color = ZashiColors.Surfaces.bgPrimary
+) = Brush.verticalGradient(
+ START_STOP to startColor,
+ (END_STOP_LIGHT orDark END_STOP_DARK) to endColor,
+)
+
+private const val START_STOP = .0f
+private const val END_STOP_DARK = .35f
+private const val END_STOP_LIGHT = .4f
diff --git a/ui-design-lib/src/main/res/ui/common/drawable/ic_zashi_navigation_back_dark.xml b/ui-design-lib/src/main/res/ui/common/drawable-night/ic_zashi_navigation_back.xml
similarity index 100%
rename from ui-design-lib/src/main/res/ui/common/drawable/ic_zashi_navigation_back_dark.xml
rename to ui-design-lib/src/main/res/ui/common/drawable-night/ic_zashi_navigation_back.xml
diff --git a/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_close.xml b/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_close.xml
new file mode 100644
index 00000000..863f0a03
--- /dev/null
+++ b/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_close.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_hamburger.xml b/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_hamburger.xml
new file mode 100644
index 00000000..eba4dd6e
--- /dev/null
+++ b/ui-design-lib/src/main/res/ui/common/drawable/ic_navigation_hamburger.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/UpdateViewModelTest.kt b/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/UpdateViewModelTest.kt
index fdbc64a3..99009599 100644
--- a/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/UpdateViewModelTest.kt
+++ b/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/UpdateViewModelTest.kt
@@ -35,7 +35,7 @@ class UpdateViewModelTest : UiTestPrerequisites() {
@Before
fun setup() {
- checker = AppUpdateCheckerMock.new()
+ checker = AppUpdateCheckerMock()
initialUpdateInfo =
UpdateInfoFixture.new(
diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/settings/SettingsViewTestSetup.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/settings/SettingsViewTestSetup.kt
index e6c9d3d3..809275d8 100644
--- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/settings/SettingsViewTestSetup.kt
+++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/settings/SettingsViewTestSetup.kt
@@ -106,7 +106,6 @@ class SettingsViewTestSetup(
Settings(
state =
SettingsState(
- isLoading = false,
version = stringRes("app_version"),
debugMenu = settingsTroubleshootingState,
onBack = {
diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTest.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTest.kt
index b6833455..0ba4e3b6 100644
--- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTest.kt
+++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTest.kt
@@ -41,13 +41,13 @@ class UpdateViewAndroidTest : UiTestPrerequisites() {
)
newTestSetup(updateInfo)
- composeTestRule.onNodeWithText(getStringResource(R.string.update_header), ignoreCase = true).also {
+ composeTestRule.onNodeWithText(getStringResource(R.string.update_title_available), ignoreCase = true).also {
it.assertExists()
}
Espresso.pressBack()
- composeTestRule.onNodeWithText(getStringResource(R.string.update_header), ignoreCase = true).also {
+ composeTestRule.onNodeWithText(getStringResource(R.string.update_title_available), ignoreCase = true).also {
it.assertDoesNotExist()
}
}
@@ -64,13 +64,13 @@ class UpdateViewAndroidTest : UiTestPrerequisites() {
)
newTestSetup(updateInfo)
- composeTestRule.onNodeWithText(getStringResource(R.string.update_critical_header), ignoreCase = true).also {
+ composeTestRule.onNodeWithText(getStringResource(R.string.update_title_required), ignoreCase = true).also {
it.assertExists()
}
Espresso.pressBack()
- composeTestRule.onNodeWithText(getStringResource(R.string.update_critical_header), ignoreCase = true).also {
+ composeTestRule.onNodeWithText(getStringResource(R.string.update_title_required), ignoreCase = true).also {
it.assertExists()
}
}
diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTestSetup.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTestSetup.kt
index 7e3de608..caa37942 100644
--- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTestSetup.kt
+++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewAndroidTestSetup.kt
@@ -19,7 +19,7 @@ class UpdateViewAndroidTestSetup(
UpdateViewModel(
application = composeTestRule.activity.application,
updateInfo = updateInfo,
- appUpdateChecker = AppUpdateCheckerMock.new()
+ appUpdateChecker = AppUpdateCheckerMock()
)
@Composable
@@ -32,7 +32,8 @@ class UpdateViewAndroidTestSetup(
updateInfo = updateInfo,
checkForUpdate = viewModel::checkForAppUpdate,
remindLater = viewModel::remindLater,
- goForUpdate = {}
+ goForUpdate = {},
+ onSettings = {}
)
}
}
diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTest.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTest.kt
index f5904d57..7c7b07f1 100644
--- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTest.kt
+++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTest.kt
@@ -6,7 +6,6 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performScrollTo
import androidx.test.filters.MediumTest
import co.electriccoin.zcash.test.UiTestPrerequisites
import co.electriccoin.zcash.ui.R
@@ -17,6 +16,7 @@ import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
import co.electriccoin.zcash.ui.test.getStringResource
import org.junit.Assert.assertEquals
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@@ -38,14 +38,7 @@ class UpdateViewTest : UiTestPrerequisites() {
newTestSetup(updateInfo)
composeTestRule.onNodeWithText(
- text = getStringResource(R.string.update_critical_header),
- ignoreCase = true
- ).also {
- it.assertExists()
- }
-
- composeTestRule.onNodeWithText(
- text = getStringResource(R.string.update_later_disabled_button),
+ text = getStringResource(R.string.update_title_required),
ignoreCase = true
).also {
it.assertExists()
@@ -85,14 +78,7 @@ class UpdateViewTest : UiTestPrerequisites() {
newTestSetup(updateInfo)
composeTestRule.onNodeWithText(
- text = getStringResource(R.string.update_header),
- ignoreCase = true
- ).also {
- it.assertExists()
- }
-
- composeTestRule.onNodeWithText(
- text = getStringResource(R.string.update_later_enabled_button),
+ text = getStringResource(R.string.update_title_available),
ignoreCase = true
).also {
it.assertExists()
@@ -101,11 +87,11 @@ class UpdateViewTest : UiTestPrerequisites() {
@Test
@MediumTest
- fun later_btn_force_update_test() {
+ fun later_btn_update_test() {
val updateInfo =
UpdateInfoFixture.new(
- priority = AppUpdateChecker.Priority.HIGH,
- force = true,
+ priority = AppUpdateChecker.Priority.LOW,
+ force = false,
appUpdateInfo = null,
state = UpdateState.Prepared
)
@@ -115,7 +101,7 @@ class UpdateViewTest : UiTestPrerequisites() {
composeTestRule.clickLater()
- assertEquals(0, testSetup.getOnLaterCount())
+ assertEquals(1, testSetup.getOnLaterCount())
}
@Test
@@ -127,10 +113,6 @@ class UpdateViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnDownloadCount())
- composeTestRule.onNodeWithText(UpdateTag.PROGRESSBAR_DOWNLOADING).also {
- it.assertDoesNotExist()
- }
-
composeTestRule.clickDownload()
assertEquals(1, testSetup.getOnDownloadCount())
@@ -138,6 +120,7 @@ class UpdateViewTest : UiTestPrerequisites() {
@Test
@MediumTest
+ @Ignore("Disable the test for now -> we have no way to click a clickable span right now")
fun play_store_ref_test() {
val updateInfo = UpdateInfoFixture.new(appUpdateInfo = null)
@@ -146,9 +129,8 @@ class UpdateViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnReferenceCount())
composeTestRule.onRoot().assertExists()
- composeTestRule.onNodeWithText(getStringResource(R.string.update_link_text)).also {
+ composeTestRule.onNodeWithText(getStringResource(R.string.update_link_text), substring = true,).also {
it.assertExists()
- it.performScrollTo()
it.performClick()
}
diff --git a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTestSetup.kt b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTestSetup.kt
index e31cb4cc..f78ce668 100644
--- a/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTestSetup.kt
+++ b/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/view/UpdateViewTestSetup.kt
@@ -58,7 +58,8 @@ class UpdateViewTestSetup(
},
onReference = {
onReferenceCount.incrementAndGet()
- }
+ },
+ onSettings = {}
)
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/di/UseCaseModule.kt b/ui-lib/src/main/java/co/electriccoin/zcash/di/UseCaseModule.kt
index 33c998e4..dd55ab4b 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/di/UseCaseModule.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/di/UseCaseModule.kt
@@ -24,6 +24,7 @@ import co.electriccoin.zcash.ui.common.usecase.PersistEndpointUseCase
import co.electriccoin.zcash.ui.common.usecase.RefreshFastestServersUseCase
import co.electriccoin.zcash.ui.common.usecase.RescanBlockchainUseCase
import co.electriccoin.zcash.ui.common.usecase.SaveContactUseCase
+import co.electriccoin.zcash.ui.common.usecase.SensitiveSettingsVisibleUseCase
import co.electriccoin.zcash.ui.common.usecase.ShareImageUseCase
import co.electriccoin.zcash.ui.common.usecase.UpdateContactUseCase
import co.electriccoin.zcash.ui.common.usecase.ValidateContactAddressUseCase
@@ -69,4 +70,5 @@ val useCaseModule =
singleOf(::ObserveWalletStateUseCase)
singleOf(::IsCoinbaseAvailableUseCase)
singleOf(::GetSpendingKeyUseCase)
+ singleOf(::SensitiveSettingsVisibleUseCase)
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt b/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt
index 20efe5ac..18deb660 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/di/ViewModelModule.kt
@@ -26,6 +26,7 @@ import co.electriccoin.zcash.ui.screen.sendconfirmation.viewmodel.CreateTransact
import co.electriccoin.zcash.ui.screen.settings.viewmodel.ScreenBrightnessViewModel
import co.electriccoin.zcash.ui.screen.settings.viewmodel.SettingsViewModel
import co.electriccoin.zcash.ui.screen.support.viewmodel.SupportViewModel
+import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
import co.electriccoin.zcash.ui.screen.update.viewmodel.UpdateViewModel
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
import co.electriccoin.zcash.ui.screen.whatsnew.viewmodel.WhatsNewViewModel
@@ -50,7 +51,13 @@ val viewModelModule =
viewModelOf(::CreateTransactionsViewModel)
viewModelOf(::RestoreSuccessViewModel)
viewModelOf(::WhatsNewViewModel)
- viewModelOf(::UpdateViewModel)
+ viewModel { (updateInfo: UpdateInfo) ->
+ UpdateViewModel(
+ application = get(),
+ updateInfo = updateInfo,
+ appUpdateChecker = get(),
+ )
+ }
viewModelOf(::ChooseServerViewModel)
viewModel { (args: AddressBookArgs) ->
AddressBookViewModel(
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt
index 56e6fa24..8ea79ef0 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/Navigation.kt
@@ -510,7 +510,7 @@ private fun fillInHandleForPaymentRequest(
handle[PAYMENT_REQUEST_URI] = zip321
}
-private fun NavHostController.navigateJustOnce(
+fun NavHostController.navigateJustOnce(
route: String,
navOptionsBuilder: (NavOptionsBuilder.() -> Unit)? = null
) {
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SensitiveSettingsVisibleUseCase.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SensitiveSettingsVisibleUseCase.kt
new file mode 100644
index 00000000..7bcbaf9a
--- /dev/null
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/common/usecase/SensitiveSettingsVisibleUseCase.kt
@@ -0,0 +1,30 @@
+package co.electriccoin.zcash.ui.common.usecase
+
+import android.content.Context
+import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
+import co.electriccoin.zcash.ui.screen.update.AppUpdateChecker
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.WhileSubscribed
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+class SensitiveSettingsVisibleUseCase(
+ appUpdateChecker: AppUpdateChecker,
+ context: Context
+) {
+ private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
+
+ private val flow =
+ appUpdateChecker.newCheckForUpdateAvailabilityFlow(context)
+ .map { it.isForce.not() }
+ .stateIn(
+ scope = scope,
+ started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
+ initialValue = true
+ )
+
+ operator fun invoke() = flow
+}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AndroidAdvancedSettings.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AndroidAdvancedSettings.kt
index 2e6f8966..d2b257a2 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AndroidAdvancedSettings.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/AndroidAdvancedSettings.kt
@@ -14,7 +14,6 @@ import co.electriccoin.zcash.ui.screen.advancedsettings.viewmodel.AdvancedSettin
import kotlinx.collections.immutable.toImmutableList
import org.koin.androidx.compose.koinViewModel
-@Suppress("LongParameterList")
@Composable
internal fun WrapAdvancedSettings(
goDeleteWallet: () -> Unit,
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/viewmodel/AdvancedSettingsViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/viewmodel/AdvancedSettingsViewModel.kt
index 3ec91a88..f09c7b6d 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/viewmodel/AdvancedSettingsViewModel.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/advancedsettings/viewmodel/AdvancedSettingsViewModel.kt
@@ -2,55 +2,71 @@ package co.electriccoin.zcash.ui.screen.advancedsettings.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import cash.z.ecc.sdk.ANDROID_STATE_FLOW_TIMEOUT
import co.electriccoin.zcash.ui.NavigationTargets
import co.electriccoin.zcash.ui.R
+import co.electriccoin.zcash.ui.common.usecase.SensitiveSettingsVisibleUseCase
import co.electriccoin.zcash.ui.design.component.ButtonState
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.stringRes
import co.electriccoin.zcash.ui.screen.advancedsettings.model.AdvancedSettingsState
-import kotlinx.collections.immutable.persistentListOf
+import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.WhileSubscribed
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-class AdvancedSettingsViewModel : ViewModel() {
- val state =
- MutableStateFlow(
- AdvancedSettingsState(
- onBack = ::onBack,
- items =
- persistentListOf(
- ZashiSettingsListItemState(
- text = stringRes(R.string.advanced_settings_recovery),
- icon = R.drawable.ic_advanced_settings_recovery,
- onClick = {}
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.advanced_settings_export),
- icon = R.drawable.ic_advanced_settings_export,
- onClick = {}
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.advanced_settings_choose_server),
- icon =
- R.drawable.ic_advanced_settings_choose_server,
- onClick = ::onChooseServerClick
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.advanced_settings_currency_conversion),
- icon =
- R.drawable.ic_advanced_settings_currency_conversion,
- onClick = ::onCurrencyConversionClick
- )
- ),
- deleteButton =
- ButtonState(
- stringRes(R.string.advanced_settings_delete_button),
- onClick = {}
- )
+class AdvancedSettingsViewModel(
+ isSensitiveSettingsVisible: SensitiveSettingsVisibleUseCase
+) : ViewModel() {
+ val state: StateFlow =
+ isSensitiveSettingsVisible()
+ .map { isSensitiveSettingsVisible ->
+ createState(isSensitiveSettingsVisible)
+ }
+ .stateIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
+ initialValue = createState(isSensitiveSettingsVisible().value)
)
- ).asStateFlow()
+
+ private fun createState(isSensitiveSettingsVisible: Boolean) =
+ AdvancedSettingsState(
+ onBack = ::onBack,
+ items =
+ listOfNotNull(
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.advanced_settings_recovery),
+ icon = R.drawable.ic_advanced_settings_recovery,
+ onClick = {}
+ ),
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.advanced_settings_export),
+ icon = R.drawable.ic_advanced_settings_export,
+ onClick = {}
+ ),
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.advanced_settings_choose_server),
+ icon =
+ R.drawable.ic_advanced_settings_choose_server,
+ onClick = ::onChooseServerClick
+ ).takeIf { isSensitiveSettingsVisible },
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.advanced_settings_currency_conversion),
+ icon =
+ R.drawable.ic_advanced_settings_currency_conversion,
+ onClick = ::onCurrencyConversionClick
+ ).takeIf { isSensitiveSettingsVisible }
+ ).toImmutableList(),
+ deleteButton =
+ ButtonState(
+ stringRes(R.string.advanced_settings_delete_button),
+ onClick = {}
+ ),
+ )
val navigationCommand = MutableSharedFlow()
val backNavigationCommand = MutableSharedFlow()
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
index f4a172f7..0f52e9c7 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/AndroidSettings.kt
@@ -36,10 +36,8 @@ internal fun WrapSettings() {
settingsViewModel.onBack()
}
- state?.let {
- Settings(
- state = it,
- topAppBarSubTitleState = walletState,
- )
- }
+ Settings(
+ state = state,
+ topAppBarSubTitleState = walletState,
+ )
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/model/SettingsState.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/model/SettingsState.kt
index c7081734..f5549cf6 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/model/SettingsState.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/model/SettingsState.kt
@@ -6,7 +6,6 @@ import kotlinx.collections.immutable.ImmutableList
data class SettingsState(
val version: StringResource,
- val isLoading: Boolean,
val onBack: () -> Unit,
val debugMenu: SettingsTroubleshootingState?,
val items: ImmutableList,
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/view/SettingsView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/view/SettingsView.kt
index 5e89c68d..461a48f8 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/view/SettingsView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/view/SettingsView.kt
@@ -29,7 +29,6 @@ import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
-import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
import co.electriccoin.zcash.ui.design.component.ZashiHorizontalDivider
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItem
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
@@ -59,31 +58,27 @@ fun Settings(
)
}
) { paddingValues ->
- if (state.isLoading) {
- CircularScreenProgressIndicator()
- } else {
- Column(
- modifier =
- Modifier
- .fillMaxSize()
- .verticalScroll(rememberScrollState())
- .padding(
- top = paddingValues.calculateTopPadding(),
- bottom = paddingValues.calculateBottomPadding() + ZashiDimensions.Spacing.spacing3xl,
- start = 4.dp,
- end = 4.dp
- ),
- ) {
- state.items.forEachIndexed { index, item ->
- ZashiSettingsListItem(state = item)
- if (index != state.items.lastIndex) {
- ZashiHorizontalDivider()
- }
+ Column(
+ modifier =
+ Modifier
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState())
+ .padding(
+ top = paddingValues.calculateTopPadding(),
+ bottom = paddingValues.calculateBottomPadding() + ZashiDimensions.Spacing.spacing3xl,
+ start = 4.dp,
+ end = 4.dp
+ ),
+ ) {
+ state.items.forEachIndexed { index, item ->
+ ZashiSettingsListItem(state = item)
+ if (index != state.items.lastIndex) {
+ ZashiHorizontalDivider()
}
- Spacer(modifier = Modifier.height(ZashiDimensions.Spacing.spacingXl))
- Spacer(modifier = Modifier.weight(1f))
- ZashiVersion(modifier = Modifier.align(CenterHorizontally), version = state.version)
}
+ Spacer(modifier = Modifier.height(ZashiDimensions.Spacing.spacingXl))
+ Spacer(modifier = Modifier.weight(1f))
+ ZashiVersion(modifier = Modifier.align(CenterHorizontally), version = state.version)
}
}
}
@@ -197,53 +192,6 @@ private fun PreviewSettings() {
Settings(
state =
SettingsState(
- isLoading = false,
- version = stringRes("Version 1.2"),
- debugMenu = null,
- onBack = {},
- items =
- persistentListOf(
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_address_book),
- icon = R.drawable.ic_settings_address_book,
- onClick = { },
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_integrations),
- icon = R.drawable.ic_settings_integrations,
- onClick = { },
- titleIcons = persistentListOf(R.drawable.ic_integrations_coinbase)
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_advanced_settings),
- icon = R.drawable.ic_advanced_settings,
- onClick = { },
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_about_us),
- icon = R.drawable.ic_settings_info,
- onClick = { },
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_feedback),
- icon = R.drawable.ic_settings_feedback,
- onClick = { },
- ),
- ),
- ),
- topAppBarSubTitleState = TopAppBarSubTitleState.None,
- )
- }
-}
-
-@PreviewScreens
-@Composable
-private fun PreviewSettingsLoading() {
- ZcashTheme {
- Settings(
- state =
- SettingsState(
- isLoading = true,
version = stringRes("Version 1.2"),
debugMenu = null,
onBack = {},
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/viewmodel/SettingsViewModel.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/viewmodel/SettingsViewModel.kt
index a5fcce54..e66b0c37 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/viewmodel/SettingsViewModel.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/settings/viewmodel/SettingsViewModel.kt
@@ -14,6 +14,7 @@ import co.electriccoin.zcash.ui.common.provider.GetVersionInfoProvider
import co.electriccoin.zcash.ui.common.usecase.IsFlexaAvailableUseCase
import co.electriccoin.zcash.ui.common.usecase.ObserveConfigurationUseCase
import co.electriccoin.zcash.ui.common.usecase.RescanBlockchainUseCase
+import co.electriccoin.zcash.ui.common.usecase.SensitiveSettingsVisibleUseCase
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
import co.electriccoin.zcash.ui.design.component.ZashiSettingsListItemState
import co.electriccoin.zcash.ui.design.util.stringRes
@@ -22,14 +23,12 @@ import co.electriccoin.zcash.ui.screen.addressbook.AddressBookArgs
import co.electriccoin.zcash.ui.screen.settings.model.SettingsState
import co.electriccoin.zcash.ui.screen.settings.model.SettingsTroubleshootingState
import co.electriccoin.zcash.ui.screen.settings.model.TroubleshootingItemState
-import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
@@ -38,6 +37,7 @@ import kotlinx.coroutines.launch
@Suppress("TooManyFunctions")
class SettingsViewModel(
observeConfiguration: ObserveConfigurationUseCase,
+ isSensitiveSettingsVisible: SensitiveSettingsVisibleUseCase,
private val standardPreferenceProvider: StandardPreferenceProvider,
private val getVersionInfo: GetVersionInfoProvider,
private val rescanBlockchain: RescanBlockchainUseCase,
@@ -50,15 +50,6 @@ class SettingsViewModel(
private val isKeepScreenOnWhileSyncingEnabled =
booleanStateFlow(StandardPreferenceKeys.IS_KEEP_SCREEN_ON_DURING_SYNC)
- private val isLoading =
- combine(
- isAnalyticsEnabled,
- isBackgroundSyncEnabled,
- isKeepScreenOnWhileSyncingEnabled
- ) { isAnalyticsEnabled, isBackgroundSync, isKeepScreenOnWhileSyncing ->
- isAnalyticsEnabled == null || isBackgroundSync == null || isKeepScreenOnWhileSyncing == null
- }.distinctUntilChanged()
-
@Suppress("ComplexCondition")
private val troubleshootingState =
combine(
@@ -98,48 +89,63 @@ class SettingsViewModel(
}
}
- val state: StateFlow =
- combine(isLoading, troubleshootingState) { isLoading, troubleshootingState ->
- SettingsState(
- isLoading = isLoading,
- debugMenu = troubleshootingState,
- onBack = ::onBack,
- items =
- persistentListOf(
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_address_book),
- icon = R.drawable.ic_settings_address_book,
- onClick = ::onAddressBookClick
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_integrations),
- icon = R.drawable.ic_settings_integrations,
- onClick = ::onIntegrationsClick,
- titleIcons =
- listOfNotNull(
- R.drawable.ic_integrations_coinbase,
- R.drawable.ic_integrations_flexa.takeIf { isFlexaAvailable() }
- ).toImmutableList()
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_advanced_settings),
- icon = R.drawable.ic_advanced_settings,
- onClick = ::onAdvancedSettingsClick
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_about_us),
- icon = R.drawable.ic_settings_info,
- onClick = ::onAboutUsClick
- ),
- ZashiSettingsListItemState(
- text = stringRes(R.string.settings_feedback),
- icon = R.drawable.ic_settings_feedback,
- onClick = ::onSendUsFeedbackClick
- ),
- ),
- version = stringRes(R.string.settings_version, versionInfo.versionName)
- )
- }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT), null)
+ val state: StateFlow =
+ combine(
+ troubleshootingState,
+ isSensitiveSettingsVisible()
+ ) { troubleshootingState, isSensitiveSettingsVisible ->
+ createState(troubleshootingState, isSensitiveSettingsVisible)
+ }.stateIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
+ initialValue =
+ createState(
+ troubleshootingState = null,
+ isSensitiveSettingsVisible = isSensitiveSettingsVisible().value
+ )
+ )
+
+ private fun createState(
+ troubleshootingState: SettingsTroubleshootingState?,
+ isSensitiveSettingsVisible: Boolean
+ ) = SettingsState(
+ debugMenu = troubleshootingState,
+ onBack = ::onBack,
+ items =
+ listOfNotNull(
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.settings_address_book),
+ icon = R.drawable.ic_settings_address_book,
+ onClick = ::onAddressBookClick
+ ),
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.settings_integrations),
+ icon = R.drawable.ic_settings_integrations,
+ onClick = ::onIntegrationsClick,
+ titleIcons =
+ listOfNotNull(
+ R.drawable.ic_integrations_coinbase,
+ R.drawable.ic_integrations_flexa.takeIf { isFlexaAvailable() }
+ ).toImmutableList()
+ ).takeIf { isSensitiveSettingsVisible },
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.settings_advanced_settings),
+ icon = R.drawable.ic_advanced_settings,
+ onClick = ::onAdvancedSettingsClick
+ ),
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.settings_about_us),
+ icon = R.drawable.ic_settings_info,
+ onClick = ::onAboutUsClick
+ ),
+ ZashiSettingsListItemState(
+ text = stringRes(R.string.settings_feedback),
+ icon = R.drawable.ic_settings_feedback,
+ onClick = ::onSendUsFeedbackClick
+ ),
+ ).toImmutableList(),
+ version = stringRes(R.string.settings_version, versionInfo.versionName)
+ )
val navigationCommand = MutableSharedFlow()
val backNavigationCommand = MutableSharedFlow()
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
index d67fcf82..7a8cd394 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AndroidUpdate.kt
@@ -10,9 +10,12 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.di.koinActivityViewModel
+import co.electriccoin.zcash.ui.NavigationTargets.SETTINGS
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.LocalActivity
+import co.electriccoin.zcash.ui.common.compose.LocalNavController
import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel
+import co.electriccoin.zcash.ui.navigateJustOnce
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.view.Update
@@ -29,12 +32,19 @@ internal fun WrapCheckForUpdate() {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
val checkUpdateViewModel = koinActivityViewModel()
+ // Check for an app update asynchronously. We create an effect that matches the activity
+ // lifecycle. If the wrapping compose recomposes, the check shouldn't run again.
+ LaunchedEffect(true) {
+ checkUpdateViewModel.checkForAppUpdate()
+ }
+
val activity = LocalActivity.current
val inputUpdateInfo = checkUpdateViewModel.updateInfo.collectAsStateWithLifecycle().value ?: return
val viewModel = koinActivityViewModel { parametersOf(inputUpdateInfo) }
val updateInfo = viewModel.updateInfo.collectAsStateWithLifecycle().value
+ val navController = LocalNavController.current
if (updateInfo.appUpdateInfo != null && updateInfo.state == UpdateState.Prepared) {
WrapUpdate(
@@ -46,15 +56,12 @@ internal fun WrapCheckForUpdate() {
activity = activity,
appUpdateInfo = updateInfo.appUpdateInfo
)
+ },
+ onSettings = {
+ navController.navigateJustOnce(SETTINGS)
}
)
}
-
- // Check for an app update asynchronously. We create an effect that matches the activity
- // lifecycle. If the wrapping compose recomposes, the check shouldn't run again.
- LaunchedEffect(true) {
- checkUpdateViewModel.checkForAppUpdate()
- }
}
@VisibleForTesting
@@ -64,6 +71,7 @@ internal fun WrapUpdate(
checkForUpdate: () -> Unit,
remindLater: () -> Unit,
goForUpdate: () -> Unit,
+ onSettings: () -> Unit
) {
val activity = LocalActivity.current
@@ -111,7 +119,8 @@ internal fun WrapUpdate(
snackbarHostState,
scope
)
- }
+ },
+ onSettings = onSettings
)
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt
index 9ebaa421..1ffc84cc 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt
@@ -19,12 +19,10 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flow
import kotlin.time.Duration.Companion.milliseconds
-class AppUpdateCheckerMock private constructor() : AppUpdateChecker {
+class AppUpdateCheckerMock : AppUpdateChecker {
companion object {
private const val DEFAULT_STALENESS_DAYS = 3
- fun new() = AppUpdateCheckerMock()
-
// Used mostly for tests
val resultUpdateInfo =
UpdateInfoFixture.new(
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/UpdateTag.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/UpdateTag.kt
index 1b2d1def..802682b0 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/UpdateTag.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/UpdateTag.kt
@@ -6,5 +6,4 @@ package co.electriccoin.zcash.ui.screen.update
object UpdateTag {
const val BTN_LATER = "btn_later"
const val BTN_DOWNLOAD = "btn_download"
- const val PROGRESSBAR_DOWNLOADING = "progressbar_downloading"
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt
index 4387f753..ff28916e 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/view/UpdateView.kt
@@ -2,327 +2,197 @@ package co.electriccoin.zcash.ui.screen.update.view
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.DividerDefaults
-import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.ColorFilter
-import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.text.LinkAnnotation
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.text.withLink
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
-import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
-import co.electriccoin.zcash.ui.design.component.Body
-import co.electriccoin.zcash.ui.design.component.Header
-import co.electriccoin.zcash.ui.design.component.Reference
-import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.ZashiButton
+import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
+import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarCloseNavigation
+import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarHamburgerNavigation
+import co.electriccoin.zcash.ui.design.component.zashiVerticalGradient
+import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
-import co.electriccoin.zcash.ui.design.theme.dimensions.ZashiDimensions
+import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
+import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
import co.electriccoin.zcash.ui.design.util.scaffoldPadding
import co.electriccoin.zcash.ui.fixture.UpdateInfoFixture
-import co.electriccoin.zcash.ui.screen.update.UpdateTag
+import co.electriccoin.zcash.ui.screen.update.UpdateTag.BTN_DOWNLOAD
+import co.electriccoin.zcash.ui.screen.update.UpdateTag.BTN_LATER
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
-@Preview
-@Composable
-private fun UpdatePreview() {
- ZcashTheme(forceDarkMode = false) {
- Update(
- snackbarHostState = SnackbarHostState(),
- UpdateInfoFixture.new(appUpdateInfo = null),
- onDownload = {},
- onLater = {},
- onReference = {}
- )
- }
-}
-
-@Preview
-@Composable
-private fun UpdateRequiredPreview() {
- ZcashTheme(forceDarkMode = false) {
- Update(
- snackbarHostState = SnackbarHostState(),
- UpdateInfoFixture.new(force = true),
- onDownload = {},
- onLater = {},
- onReference = {}
- )
- }
-}
-
-@Preview
-@Composable
-private fun UpdateAvailableDarkPreview() {
- ZcashTheme(forceDarkMode = true) {
- Update(
- snackbarHostState = SnackbarHostState(),
- UpdateInfoFixture.new(appUpdateInfo = null),
- onDownload = {},
- onLater = {},
- onReference = {}
- )
- }
-}
-
-@Preview
-@Composable
-private fun UpdateRequiredDarkPreview() {
- ZcashTheme(forceDarkMode = true) {
- Update(
- snackbarHostState = SnackbarHostState(),
- UpdateInfoFixture.new(force = true),
- onDownload = {},
- onLater = {},
- onReference = {}
- )
- }
-}
-
@Composable
fun Update(
snackbarHostState: SnackbarHostState,
updateInfo: UpdateInfo,
onDownload: (state: UpdateState) -> Unit,
onLater: () -> Unit,
- onReference: () -> Unit
+ onReference: () -> Unit,
+ onSettings: () -> Unit
) {
- BlankBgScaffold(
- topBar = {
- UpdateTopAppBar(updateInfo = updateInfo)
- },
- snackbarHost = {
- SnackbarHost(snackbarHostState)
- },
- bottomBar = {
- UpdateBottomAppBar(
- updateInfo,
- onDownload,
- onLater,
- modifier = Modifier.fillMaxWidth()
- )
- }
- ) { paddingValues ->
- UpdateContent(
- onReference = onReference,
- updateInfo = updateInfo,
- modifier =
- Modifier
- .fillMaxWidth()
- .scaffoldPadding(paddingValues)
- )
- }
- UpdateOverlayRunning(updateInfo)
-}
-
-@Suppress("MagicNumber")
-@Composable
-fun UpdateOverlayRunning(updateInfo: UpdateInfo) {
- if (updateInfo.state == UpdateState.Running) {
- Column(
- Modifier
- .background(ZcashTheme.colors.overlay.copy(0.65f))
- .fillMaxSize()
- .clickable(
- interactionSource = remember { MutableInteractionSource() },
- indication = null // Set indication to null to disable ripple effect
- ) {}
- .testTag(UpdateTag.PROGRESSBAR_DOWNLOADING),
- horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = Arrangement.Center
- ) {
- CircularProgressIndicator(color = ZcashTheme.colors.overlayProgressBar)
- }
- }
-}
-
-@Composable
-private fun UpdateTopAppBar(updateInfo: UpdateInfo) {
- SmallTopAppBar(
- titleText =
- stringResource(
- updateInfo.isForce.let { force ->
- if (force) {
- R.string.update_critical_header
+ Box(
+ modifier =
+ Modifier.background(
+ zashiVerticalGradient(
+ if (updateInfo.isForce) {
+ ZashiColors.Utility.WarningYellow.utilityOrange100
} else {
- R.string.update_header
+ ZashiColors.Utility.Purple.utilityPurple100
}
- }
- ),
- )
-}
-
-@Composable
-@Suppress("LongMethod")
-private fun UpdateBottomAppBar(
- updateInfo: UpdateInfo,
- onDownload: (state: UpdateState) -> Unit,
- onLater: () -> Unit,
- modifier: Modifier = Modifier
-) {
- Column(
- modifier = modifier,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- HorizontalDivider(
- thickness = DividerDefaults.Thickness,
- color = ZcashTheme.colors.primaryDividerColor
- )
-
- Column(
- modifier =
- Modifier
- .padding(
- top = ZashiDimensions.Spacing.spacingLg,
- bottom = ZashiDimensions.Spacing.spacing3xl,
- start = ZashiDimensions.Spacing.spacing3xl,
- end = ZashiDimensions.Spacing.spacing3xl
- ),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- ZashiButton(
- onClick = { onDownload(UpdateState.Running) },
- text = stringResource(R.string.update_download_button),
- modifier =
- Modifier
- .testTag(UpdateTag.BTN_DOWNLOAD)
- .fillMaxWidth(),
- enabled = updateInfo.state != UpdateState.Running,
- )
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
-
- if (updateInfo.isForce) {
- Text(
- text = stringResource(R.string.update_later_disabled_button),
- textAlign = TextAlign.Center,
- style = ZcashTheme.typography.primary.bodyLarge,
- fontWeight = FontWeight.SemiBold,
- color = ZcashTheme.colors.textPrimary,
- modifier =
- Modifier
- .padding(all = ZcashTheme.dimens.spacingDefault)
- .testTag(UpdateTag.BTN_LATER)
)
- } else {
- Reference(
- text = stringResource(R.string.update_later_enabled_button),
- onClick = {
- if (updateInfo.state != UpdateState.Running) {
- onLater()
- } else {
- // Keep current state
+ )
+ ) {
+ Scaffold(
+ topBar = {
+ ZashiSmallTopAppBar(
+ title = null,
+ subtitle = null,
+ colors = ZcashTheme.colors.topAppBarColors.copyColors(containerColor = Color.Transparent),
+ navigationAction = {
+ if (updateInfo.isForce.not()) {
+ ZashiTopAppBarCloseNavigation(modifier = Modifier.testTag(BTN_LATER), onBack = onLater)
}
},
+ hamburgerMenuActions = {
+ if (updateInfo.isForce) {
+ ZashiTopAppBarHamburgerNavigation(onSettings)
+ }
+ }
+ )
+ },
+ snackbarHost = {
+ SnackbarHost(snackbarHostState)
+ },
+ containerColor = Color.Transparent
+ ) {
+ Column(modifier = Modifier.scaffoldPadding(it)) {
+ @Suppress("MagicNumber")
+ Spacer(Modifier.weight(.75f))
+ Image(
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ painter =
+ painterResource(
+ if (updateInfo.isForce) {
+ R.drawable.ic_update_required
+ } else {
+ R.drawable.ic_update
+ }
+ ),
+ contentDescription = ""
+ )
+ Spacer(Modifier.height(24.dp))
+ Text(
+ modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
- modifier =
- Modifier
- .padding(all = ZcashTheme.dimens.spacingDefault)
- .testTag(UpdateTag.BTN_LATER)
+ text =
+ if (updateInfo.isForce) {
+ stringResource(id = R.string.update_title_required)
+ } else {
+ stringResource(id = R.string.update_title_available)
+ },
+ style = ZashiTypography.header6,
+ fontWeight = FontWeight.SemiBold,
+ color = ZashiColors.Text.textPrimary
+ )
+ Spacer(Modifier.height(12.dp))
+
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ text =
+ buildAnnotatedString {
+ append(
+ if (updateInfo.isForce) {
+ stringResource(id = R.string.update_description_required)
+ } else {
+ stringResource(id = R.string.update_description_available)
+ }
+ )
+ appendLine()
+ appendLine()
+
+ withStyle(
+ style =
+ SpanStyle(
+ textDecoration = TextDecoration.Underline
+ )
+ ) {
+ withLink(
+ LinkAnnotation.Clickable(CLICKABLE_TAG) {
+ if (updateInfo.state != UpdateState.Running) {
+ onReference()
+ }
+ }
+ ) {
+ append(stringResource(R.string.update_link_text))
+ }
+ }
+ },
+ style = ZashiTypography.textSm,
+ textAlign = TextAlign.Center,
+ color = ZashiColors.Text.textPrimary,
+ )
+ Spacer(Modifier.weight(1f))
+ ZashiButton(
+ modifier = Modifier.fillMaxWidth().testTag(BTN_DOWNLOAD),
+ text = stringResource(R.string.update_download_button),
+ onClick = { onDownload(UpdateState.Running) },
+ enabled = updateInfo.state != UpdateState.Running,
+ isLoading = updateInfo.state == UpdateState.Running
)
}
}
}
}
+@PreviewScreens
@Composable
-@Suppress("LongMethod")
-private fun UpdateContent(
- onReference: () -> Unit,
- updateInfo: UpdateInfo,
- modifier: Modifier = Modifier,
-) {
- val appName = stringResource(id = R.string.app_name)
-
- Column(
- modifier =
- modifier.then(
- Modifier
- .fillMaxHeight()
- .verticalScroll(
- rememberScrollState()
- )
- ),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Image(
- imageVector =
- if (updateInfo.isForce) {
- ImageVector.vectorResource(R.drawable.ic_zashi_logo_sign_warn)
- } else {
- ImageVector.vectorResource(R.drawable.ic_zashi_logo_update_available)
- },
- colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor),
- contentDescription = null
+private fun UpdatePreview() =
+ ZcashTheme {
+ Update(
+ snackbarHostState = SnackbarHostState(),
+ updateInfo = UpdateInfoFixture.new(appUpdateInfo = null),
+ onDownload = {},
+ onLater = {},
+ onReference = {},
+ onSettings = {}
)
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig))
-
- Header(
- text =
- if (updateInfo.isForce) {
- stringResource(id = R.string.update_title_required)
- } else {
- stringResource(id = R.string.update_title_available, appName)
- },
- textAlign = TextAlign.Center
- )
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
-
- Body(
- text =
- if (updateInfo.isForce) {
- stringResource(id = R.string.update_description_required, appName)
- } else {
- stringResource(id = R.string.update_description_available, appName)
- },
- textAlign = TextAlign.Center,
- color = ZcashTheme.colors.textDescriptionDark
- )
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
-
- Reference(
- text = stringResource(id = R.string.update_link_text),
- onClick = {
- if (updateInfo.state != UpdateState.Running) {
- onReference()
- } else {
- // Keep current state
- }
- },
- fontWeight = FontWeight.Normal,
- textStyle = ZcashTheme.typography.primary.bodyMedium,
- textAlign = TextAlign.Center,
- color = ZcashTheme.colors.textDescriptionDark,
- modifier = Modifier.padding(all = ZcashTheme.dimens.spacingDefault)
- )
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
}
-}
+
+@PreviewScreens
+@Composable
+private fun UpdateRequiredPreview() =
+ ZcashTheme {
+ Update(
+ snackbarHostState = SnackbarHostState(),
+ updateInfo = UpdateInfoFixture.new(force = true),
+ onDownload = {},
+ onLater = {},
+ onReference = {},
+ onSettings = {}
+ )
+ }
+
+private const val CLICKABLE_TAG = "clickable"
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
index b9f755e1..378c4296 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/AndroidNotEnoughSpace.kt
@@ -12,8 +12,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.electriccoin.zcash.di.koinActivityViewModel
import co.electriccoin.zcash.ui.MainActivity
import co.electriccoin.zcash.ui.R
-import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
-import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.screen.warning.view.NotEnoughSpaceView
import co.electriccoin.zcash.ui.screen.warning.viewmodel.StorageCheckViewModel
import co.electriccoin.zcash.ui.util.SettingsUtil
@@ -24,12 +22,8 @@ fun MainActivity.WrapNotEnoughSpace(
goPrevious: () -> Unit,
goSettings: () -> Unit
) {
- val walletViewModel = koinActivityViewModel()
-
val storageCheckViewModel = koinActivityViewModel()
- val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
-
val isEnoughFreeSpace = storageCheckViewModel.isEnoughSpace.collectAsStateWithLifecycle().value
if (isEnoughFreeSpace == true) {
goPrevious()
@@ -46,7 +40,6 @@ fun MainActivity.WrapNotEnoughSpace(
goSettings = goSettings,
spaceAvailableMegabytes = spaceAvailableMegabytes.value ?: 0,
requiredStorageSpaceGigabytes = requiredStorageSpaceGigabytes,
- walletState = walletState,
)
}
@@ -55,7 +48,6 @@ private fun WrapNotEnoughFreeSpace(
goSettings: () -> Unit,
requiredStorageSpaceGigabytes: Int,
spaceAvailableMegabytes: Int,
- walletState: TopAppBarSubTitleState,
) {
val context = LocalContext.current
@@ -81,6 +73,5 @@ private fun WrapNotEnoughFreeSpace(
snackbarHostState = snackbarHostState,
storageSpaceRequiredGigabytes = requiredStorageSpaceGigabytes,
spaceAvailableMegabytes = spaceAvailableMegabytes,
- topAppBarSubTitleState = walletState,
)
}
diff --git a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt
index 26ca70ed..36513f93 100644
--- a/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt
+++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/warning/view/NotEnoughSpaceView.kt
@@ -1,189 +1,141 @@
package co.electriccoin.zcash.ui.screen.warning.view
import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.IconButton
+import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.ColorFilter
-import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.dp
import co.electriccoin.zcash.ui.R
-import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
-import co.electriccoin.zcash.ui.common.test.CommonTag
-import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
-import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
-import co.electriccoin.zcash.ui.design.component.Body
-import co.electriccoin.zcash.ui.design.component.Header
-import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.ZashiButton
+import co.electriccoin.zcash.ui.design.component.ZashiSmallTopAppBar
+import co.electriccoin.zcash.ui.design.component.ZashiTopAppBarHamburgerNavigation
+import co.electriccoin.zcash.ui.design.component.zashiVerticalGradient
+import co.electriccoin.zcash.ui.design.newcomponent.PreviewScreens
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
+import co.electriccoin.zcash.ui.design.theme.colors.ZashiColors
+import co.electriccoin.zcash.ui.design.theme.typography.ZashiTypography
import co.electriccoin.zcash.ui.design.util.scaffoldPadding
-@Preview
@Composable
-private fun NotEnoughSpacePreview() {
- ZcashTheme(forceDarkMode = false) {
- NotEnoughSpaceView(
- onSettings = {},
- onSystemSettings = {},
- snackbarHostState = SnackbarHostState(),
- spaceAvailableMegabytes = 300,
- storageSpaceRequiredGigabytes = 1,
- topAppBarSubTitleState = TopAppBarSubTitleState.None,
- )
- }
-}
-
-@Preview
-@Composable
-private fun NotEnoughSpaceDarkPreview() {
- ZcashTheme(forceDarkMode = true) {
- NotEnoughSpaceView(
- onSettings = {},
- onSystemSettings = {},
- snackbarHostState = SnackbarHostState(),
- spaceAvailableMegabytes = 300,
- storageSpaceRequiredGigabytes = 1,
- topAppBarSubTitleState = TopAppBarSubTitleState.None,
- )
- }
-}
-
-@Composable
-@Suppress("LongParameterList")
fun NotEnoughSpaceView(
onSettings: () -> Unit,
onSystemSettings: () -> Unit,
spaceAvailableMegabytes: Int,
storageSpaceRequiredGigabytes: Int,
- topAppBarSubTitleState: TopAppBarSubTitleState,
snackbarHostState: SnackbarHostState,
) {
- BlankBgScaffold(
- topBar = {
- NotEnoughSpaceTopAppBar(
- onSettings = onSettings,
- subTitleState = topAppBarSubTitleState,
+ Box(
+ modifier =
+ Modifier.background(
+ zashiVerticalGradient(ZashiColors.Utility.ErrorRed.utilityError100)
)
- },
- snackbarHost = { SnackbarHost(snackbarHostState) },
- ) { paddingValues ->
- NotEnoughSpaceMainContent(
- onSystemSettings = onSystemSettings,
- spaceRequiredToContinueMegabytes = spaceAvailableMegabytes,
- storageSpaceRequiredGigabytes = storageSpaceRequiredGigabytes,
- modifier =
- Modifier
- .scaffoldPadding(paddingValues)
- )
- }
-}
-
-@Composable
-private fun NotEnoughSpaceTopAppBar(
- onSettings: () -> Unit,
- subTitleState: TopAppBarSubTitleState
-) {
- SmallTopAppBar(
- subTitle =
- when (subTitleState) {
- TopAppBarSubTitleState.Disconnected -> stringResource(id = R.string.disconnected_label)
- TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
- TopAppBarSubTitleState.None -> null
+ ) {
+ Scaffold(
+ topBar = {
+ ZashiSmallTopAppBar(
+ colors = ZcashTheme.colors.topAppBarColors.copyColors(containerColor = Color.Transparent),
+ title = null,
+ subtitle = null,
+ hamburgerMenuActions = {
+ ZashiTopAppBarHamburgerNavigation(onSettings)
+ }
+ )
},
- titleText = stringResource(id = R.string.not_enough_space_title).uppercase(),
- hamburgerMenuActions = {
- IconButton(
- onClick = onSettings,
- modifier = Modifier.testTag(CommonTag.SETTINGS_TOP_BAR_BUTTON)
- ) {
+ snackbarHost = {
+ SnackbarHost(snackbarHostState)
+ },
+ containerColor = Color.Transparent
+ ) {
+ Column(modifier = Modifier.scaffoldPadding(it)) {
+ @Suppress("MagicNumber")
+ Spacer(Modifier.weight(.75f))
Image(
- painter = painterResource(id = co.electriccoin.zcash.ui.design.R.drawable.ic_hamburger_menu),
- contentDescription = stringResource(id = R.string.settings_menu_content_description)
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ painter = painterResource(R.drawable.ic_not_enough_space),
+ contentDescription = ""
+ )
+ Spacer(Modifier.height(24.dp))
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ textAlign = TextAlign.Center,
+ text = stringResource(id = R.string.not_enough_space_title),
+ style = ZashiTypography.header6,
+ fontWeight = FontWeight.SemiBold,
+ color = ZashiColors.Text.textPrimary
+ )
+ Spacer(Modifier.height(12.dp))
+
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ text =
+ buildAnnotatedString {
+ append(
+ stringResource(
+ R.string.not_enough_space_description_1,
+ storageSpaceRequiredGigabytes
+ ) + " "
+ )
+ withStyle(
+ SpanStyle(
+ fontWeight = FontWeight.Bold
+ )
+ ) {
+ append(
+ stringResource(R.string.not_enough_space_description_2, spaceAvailableMegabytes)
+ )
+ }
+ append(
+ stringResource(
+ R.string.not_enough_space_description_3,
+ storageSpaceRequiredGigabytes *
+ GB_TO_MEGABYTES - spaceAvailableMegabytes
+ )
+ )
+ },
+ style = ZashiTypography.textSm,
+ textAlign = TextAlign.Center,
+ color = ZashiColors.Text.textPrimary,
+ )
+ Spacer(Modifier.weight(1f))
+ ZashiButton(
+ modifier = Modifier.fillMaxWidth(),
+ text = stringResource(R.string.not_enough_space_system_settings_btn),
+ onClick = onSystemSettings,
)
}
}
- )
-}
-
-@Composable
-private fun NotEnoughSpaceMainContent(
- onSystemSettings: () -> Unit,
- spaceRequiredToContinueMegabytes: Int,
- storageSpaceRequiredGigabytes: Int,
- modifier: Modifier = Modifier
-) {
- Column(
- modifier =
- modifier.then(
- Modifier
- .fillMaxHeight()
- .verticalScroll(
- rememberScrollState()
- )
- ),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig))
-
- Image(
- painter = painterResource(id = R.drawable.ic_zashi_logo_sign_warn),
- colorFilter = ColorFilter.tint(color = ZcashTheme.colors.secondaryColor),
- contentDescription = null,
- )
-
- Spacer(Modifier.height(ZcashTheme.dimens.spacingBig))
-
- Header(
- text =
- stringResource(
- id = R.string.not_enough_space_description_1,
- stringResource(id = R.string.app_name),
- storageSpaceRequiredGigabytes,
- spaceRequiredToContinueMegabytes
- ),
- textAlign = TextAlign.Center
- )
-
- Spacer(Modifier.height(ZcashTheme.dimens.spacingLarge))
-
- Body(
- text =
- stringResource(
- id = R.string.not_enough_space_description_2,
- stringResource(id = R.string.app_name)
- ),
- textAlign = TextAlign.Center
- )
-
- Spacer(
- modifier =
- Modifier
- .fillMaxHeight()
- .weight(MINIMAL_WEIGHT)
- )
-
- Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
-
- ZashiButton(
- modifier = Modifier.fillMaxWidth(),
- onClick = onSystemSettings,
- text = stringResource(R.string.not_enough_space_system_settings_btn),
- )
-
- Spacer(Modifier.height(ZcashTheme.dimens.spacingHuge))
}
}
+
+@PreviewScreens
+@Composable
+private fun NotEnoughSpacePreview() =
+ ZcashTheme {
+ NotEnoughSpaceView(
+ onSettings = {},
+ onSystemSettings = {},
+ snackbarHostState = SnackbarHostState(),
+ spaceAvailableMegabytes = 300,
+ storageSpaceRequiredGigabytes = 1,
+ )
+ }
+
+private const val GB_TO_MEGABYTES = 1024
diff --git a/ui-lib/src/main/res/ui/update/drawable-night/ic_update.xml b/ui-lib/src/main/res/ui/update/drawable-night/ic_update.xml
new file mode 100644
index 00000000..04bbf39b
--- /dev/null
+++ b/ui-lib/src/main/res/ui/update/drawable-night/ic_update.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/update/drawable-night/ic_update_required.xml b/ui-lib/src/main/res/ui/update/drawable-night/ic_update_required.xml
new file mode 100644
index 00000000..c1048a05
--- /dev/null
+++ b/ui-lib/src/main/res/ui/update/drawable-night/ic_update_required.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/update/drawable/ic_update.xml b/ui-lib/src/main/res/ui/update/drawable/ic_update.xml
new file mode 100644
index 00000000..ef61e89e
--- /dev/null
+++ b/ui-lib/src/main/res/ui/update/drawable/ic_update.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/update/drawable/ic_update_required.xml b/ui-lib/src/main/res/ui/update/drawable/ic_update_required.xml
new file mode 100644
index 00000000..97e8e32c
--- /dev/null
+++ b/ui-lib/src/main/res/ui/update/drawable/ic_update_required.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/update/values-es/strings.xml b/ui-lib/src/main/res/ui/update/values-es/strings.xml
index e8dcb27e..dcac791f 100644
--- a/ui-lib/src/main/res/ui/update/values-es/strings.xml
+++ b/ui-lib/src/main/res/ui/update/values-es/strings.xml
@@ -1,17 +1,13 @@
- Actualización disponible
- Actualización requerida
- %1$s aquí.
+ Zashi aquí.
No eres tú, soy yo.
- Hay una actualización requerida para %1$s que realiza importantes mejoras en el rendimiento y/o la seguridad.
+ Hay una actualización requerida para Zashi que realiza importantes mejoras en el rendimiento y/o la seguridad.
- Hay una nueva versión de %1$s que realiza actualizaciones menores para mejorar el rendimiento y/o la seguridad.\n\nPor favor, toma un momento para actualizar a la última versión.
+ Hay una nueva versión de Zashi que realiza actualizaciones menores para mejorar el rendimiento y/o la seguridad.\n\nPor favor, toma un momento para actualizar a la última versión.
Obtén más información sobre esta actualización aquí.
Actualizar
- Recordarme más tarde
- (requerido)
diff --git a/ui-lib/src/main/res/ui/update/values/strings.xml b/ui-lib/src/main/res/ui/update/values/strings.xml
index c1c76fbb..a576d9ac 100644
--- a/ui-lib/src/main/res/ui/update/values/strings.xml
+++ b/ui-lib/src/main/res/ui/update/values/strings.xml
@@ -1,19 +1,14 @@
- Update available
- Update required
- %1$s here.
- It\'s not you, it\'s me.
+ Zashi here.
+ It\'s not you, it\'s us.
- There is a required update for %1$s that makes major
- improvements to performance and/or security.
+ There is a required update\nfor Zashi that makes major improvements to\nperformance and/or security.
- There is a new version of %1$s that makes minor updates to
+ There is a new version of Zashi that makes minor updates to
improve performance and/or security.\n\nPlease take a moment to update to the latest version.
Learn more about this update here.
Update
- Remind me later
- (required)
diff --git a/ui-lib/src/main/res/ui/warning/drawable-night/ic_not_enough_space.xml b/ui-lib/src/main/res/ui/warning/drawable-night/ic_not_enough_space.xml
new file mode 100644
index 00000000..6864035e
--- /dev/null
+++ b/ui-lib/src/main/res/ui/warning/drawable-night/ic_not_enough_space.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/warning/drawable/ic_not_enough_space.xml b/ui-lib/src/main/res/ui/warning/drawable/ic_not_enough_space.xml
new file mode 100644
index 00000000..683db862
--- /dev/null
+++ b/ui-lib/src/main/res/ui/warning/drawable/ic_not_enough_space.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/ui-lib/src/main/res/ui/warning/values-es/strings.xml b/ui-lib/src/main/res/ui/warning/values-es/strings.xml
index 8b0d98d6..52779baa 100644
--- a/ui-lib/src/main/res/ui/warning/values-es/strings.xml
+++ b/ui-lib/src/main/res/ui/warning/values-es/strings.xml
@@ -1,15 +1,9 @@
No hay suficiente espacio libre
-
- %1$s requiere al menos
- %2$d GB de espacio para funcionar, pero solo hay
- %3$d MB disponibles.
-
-
- Ve a la configuración de tu dispositivo y libera más espacio si deseas usar la aplicación
- %1$s.
-
+ Zashi requires %1$d GB of space to synchronize the Zcash blockchain but there is only
+ %1$d MB available
+ . Syncing will stay paused until more space is available.\n\n~%1$d MB of additional space required to continue
Configuración del sistema
No se pudo iniciar la aplicación de Configuración.
diff --git a/ui-lib/src/main/res/ui/warning/values/strings.xml b/ui-lib/src/main/res/ui/warning/values/strings.xml
index be521ee2..ade8e6fa 100644
--- a/ui-lib/src/main/res/ui/warning/values/strings.xml
+++ b/ui-lib/src/main/res/ui/warning/values/strings.xml
@@ -1,15 +1,9 @@
Not enough free space
-
- %1$s requires at least
- %2$d GB of space to operate but there is only
- %3$d MB available.
-
-
- Go to your device settings and make more space available if you wish to use the
- %1$s app.
-
+ Zashi requires %1$d GB of space to synchronize the Zcash blockchain but there is only
+ %1$d MB available
+ . Syncing will stay paused until more space is available.\n\n~%1$d MB of additional space required to continue
System settings
Unable to launch Settings app.