From a97b71d9221d1aa390d5f5c59e1612823c03de7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Honza=20Rychnovsk=C3=BD?= Date: Tue, 7 May 2024 16:57:45 +0200 Subject: [PATCH] [#1338] Redesign Update-Available screen - Closes #1338 - Changelog update --- CHANGELOG.md | 1 + .../secant.publish-conventions.gradle.kts | 2 + gradle.properties | 2 +- .../zcash/ui/design/component/Text.kt | 3 +- .../zcash/ui/design/theme/ExtendedColors.kt | 1 + .../zcash/ui/design/theme/internal/Color.kt | 5 + .../ui/design/theme/internal/Typography.kt | 5 + .../update/viewmodel/UpdateViewModelTest.kt | 1 + .../ui/screen/update/view/UpdateViewTest.kt | 2 + .../ui/screen/update}/AppUpdateCheckerMock.kt | 15 +- .../zcash/ui/screen/update/view/UpdateView.kt | 190 ++++++++++++------ .../ic_zashi_logo_update_available.xml | 34 ++++ .../ic_zashi_logo_update_required.xml | 14 ++ .../src/main/res/ui/update/values/strings.xml | 19 +- 14 files changed, 218 insertions(+), 76 deletions(-) rename {ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel => ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update}/AppUpdateCheckerMock.kt (87%) create mode 100644 ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_available.xml create mode 100644 ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a98b62b..7b2578d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ directly impact users rather than highlighting other key architectural updates.* ### Changed - We've improved the visibility logic of the little loader that is part of the Balances widget +- The App-Update screen UI has been reworked to align with the latest design guidelines ### Removed - Concatenation of the messages on a multi-messages transaction has been removed and will be addressed using a new diff --git a/build-conventions-secant/src/main/kotlin/secant.publish-conventions.gradle.kts b/build-conventions-secant/src/main/kotlin/secant.publish-conventions.gradle.kts index 480e5880..4ccaf45e 100644 --- a/build-conventions-secant/src/main/kotlin/secant.publish-conventions.gradle.kts +++ b/build-conventions-secant/src/main/kotlin/secant.publish-conventions.gradle.kts @@ -245,6 +245,8 @@ abstract class PublishToGooglePlay @Inject constructor( track, Track().setReleases( listOf(TrackRelease() + // TODO [#1440]: Provide a way to inject in-app-update information + // TODO [#1440]: https://github.com/Electric-Coin-Company/zashi-android/issues/1440 .setName(versionName) .setVersionCodes(bundleVersionCodes) .setStatus(status) diff --git a/gradle.properties b/gradle.properties index b6012d10..93e2b629 100644 --- a/gradle.properties +++ b/gradle.properties @@ -161,7 +161,7 @@ ANDROIDX_CAMERA_VERSION=1.3.2 ANDROIDX_COMPOSE_COMPILER_VERSION=1.5.11 ANDROIDX_COMPOSE_MATERIAL3_VERSION=1.2.1 ANDROIDX_COMPOSE_MATERIAL_ICONS_VERSION=1.6.5 -ANDROIDX_COMPOSE_VERSION=1.6.5 +ANDROIDX_COMPOSE_VERSION=1.6.6 ANDROIDX_CONSTRAINTLAYOUT_VERSION=1.0.1 ANDROIDX_CORE_VERSION=1.12.0 ANDROIDX_ESPRESSO_VERSION=3.5.1 diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt index 473d77c0..00ae2c5b 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/component/Text.kt @@ -278,6 +278,7 @@ fun Reference( fontWeight: FontWeight = FontWeight.SemiBold, textAlign: TextAlign = TextAlign.Center, textStyle: TextStyle = ZcashTheme.typography.primary.bodyLarge, + color: Color = ZcashTheme.colors.reference, imageVector: ImageVector? = null, imageContentDescription: String? = null ) { @@ -303,7 +304,7 @@ fun Reference( style = textStyle.merge( TextStyle( - color = ZcashTheme.colors.reference, + color = color, textAlign = textAlign, textDecoration = TextDecoration.Underline, fontWeight = fontWeight diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt index 1bab8a37..222a8f82 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/ExtendedColors.kt @@ -29,6 +29,7 @@ data class ExtendedColors( val textFieldWarning: Color, val textFieldFrame: Color, val textDescription: Color, + val textDescriptionDark: Color, val textPending: Color, val layoutStroke: Color, val overlay: Color, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt index c1a09fa9..e86af5e6 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Color.kt @@ -32,6 +32,7 @@ internal object Dark { val textFieldWarning = Color(0xFFF40202) val textFieldHint = Color(0xFFB7B7B7) val textDescription = Color(0xFF777777) + val textDescriptionDark = Color(0xFF4D4D4D) val textProgress = Color(0xFF8B8A8A) val aboutTextColor = Color(0xFF4E4E4E) @@ -98,6 +99,7 @@ internal object Light { val textFieldHint = Color(0xFFB7B7B7) val textChipIndex = Color(0xFFEE8592) val textDescription = Color(0xFF777777) + val textDescriptionDark = Color(0xFF4D4D4D) val textProgress = Color(0xFF8B8A8A) val screenTitleColor = Color(0xFF040404) @@ -191,6 +193,7 @@ internal val DarkExtendedColorPalette = textFieldWarning = Dark.textFieldWarning, textFieldHint = Dark.textFieldHint, textDescription = Dark.textDescription, + textDescriptionDark = Dark.textDescriptionDark, textPending = Dark.textProgress, layoutStroke = Dark.layoutStroke, overlay = Dark.overlay, @@ -240,6 +243,7 @@ internal val LightExtendedColorPalette = textFieldWarning = Light.textFieldWarning, textFieldHint = Light.textFieldHint, textDescription = Light.textDescription, + textDescriptionDark = Light.textDescriptionDark, textPending = Light.textProgress, layoutStroke = Light.layoutStroke, overlay = Light.overlay, @@ -291,6 +295,7 @@ internal val LocalExtendedColors = textFieldWarning = Color.Unspecified, textFieldFrame = Color.Unspecified, textDescription = Color.Unspecified, + textDescriptionDark = Color.Unspecified, textPending = Color.Unspecified, layoutStroke = Color.Unspecified, overlay = Color.Unspecified, diff --git a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt index 513ab082..ee80a01a 100644 --- a/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt +++ b/ui-design-lib/src/main/java/co/electriccoin/zcash/ui/design/theme/internal/Typography.kt @@ -194,6 +194,7 @@ data class ExtendedTypography( val transactionItemStyles: TransactionItemTextStyles, val restoringTopAppBarStyle: TextStyle, val deleteWalletWarnStyle: TextStyle, + val updateTitleStyle: TextStyle, ) @Suppress("CompositionLocalAllowlist") @@ -377,6 +378,10 @@ val LocalExtendedTypography = deleteWalletWarnStyle = PrimaryTypography.bodyLarge.copy( fontWeight = FontWeight.Bold + ), + updateTitleStyle = + PrimaryTypography.titleLarge.copy( + fontWeight = FontWeight.Bold ) ) } 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 b0f6c248..fdbc64a3 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 @@ -7,6 +7,7 @@ import co.electriccoin.zcash.test.UiTestPrerequisites import co.electriccoin.zcash.ui.fixture.UpdateInfoFixture import co.electriccoin.zcash.ui.integration.test.common.IntegrationTestingActivity import co.electriccoin.zcash.ui.screen.update.AppUpdateChecker +import co.electriccoin.zcash.ui.screen.update.AppUpdateCheckerMock 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.viewmodel.UpdateViewModel 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 18eb84dc..f5904d57 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,6 +6,7 @@ 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 @@ -147,6 +148,7 @@ class UpdateViewTest : UiTestPrerequisites() { composeTestRule.onNodeWithText(getStringResource(R.string.update_link_text)).also { it.assertExists() + it.performScrollTo() it.performClick() } diff --git a/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/AppUpdateCheckerMock.kt b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt similarity index 87% rename from ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/AppUpdateCheckerMock.kt rename to ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt index 4731cf46..9b0477fd 100644 --- a/ui-integration-test/src/main/java/co/electriccoin/zcash/ui/integration/test/screen/update/viewmodel/AppUpdateCheckerMock.kt +++ b/ui-lib/src/main/java/co/electriccoin/zcash/ui/screen/update/AppUpdateCheckerMock.kt @@ -1,4 +1,4 @@ -package co.electriccoin.zcash.ui.integration.test.screen.update.viewmodel +package co.electriccoin.zcash.ui.screen.update import android.app.Activity import android.content.Context @@ -6,7 +6,6 @@ import androidx.activity.ComponentActivity import co.electriccoin.zcash.spackle.getPackageInfoCompat import co.electriccoin.zcash.spackle.versionCodeCompat import co.electriccoin.zcash.ui.fixture.UpdateInfoFixture -import co.electriccoin.zcash.ui.screen.update.AppUpdateChecker import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo import co.electriccoin.zcash.ui.screen.update.model.UpdateState import com.google.android.play.core.appupdate.AppUpdateInfo @@ -26,13 +25,13 @@ class AppUpdateCheckerMock private constructor() : AppUpdateChecker { fun new() = AppUpdateCheckerMock() - // used mostly for tests + // Used mostly for tests val resultUpdateInfo = UpdateInfoFixture.new( appUpdateInfo = null, state = UpdateState.Prepared, - priority = AppUpdateChecker.Priority.HIGH, - force = true + priority = AppUpdateChecker.Priority.LOW, + force = false ) } @@ -52,7 +51,7 @@ class AppUpdateCheckerMock private constructor() : AppUpdateChecker { val appUpdateInfoTask = fakeAppUpdateManager.appUpdateInfo - // to simulate a real-world situation + // To simulate a real-world situation delay(100.milliseconds) appUpdateInfoTask.addOnCompleteListener { infoTask -> @@ -83,8 +82,8 @@ class AppUpdateCheckerMock private constructor() : AppUpdateChecker { appUpdateInfo: AppUpdateInfo ): Flow = flow { - // to simulate a real-world situation - delay(100.milliseconds) + // To simulate a real-world situation + delay(2000.milliseconds) emit(Activity.RESULT_OK) } } 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 de113bf0..6f2fa3f7 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 @@ -7,22 +7,27 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues 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.layout.wrapContentHeight -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Update +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.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.design.component.Body @@ -30,7 +35,6 @@ import co.electriccoin.zcash.ui.design.component.GradientSurface import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.Reference import co.electriccoin.zcash.ui.design.component.SmallTopAppBar -import co.electriccoin.zcash.ui.design.component.TertiaryButton import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.fixture.UpdateInfoFixture import co.electriccoin.zcash.ui.screen.update.UpdateTag @@ -73,28 +77,21 @@ fun Update( updateInfo, onDownload, onLater, - modifier = - Modifier - .fillMaxWidth() - .padding( - top = ZcashTheme.dimens.spacingDefault, - bottom = ZcashTheme.dimens.spacingHuge, - start = ZcashTheme.dimens.screenHorizontalSpacingBig, - end = ZcashTheme.dimens.screenHorizontalSpacingBig - ) + modifier = Modifier.fillMaxWidth() ) } ) { paddingValues -> - UpdateContentNormal( - onReference, + UpdateContentContent( + onReference = onReference, + updateInfo = updateInfo, modifier = Modifier .fillMaxWidth() .padding( top = paddingValues.calculateTopPadding(), bottom = paddingValues.calculateBottomPadding(), - start = ZcashTheme.dimens.spacingDefault, - end = ZcashTheme.dimens.spacingDefault + start = ZcashTheme.dimens.screenHorizontalSpacingRegular, + end = ZcashTheme.dimens.screenHorizontalSpacingRegular ) ) } @@ -136,6 +133,7 @@ private fun UpdateTopAppBar(updateInfo: UpdateInfo) { } @Composable +@Suppress("LongMethod") private fun UpdateBottomAppBar( updateInfo: UpdateInfo, onDownload: (state: UpdateState) -> Unit, @@ -146,73 +144,143 @@ private fun UpdateBottomAppBar( modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally ) { - PrimaryButton( - onClick = { onDownload(UpdateState.Running) }, - text = stringResource(R.string.update_download_button), + HorizontalDivider( + thickness = DividerDefaults.Thickness, + color = ZcashTheme.colors.dividerColor + ) + + Column( modifier = Modifier - .testTag(UpdateTag.BTN_DOWNLOAD) - .fillMaxWidth(), - enabled = updateInfo.state != UpdateState.Running, - outerPaddingValues = PaddingValues(all = ZcashTheme.dimens.spacingNone), - ) + .padding( + top = ZcashTheme.dimens.spacingDefault, + bottom = ZcashTheme.dimens.spacingBig, + start = ZcashTheme.dimens.screenHorizontalSpacingBig, + end = ZcashTheme.dimens.screenHorizontalSpacingBig + ), + horizontalAlignment = Alignment.CenterHorizontally + ) { + PrimaryButton( + onClick = { onDownload(UpdateState.Running) }, + text = stringResource(R.string.update_download_button), + modifier = + Modifier + .testTag(UpdateTag.BTN_DOWNLOAD) + .fillMaxWidth(), + enabled = updateInfo.state != UpdateState.Running, + outerPaddingValues = PaddingValues(all = ZcashTheme.dimens.spacingNone), + ) - Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) - TertiaryButton( - onClick = onLater, - text = - stringResource( - updateInfo.isForce.let { force -> - if (force) { - R.string.update_later_disabled_button + if (updateInfo.isForce) { + Text( + text = stringResource(R.string.update_later_disabled_button), + textAlign = TextAlign.Center, + style = ZcashTheme.typography.primary.bodyLarge, + fontWeight = FontWeight.SemiBold, + 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 { - R.string.update_later_enabled_button + // Keep current state } - } - ), - modifier = Modifier.testTag(UpdateTag.BTN_LATER), - enabled = !updateInfo.isForce && updateInfo.state != UpdateState.Running, - outerPaddingValues = PaddingValues(top = ZcashTheme.dimens.spacingSmall) - ) + }, + textAlign = TextAlign.Center, + modifier = + Modifier + .padding(all = ZcashTheme.dimens.spacingDefault) + .testTag(UpdateTag.BTN_LATER) + ) + } + } } } @Composable -private fun UpdateContentNormal( +@Suppress("LongMethod") +private fun UpdateContentContent( onReference: () -> Unit, - modifier: Modifier = Modifier + updateInfo: UpdateInfo, + modifier: Modifier = Modifier, ) { + val appName = stringResource(id = R.string.app_name) + Column( - modifier = modifier, + modifier = + modifier.then( + Modifier + .fillMaxHeight() + .verticalScroll( + rememberScrollState() + ) + ), horizontalAlignment = Alignment.CenterHorizontally ) { - // Replace this placeholder graphic once this screen is being redesigned - @Suppress("MagicNumber") + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig)) + Image( - imageVector = Icons.Filled.Update, - contentDescription = stringResource(id = R.string.update_image_content_description), - modifier = Modifier.fillMaxSize(0.45f) + imageVector = + if (updateInfo.isForce) { + ImageVector.vectorResource(R.drawable.ic_zashi_logo_update_required) + } else { + ImageVector.vectorResource(R.drawable.ic_zashi_logo_update_available) + }, + contentDescription = stringResource(id = R.string.update_image_content_description) ) - Body( - text = stringResource(id = R.string.update_description), - modifier = - Modifier - .wrapContentHeight() - .align(Alignment.CenterHorizontally) + Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingBig)) + + Text( + text = + if (updateInfo.isForce) { + stringResource(id = R.string.update_title_required) + } else { + stringResource(id = R.string.update_title_available, appName) + }, + style = ZcashTheme.extendedTypography.updateTitleStyle, + 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 = { - onReference() + if (updateInfo.state != UpdateState.Running) { + onReference() + } else { + // Keep current state + } }, - modifier = - Modifier - .wrapContentHeight() - .align(Alignment.CenterHorizontally) - .padding(all = ZcashTheme.dimens.spacingDefault), + 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)) } } diff --git a/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_available.xml b/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_available.xml new file mode 100644 index 00000000..70b1a725 --- /dev/null +++ b/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_available.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml b/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml new file mode 100644 index 00000000..5725a6ae --- /dev/null +++ b/ui-lib/src/main/res/ui/update/drawable/ic_zashi_logo_update_required.xml @@ -0,0 +1,14 @@ + + + + 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 e6f77c67..78539d9a 100644 --- a/ui-lib/src/main/res/ui/update/values/strings.xml +++ b/ui-lib/src/main/res/ui/update/values/strings.xml @@ -1,12 +1,21 @@ - + Update available - Critical update required! + Update required - There is a new version of the app available. + %1$s here. + It\'s not you, it\'s me. + + There is a required update for %1$s that makes major + improvements to performance and/or security. + + + There is a new version of %1$s 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. - Download Update + Update Remind me later - This can not be skipped. + (required) Unable to launch Google Play store app.