diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/navigation/BitwardenNavigationBarItem.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/navigation/BitwardenNavigationBarItem.kt new file mode 100644 index 000000000..4033271d8 --- /dev/null +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/navigation/BitwardenNavigationBarItem.kt @@ -0,0 +1,78 @@ +package com.x8bit.bitwarden.ui.platform.components.navigation + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.RowScope +import androidx.compose.material3.BadgedBox +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationBarItemDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import com.x8bit.bitwarden.ui.platform.components.badge.NotificationBadge +import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter + +/** + * A custom Bitwarden-themed bottom app bar. + * + * @param labelRes The custom label for the navigation item. + * @param contentDescriptionRes The custom content description for the navigation item. + * @param selectedIconRes The icon to be displayed when the navigation item is selected. + * @param unselectedIconRes The icon to be displayed when the navigation item is not selected. + * @param isSelected Indicates that the navigation item is selected. + * @param onClick The lambda to be invoked when the navigation item is clicked. + * @param modifier A [Modifier] that you can use to apply custom modifications to the composable. + * @param notificationCount The notification count for the navigation item. + */ +@Composable +fun RowScope.BitwardenNavigationBarItem( + @StringRes labelRes: Int, + @StringRes contentDescriptionRes: Int, + @DrawableRes selectedIconRes: Int, + @DrawableRes unselectedIconRes: Int, + isSelected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + notificationCount: Int = 0, +) { + NavigationBarItem( + icon = { + BadgedBox( + badge = { + NotificationBadge( + notificationCount = notificationCount, + isVisible = notificationCount > 0, + ) + }, + ) { + Icon( + painter = rememberVectorPainter( + id = if (isSelected) selectedIconRes else unselectedIconRes, + ), + contentDescription = stringResource(id = contentDescriptionRes), + ) + } + }, + label = { + Text( + text = stringResource(id = labelRes), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + }, + selected = isSelected, + onClick = onClick, + colors = NavigationBarItemDefaults.colors( + indicatorColor = MaterialTheme.colorScheme.secondaryContainer, + selectedIconColor = MaterialTheme.colorScheme.onSecondaryContainer, + unselectedIconColor = MaterialTheme.colorScheme.onSurface, + selectedTextColor = MaterialTheme.colorScheme.onSecondaryContainer, + unselectedTextColor = MaterialTheme.colorScheme.onSurface, + ), + modifier = modifier, + ) +} diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlockednavbar/VaultUnlockedNavBarScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlockednavbar/VaultUnlockedNavBarScreen.kt index efbb010da..30405bac2 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlockednavbar/VaultUnlockedNavBarScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlockednavbar/VaultUnlockedNavBarScreen.kt @@ -1,7 +1,5 @@ package com.x8bit.bitwarden.ui.platform.feature.vaultunlockednavbar -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.consumeWindowInsets @@ -12,14 +10,9 @@ import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBars -import androidx.compose.material3.BadgedBox import androidx.compose.material3.BottomAppBar -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.ScaffoldDefaults -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf @@ -29,8 +22,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavBackStackEntry @@ -47,10 +38,9 @@ import androidx.navigation.navOptions import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect import com.x8bit.bitwarden.ui.platform.base.util.max import com.x8bit.bitwarden.ui.platform.base.util.toDp -import com.x8bit.bitwarden.ui.platform.components.badge.NotificationBadge +import com.x8bit.bitwarden.ui.platform.components.navigation.BitwardenNavigationBarItem import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold import com.x8bit.bitwarden.ui.platform.components.scrim.BitwardenAnimatedScrim -import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter import com.x8bit.bitwarden.ui.platform.feature.search.model.SearchType import com.x8bit.bitwarden.ui.platform.feature.settings.navigateToSettingsGraph import com.x8bit.bitwarden.ui.platform.feature.settings.settingsGraph @@ -249,7 +239,6 @@ private fun VaultUnlockedNavBarScaffold( } } -@Suppress("LongMethod") @Composable private fun VaultBottomAppBar( state: VaultUnlockedNavBarState, @@ -277,56 +266,20 @@ private fun VaultBottomAppBar( // below recompose when the navigation state changes to update the selected tab. val navBackStackEntry by navController.currentBackStackEntryAsState() destinations.forEach { destination -> - val isSelected = navBackStackEntry.isCurrentTab(destination) - - NavigationBarItem( - icon = { - BadgedBox( - badge = { - NotificationBadge( - notificationCount = destination.notificationCount, - isVisible = destination.notificationCount > 0, - ) - }, - ) { - Icon( - painter = rememberVectorPainter( - id = if (isSelected) { - destination.iconResSelected - } else { - destination.iconRes - }, - ), - contentDescription = stringResource( - id = destination.contentDescriptionRes, - ), - ) - } + BitwardenNavigationBarItem( + labelRes = destination.labelRes, + contentDescriptionRes = destination.contentDescriptionRes, + selectedIconRes = destination.iconResSelected, + unselectedIconRes = destination.iconRes, + notificationCount = destination.notificationCount, + isSelected = navBackStackEntry.isCurrentTab(tab = destination), + onClick = when (destination) { + is VaultUnlockedNavBarTab.Vault -> vaultTabClickedAction + VaultUnlockedNavBarTab.Send -> sendTabClickedAction + VaultUnlockedNavBarTab.Generator -> generatorTabClickedAction + is VaultUnlockedNavBarTab.Settings -> settingsTabClickedAction }, - label = { - Text( - text = stringResource(id = destination.labelRes), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - selected = isSelected, - onClick = { - when (destination) { - is VaultUnlockedNavBarTab.Vault -> vaultTabClickedAction() - VaultUnlockedNavBarTab.Send -> sendTabClickedAction() - VaultUnlockedNavBarTab.Generator -> generatorTabClickedAction() - is VaultUnlockedNavBarTab.Settings -> settingsTabClickedAction() - } - }, - colors = NavigationBarItemDefaults.colors( - indicatorColor = MaterialTheme.colorScheme.secondaryContainer, - selectedIconColor = MaterialTheme.colorScheme.onSecondaryContainer, - unselectedIconColor = MaterialTheme.colorScheme.onSurface, - selectedTextColor = MaterialTheme.colorScheme.onSecondaryContainer, - unselectedTextColor = MaterialTheme.colorScheme.onSurface, - ), - modifier = Modifier.testTag(destination.testTag), + modifier = Modifier.testTag(tag = destination.testTag), ) } }