PM-27149: Update empty vault illustration (#6059)

This commit is contained in:
David Perez
2025-10-20 16:46:31 -05:00
committed by GitHub
parent 97bb93c18e
commit 9874aad65a
20 changed files with 152 additions and 560 deletions

View File

@@ -18,8 +18,6 @@ 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.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@@ -31,9 +29,9 @@ import com.bitwarden.ui.platform.components.button.BitwardenFilledButton
import com.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog
import com.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.platform.theme.BitwardenTheme
/**
* Top level composable for the unlock screen.
@@ -114,8 +112,7 @@ fun UnlockScreen(
.width(220.dp)
.height(74.dp)
.fillMaxWidth(),
colorFilter = ColorFilter.tint(BitwardenTheme.colorScheme.icon.secondary),
painter = painterResource(id = BitwardenDrawable.ic_logo_horizontal),
painter = rememberVectorPainter(id = BitwardenDrawable.ic_logo_horizontal),
contentDescription = stringResource(BitwardenString.bitwarden_authenticator),
)
Spacer(modifier = Modifier.height(32.dp))

View File

@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.rememberScrollState
@@ -29,11 +30,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -72,7 +71,6 @@ import com.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarHost
import com.bitwarden.ui.platform.components.snackbar.model.rememberBitwardenSnackbarHostState
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.bitwarden.ui.platform.composition.LocalIntentManager
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.manager.IntentManager
import com.bitwarden.ui.platform.resource.BitwardenDrawable
import com.bitwarden.ui.platform.resource.BitwardenString
@@ -255,7 +253,6 @@ fun ItemListingScreen(
is ItemListingState.ViewState.NoItems -> {
EmptyItemListingContent(
actionCardState = currentState.actionCard,
appTheme = state.appTheme,
onAddCodeClick = remember(viewModel) {
{ launcher.launch(Manifest.permission.CAMERA) }
},
@@ -498,7 +495,6 @@ private fun ItemListingContent(
@Composable
fun EmptyItemListingContent(
actionCardState: ItemListingState.ActionCardState,
appTheme: AppTheme,
onAddCodeClick: () -> Unit,
onDownloadBitwardenClick: () -> Unit,
onDismissDownloadBitwardenClick: () -> Unit,
@@ -538,18 +534,11 @@ fun EmptyItemListingContent(
) {
Image(
modifier = Modifier.fillMaxWidth(),
painter = painterResource(
id = when (appTheme) {
AppTheme.DARK -> BitwardenDrawable.ic_empty_vault_dark
AppTheme.LIGHT -> BitwardenDrawable.ic_empty_vault_light
AppTheme.DEFAULT -> BitwardenDrawable.ic_empty_vault
},
),
contentDescription = stringResource(
id = BitwardenString.empty_item_list,
),
contentScale = ContentScale.Fit,
painter = rememberVectorPainter(id = BitwardenDrawable.img_authenticator),
contentDescription = stringResource(id = BitwardenString.empty_item_list),
modifier = Modifier
.size(size = 100.dp)
.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(16.dp))
@@ -641,7 +630,6 @@ private fun ActionCard(
private fun EmptyListingContentPreview() {
EmptyItemListingContent(
modifier = Modifier.padding(horizontal = 16.dp),
appTheme = AppTheme.DEFAULT,
onAddCodeClick = { },
actionCardState = ItemListingState.ActionCardState.DownloadBitwardenApp,
onDownloadBitwardenClick = { },

View File

@@ -27,7 +27,6 @@ import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager
import com.bitwarden.core.data.repository.model.DataState
import com.bitwarden.ui.platform.base.BaseViewModel
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.Text
import com.bitwarden.ui.util.asText
@@ -59,8 +58,7 @@ class ItemListingViewModel @Inject constructor(
private val settingsRepository: SettingsRepository,
) : BaseViewModel<ItemListingState, ItemListingEvent, ItemListingAction>(
initialState = ItemListingState(
settingsRepository.appTheme,
settingsRepository.authenticatorAlertThresholdSeconds,
alertThresholdSeconds = settingsRepository.authenticatorAlertThresholdSeconds,
viewState = ItemListingState.ViewState.Loading,
dialog = null,
),
@@ -73,12 +71,6 @@ class ItemListingViewModel @Inject constructor(
.onEach(::sendAction)
.launchIn(viewModelScope)
settingsRepository
.appThemeStateFlow
.map { ItemListingAction.Internal.AppThemeChangeReceive(it) }
.onEach(::sendAction)
.launchIn(viewModelScope)
combine(
flow = authenticatorRepository.getLocalVerificationCodesFlow(),
flow2 = authenticatorRepository.sharedCodesStateFlow,
@@ -253,10 +245,6 @@ class ItemListingViewModel @Inject constructor(
handleDeleteItemReceive(internalAction.result)
}
is ItemListingAction.Internal.AppThemeChangeReceive -> {
handleAppThemeChangeReceive(internalAction.appTheme)
}
ItemListingAction.Internal.FirstTimeUserSyncReceive -> {
handleFirstTimeUserSync()
}
@@ -272,12 +260,6 @@ class ItemListingViewModel @Inject constructor(
)
}
private fun handleAppThemeChangeReceive(appTheme: AppTheme) {
mutableStateFlow.update {
it.copy(appTheme = appTheme)
}
}
private fun handleDeleteItemReceive(result: DeleteItemResult) {
when (result) {
DeleteItemResult.Error -> {
@@ -730,7 +712,6 @@ const val ISSUER = "issuer"
*/
@Parcelize
data class ItemListingState(
val appTheme: AppTheme,
val alertThresholdSeconds: Int,
val viewState: ViewState,
val dialog: DialogState?,
@@ -1036,11 +1017,6 @@ sealed class ItemListingAction {
*/
data class DeleteItemReceive(val result: DeleteItemResult) : Internal()
/**
* Indicates app theme change has been received.
*/
data class AppThemeChangeReceive(val appTheme: AppTheme) : Internal()
/**
* Indicates that a user synced with Bitwarden for the first time.
*/

View File

@@ -190,7 +190,7 @@ private fun TutorialScreenPortrait(
Image(
painter = rememberVectorPainter(id = state.image),
contentDescription = null,
modifier = Modifier.size(200.dp),
modifier = Modifier.size(size = 124.dp),
)
Text(
@@ -223,7 +223,7 @@ private fun TutorialScreenLandscape(
Image(
painter = rememberVectorPainter(id = state.image),
contentDescription = null,
modifier = Modifier.size(132.dp),
modifier = Modifier.size(size = 124.dp),
)
Spacer(modifier = Modifier.weight(1f))

View File

@@ -92,7 +92,7 @@ data class TutorialState(
*/
@Parcelize
data object IntroSlide : TutorialSlide() {
override val image: Int get() = BitwardenDrawable.ic_tutorial_verification_codes
override val image: Int get() = BitwardenDrawable.img_authenticator
override val title: Int get() = BitwardenString.secure_your_accounts_with_bitwarden_authenticator
override val message: Int get() = BitwardenString.get_verification_codes_for_all_your_accounts
}
@@ -102,7 +102,7 @@ data class TutorialState(
*/
@Parcelize
data object QrScannerSlide : TutorialSlide() {
override val image: Int get() = BitwardenDrawable.ic_tutorial_qr_scanner
override val image: Int get() = BitwardenDrawable.lock
override val title: Int get() = BitwardenString.use_your_device_camera_to_scan_codes
override val message: Int get() = BitwardenString.scan_the_qr_code_in_your_2_step_verification_settings_for_any_account
}
@@ -112,7 +112,7 @@ data class TutorialState(
*/
@Parcelize
data object UniqueCodesSlide : TutorialSlide() {
override val image: Int get() = BitwardenDrawable.ic_tutorial_2fa
override val image: Int get() = BitwardenDrawable.ill_pin
override val title: Int get() = BitwardenString.sign_in_using_unique_codes
override val message: Int get() = BitwardenString.when_using_2_step_verification_youll_enter_your_username_and_password_and_a_code_generated_in_this_app
}

View File

@@ -19,7 +19,6 @@ import com.bitwarden.authenticator.ui.platform.components.listitem.model.Verific
import com.bitwarden.authenticator.ui.platform.manager.permissions.FakePermissionManager
import com.bitwarden.authenticator.ui.platform.util.startBitwardenAccountSettings
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.manager.IntentManager
import com.bitwarden.ui.util.asText
import com.bitwarden.ui.util.onNodeWithContentDescriptionAfterScroll
@@ -538,7 +537,6 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
}
}
private val APP_THEME = AppTheme.DEFAULT
private const val ALERT_THRESHOLD = 7
private val LOCAL_CODE = VerificationCodeDisplayItem(
@@ -575,7 +573,6 @@ private val SHARED_ACCOUNTS_SECTION = SharedCodesDisplayState.SharedCodesAccount
)
private val DEFAULT_STATE = ItemListingState(
appTheme = APP_THEME,
alertThresholdSeconds = ALERT_THRESHOLD,
viewState = ItemListingState.ViewState.NoItems(
actionCard = ItemListingState.ActionCardState.None,

View File

@@ -17,7 +17,6 @@ import com.bitwarden.authenticator.ui.platform.components.listitem.model.Verific
import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager
import com.bitwarden.core.data.repository.model.DataState
import com.bitwarden.ui.platform.base.BaseViewModelTest
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.asText
import io.mockk.every
@@ -39,7 +38,6 @@ class ItemListingViewModelTest : BaseViewModelTest() {
private val mutableAuthenticatorAlertThresholdFlow =
MutableStateFlow(AUTHENTICATOR_ALERT_SECONDS)
private val mutableAppThemeFlow = MutableStateFlow(APP_THEME)
private val mutableVerificationCodesFlow =
MutableStateFlow<DataState<List<VerificationCodeItem>>>(DataState.Loading)
private val mutableSharedCodesFlow =
@@ -57,14 +55,12 @@ class ItemListingViewModelTest : BaseViewModelTest() {
private val clipboardManager: BitwardenClipboardManager = mockk()
private val encodingManager: BitwardenEncodingManager = mockk()
private val settingsRepository: SettingsRepository = mockk {
every { appTheme } returns mutableAppThemeFlow.value
every {
authenticatorAlertThresholdSeconds
} returns mutableAuthenticatorAlertThresholdFlow.value
every {
authenticatorAlertThresholdSecondsFlow
} returns mutableAuthenticatorAlertThresholdFlow
every { appThemeStateFlow } returns mutableAppThemeFlow
every { hasUserDismissedDownloadBitwardenCard } returns false
}
@@ -559,10 +555,8 @@ class ItemListingViewModelTest : BaseViewModelTest() {
)
}
private val APP_THEME: AppTheme = mockk()
private const val AUTHENTICATOR_ALERT_SECONDS = 7
private val DEFAULT_STATE = ItemListingState(
appTheme = APP_THEME,
alertThresholdSeconds = AUTHENTICATOR_ALERT_SECONDS,
viewState = ItemListingState.ViewState.Loading,
dialog = null,