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 366d59d99..1f80ebc99 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 890cd5344..75117e888 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 f820dd4ca..b8e302aad 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 855266701..baeea08db 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 ee9844f26..bf37490c5 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 8220d58a3..df54b36f9 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 ca084f16f..df54b36f9 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 463bd0b9d..a923925ee 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 860d4c963..5f06e6bf2 100644 --- a/app/src/main/res/drawable/logo_rounded.xml +++ b/app/src/main/res/drawable/logo_rounded.xml @@ -1,14 +1,21 @@ - - - - + + + + + diff --git a/app/src/main/res/values/colors_palette.xml b/app/src/main/res/values/colors_palette.xml index ebac38b89..6b01e9b3b 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 e53878f02..7ee472988 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 a0cbd9908..365950bcc 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.