From c0b04694d972cac598dd366191b9d1d03ebcb2c9 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com> Date: Sat, 27 Apr 2024 14:49:06 -0400 Subject: [PATCH] Release prep and refinement (#64) --- .../ui/auth/unlock/UnlockScreen.kt | 19 ++++-- .../feature/edititem/EditItemScreen.kt | 2 +- .../feature/itemlisting/ItemListingScreen.kt | 8 +-- .../manualcodeentry/ManualCodeEntryScreen.kt | 61 ++++++++++++++----- .../ManualCodeEntryViewModel.kt | 34 +++++++++++ .../res/drawable/ic_launcher_foreground.xml | 47 ++++++-------- .../res/drawable/ic_launcher_monochrome.xml | 31 +++++----- .../main/res/drawable/ic_logo_horizontal.xml | 41 +++---------- app/src/main/res/drawable/logo_rounded.xml | 23 ++++--- app/src/main/res/values/colors_palette.xml | 1 + .../res/values/ic_launcher_background.xml | 2 +- app/src/main/res/values/strings.xml | 10 ++- 12 files changed, 164 insertions(+), 115 deletions(-) diff --git a/app/src/main/kotlin/com/bitwarden/authenticator/ui/auth/unlock/UnlockScreen.kt b/app/src/main/kotlin/com/bitwarden/authenticator/ui/auth/unlock/UnlockScreen.kt index 366d59d991..1f80ebc999 100644 --- a/app/src/main/kotlin/com/bitwarden/authenticator/ui/auth/unlock/UnlockScreen.kt +++ b/app/src/main/kotlin/com/bitwarden/authenticator/ui/auth/unlock/UnlockScreen.kt @@ -10,7 +10,9 @@ 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.width import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -18,6 +20,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -27,7 +30,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.bitwarden.authenticator.R import com.bitwarden.authenticator.ui.platform.base.util.EventsEffect import com.bitwarden.authenticator.ui.platform.base.util.asText -import com.bitwarden.authenticator.ui.platform.components.button.BitwardenOutlinedButton +import com.bitwarden.authenticator.ui.platform.components.button.BitwardenFilledTonalButton import com.bitwarden.authenticator.ui.platform.components.dialog.BasicDialogState import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenBasicDialog import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenLoadingDialog @@ -107,7 +110,7 @@ fun UnlockScreen( BitwardenScaffold( modifier = Modifier - .fillMaxSize() + .fillMaxSize(), ) { innerPadding -> Box { Column( @@ -118,11 +121,17 @@ fun UnlockScreen( horizontalAlignment = Alignment.CenterHorizontally ) { Image( + modifier = Modifier + .padding(horizontal = 16.dp) + .width(220.dp) + .height(74.dp) + .fillMaxWidth(), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary), painter = painterResource(id = R.drawable.ic_logo_horizontal), - contentDescription = stringResource(R.string.bitwarden_authenticator) + contentDescription = stringResource(R.string.bitwarden_authenticator), ) - Spacer(modifier = Modifier.height(12.dp)) - BitwardenOutlinedButton( + Spacer(modifier = Modifier.height(32.dp)) + BitwardenFilledTonalButton( label = stringResource(id = R.string.use_biometrics_to_unlock), onClick = { biometricsManager.promptBiometrics( diff --git a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/edititem/EditItemScreen.kt b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/edititem/EditItemScreen.kt index 890cd53441..75117e888a 100644 --- a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/edititem/EditItemScreen.kt +++ b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/edititem/EditItemScreen.kt @@ -249,7 +249,7 @@ fun EditItemContent( modifier = Modifier .fillMaxSize() .padding(horizontal = 16.dp), - label = stringResource(id = R.string.secret_key), + label = stringResource(id = R.string.key), value = viewState.itemData.totpCode, onValueChange = onTotpCodeTextChange, singleLine = true, diff --git a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/itemlisting/ItemListingScreen.kt b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/itemlisting/ItemListingScreen.kt index f820dd4ca9..b8e302aad4 100644 --- a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/itemlisting/ItemListingScreen.kt +++ b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/itemlisting/ItemListingScreen.kt @@ -320,10 +320,10 @@ private fun ItemListingContent( onScanQrCodeClick = onScanQrCodeClick, ), ItemListingExpandableFabAction.EnterSetupKey( - label = R.string.enter_a_setup_key.asText(), + label = R.string.enter_key_manually.asText(), icon = IconResource( iconPainter = painterResource(id = R.drawable.ic_keyboard_24px), - contentDescription = stringResource(id = R.string.enter_a_setup_key), + contentDescription = stringResource(id = R.string.enter_key_manually), testTag = "EnterSetupKeyButton", ), onEnterSetupKeyClick = onEnterSetupKeyClick @@ -413,10 +413,10 @@ fun EmptyItemListingContent( onScanQrCodeClick = onScanQuCodeClick ), ItemListingExpandableFabAction.EnterSetupKey( - label = R.string.enter_a_setup_key.asText(), + label = R.string.enter_key_manually.asText(), icon = IconResource( iconPainter = painterResource(id = R.drawable.ic_keyboard_24px), - contentDescription = stringResource(id = R.string.enter_a_setup_key), + contentDescription = stringResource(id = R.string.enter_key_manually), testTag = "EnterSetupKeyButton", ), onEnterSetupKeyClick = onEnterSetupKeyClick, diff --git a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryScreen.kt b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryScreen.kt index 855266701d..baeea08db6 100644 --- a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryScreen.kt +++ b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryScreen.kt @@ -35,7 +35,11 @@ import com.bitwarden.authenticator.ui.platform.base.util.EventsEffect import com.bitwarden.authenticator.ui.platform.base.util.toAnnotatedString import com.bitwarden.authenticator.ui.platform.components.appbar.BitwardenTopAppBar import com.bitwarden.authenticator.ui.platform.components.button.BitwardenFilledTonalButton +import com.bitwarden.authenticator.ui.platform.components.dialog.BasicDialogState +import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenBasicDialog +import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenLoadingDialog import com.bitwarden.authenticator.ui.platform.components.dialog.BitwardenTwoButtonDialog +import com.bitwarden.authenticator.ui.platform.components.dialog.LoadingDialogState import com.bitwarden.authenticator.ui.platform.components.field.BitwardenTextField import com.bitwarden.authenticator.ui.platform.components.scaffold.BitwardenScaffold import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager @@ -108,11 +112,38 @@ fun ManualCodeEntryScreen( ) } + when (val dialog = state.dialog) { + + is ManualCodeEntryState.DialogState.Error -> { + BitwardenBasicDialog( + visibilityState = BasicDialogState.Shown( + title = dialog.title, + message = dialog.message + ), + onDismissRequest = remember(state) { + { viewModel.trySendAction(ManualCodeEntryAction.DismissDialog) } + } + ) + } + + is ManualCodeEntryState.DialogState.Loading -> { + BitwardenLoadingDialog( + visibilityState = LoadingDialogState.Shown( + dialog.message + ) + ) + } + + null -> { + Unit + } + } + BitwardenScaffold( modifier = Modifier.fillMaxSize(), topBar = { BitwardenTopAppBar( - title = stringResource(id = R.string.authenticator_key_scanner), + title = stringResource(id = R.string.create_verification_code), navigationIcon = painterResource(id = R.drawable.ic_close), navigationIconContentDescription = stringResource(id = R.string.close), onNavigationIconClick = remember(viewModel) { @@ -133,22 +164,22 @@ fun ManualCodeEntryScreen( Spacer(modifier = Modifier.height(8.dp)) BitwardenTextField( label = stringResource(id = R.string.name), - value = state.issuer, - onValueChange = remember(viewModel) { - { - viewModel.trySendAction( - ManualCodeEntryAction.IssuerTextChange(it), - ) - } - }, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), + value = state.issuer, + onValueChange = remember(viewModel) { + { + viewModel.trySendAction( + ManualCodeEntryAction.IssuerTextChange(it), + ) + } + }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), ) Spacer(modifier = Modifier.height(8.dp)) BitwardenTextField( singleLine = false, - label = stringResource(id = R.string.authenticator_key_scanner), + label = stringResource(id = R.string.key), value = state.code, onValueChange = remember(viewModel) { { @@ -164,7 +195,7 @@ fun ManualCodeEntryScreen( Spacer(modifier = Modifier.height(16.dp)) BitwardenFilledTonalButton( - label = stringResource(id = R.string.add_totp), + label = stringResource(id = R.string.add_code), onClick = remember(viewModel) { { viewModel.trySendAction(ManualCodeEntryAction.CodeSubmit) } }, @@ -185,7 +216,7 @@ fun ManualCodeEntryScreen( ) Text( - text = stringResource(id = R.string.cannot_add_authenticator_key), + text = stringResource(id = R.string.cannot_add_key), style = MaterialTheme.typography.bodyMedium, modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryViewModel.kt b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryViewModel.kt index ee9844f267..bf37490c5c 100644 --- a/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryViewModel.kt +++ b/app/src/main/kotlin/com/bitwarden/authenticator/ui/authenticator/feature/manualcodeentry/ManualCodeEntryViewModel.kt @@ -43,9 +43,17 @@ class ManualCodeEntryViewModel @Inject constructor( is ManualCodeEntryAction.Internal.CreateItemResultReceive -> { handleCreateItemReceive(action) } + + ManualCodeEntryAction.DismissDialog -> { + handleDialogDismiss() + } } } + private fun handleDialogDismiss() { + mutableStateFlow.update { it.copy(dialog = null) } + } + private fun handleIssuerTextChange(action: ManualCodeEntryAction.IssuerTextChange) { mutableStateFlow.update { it.copy(issuer = action.issuer) @@ -63,6 +71,27 @@ class ManualCodeEntryViewModel @Inject constructor( } private fun handleCodeSubmit() { + if (state.code.isBlank()) { + mutableStateFlow.update { + it.copy( + dialog = ManualCodeEntryState.DialogState.Error( + message = R.string.key_is_required.asText() + ) + ) + } + return + } + + if (state.issuer.isBlank()) { + mutableStateFlow.update { + it.copy( + dialog = ManualCodeEntryState.DialogState.Error( + message = R.string.name_is_required.asText() + ) + ) + } + return + } viewModelScope.launch { val result = authenticatorRepository.createItem( AuthenticatorItemEntity( @@ -216,4 +245,9 @@ sealed class ManualCodeEntryAction { * The action for the user clicking the settings button. */ data object SettingsClick : ManualCodeEntryAction() + + /** + * The user has dismissed the dialog. + */ + data object DismissDialog : ManualCodeEntryAction() } diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 8220d58a30..df54b36f91 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,34 +1,21 @@ - - - - - - - - - - - - - - + android:viewportHeight="108" + android:viewportWidth="108"> + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml index ca084f16f2..df54b36f91 100644 --- a/app/src/main/res/drawable/ic_launcher_monochrome.xml +++ b/app/src/main/res/drawable/ic_launcher_monochrome.xml @@ -1,18 +1,21 @@ - - - - - + android:viewportHeight="108" + android:viewportWidth="108"> + + + + + diff --git a/app/src/main/res/drawable/ic_logo_horizontal.xml b/app/src/main/res/drawable/ic_logo_horizontal.xml index 463bd0b9de..a923925ee3 100644 --- a/app/src/main/res/drawable/ic_logo_horizontal.xml +++ b/app/src/main/res/drawable/ic_logo_horizontal.xml @@ -1,44 +1,17 @@ + android:width="697dp" + android:height="188dp" + android:viewportWidth="697" + android:viewportHeight="188"> - - - - - - - - diff --git a/app/src/main/res/drawable/logo_rounded.xml b/app/src/main/res/drawable/logo_rounded.xml index 860d4c9630..5f06e6bf2a 100644 --- a/app/src/main/res/drawable/logo_rounded.xml +++ b/app/src/main/res/drawable/logo_rounded.xml @@ -1,14 +1,21 @@ - - - + android:pathData="M63.95,56.33V43H54.5V66.69C56.17,65.81 57.67,64.86 58.99,63.83C62.3,61.28 63.95,58.78 63.95,56.33ZM68,40.33V56.33C68,57.53 67.76,58.71 67.29,59.89C66.82,61.06 66.24,62.1 65.54,63.01C64.85,63.92 64.02,64.81 63.05,65.67C62.09,66.53 61.2,67.24 60.39,67.81C59.57,68.38 58.72,68.92 57.83,69.43C56.95,69.93 56.32,70.28 55.94,70.46C55.57,70.64 55.27,70.78 55.05,70.88C54.88,70.96 54.7,71 54.5,71C54.3,71 54.12,70.96 53.95,70.88C53.73,70.78 53.43,70.64 53.06,70.46C52.68,70.28 52.05,69.93 51.17,69.43C50.28,68.92 49.43,68.38 48.61,67.81C47.8,67.24 46.91,66.53 45.95,65.67C44.98,64.81 44.15,63.92 43.46,63.01C42.76,62.1 42.18,61.06 41.71,59.89C41.24,58.71 41,57.53 41,56.33V40.33C41,39.97 41.13,39.66 41.4,39.4C41.67,39.13 41.98,39 42.35,39H66.65C67.02,39 67.33,39.13 67.6,39.4C67.87,39.66 68,39.97 68,40.33Z" + android:fillColor="#ffffff"/> + + + + diff --git a/app/src/main/res/values/colors_palette.xml b/app/src/main/res/values/colors_palette.xml index ebac38b89d..6b01e9b3bc 100644 --- a/app/src/main/res/values/colors_palette.xml +++ b/app/src/main/res/values/colors_palette.xml @@ -11,6 +11,7 @@ #002B74 #002B73 #001848 + #020F66 #151B2C diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml index e53878f026..7ee472988b 100644 --- a/app/src/main/res/values/ic_launcher_background.xml +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - @color/blue_175DDC + @color/blue_020F66 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a0cbd9908b..365950bcc1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Bitwarden Authenticator + Authenticator Biometric verification Cancel Add item @@ -21,7 +21,7 @@ Point your camera at the QR code. Cannot scan QR code. Enter key manually. - Cannot add authenticator key? + Cannot add key? Once the key is successfully entered,\nselect Add TOTP to store the key safely Add TOTP Authenticator key @@ -32,7 +32,7 @@ You don\'t have any items to display. Add a new code to secure your accounts. Add code - Cannot read authenticator key. + Cannot read key. Verification code added Username Refresh period @@ -103,4 +103,8 @@ Privacy policy Continue to privacy policy? Check out our privacy policy on bitwarden.com + Key + Create Verification code + Key is required. + Name is required.