Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main' into bottomba…
Browse files Browse the repository at this point in the history
…r-navigation

# Conflicts:
#	app/src/main/kotlin/com/x8bit/bitwarden/authenticator/ui/authenticator/feature/itemlisting/ItemListingGraphNavigation.kt
#	app/src/main/res/values/strings.xml
  • Loading branch information
SaintPatrck committed Apr 13, 2024
2 parents 7f49ba9 + a27002a commit a850807
Show file tree
Hide file tree
Showing 23 changed files with 1,473 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.manualcodeentr
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.manualcodeentry.navigateToManualCodeEntryScreen
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.qrcodescan.navigateToQrCodeScanScreen
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.qrcodescan.qrCodeScanDestination
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search.itemSearchDestination
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search.navigateToSearch

const val ITEM_LISTING_GRAPH_ROUTE = "item_listing_graph"

Expand All @@ -27,6 +29,7 @@ fun NavGraphBuilder.itemListingGraph(
) {
itemListingDestination(
onNavigateBack = { navController.popBackStack() },
onNavigateToSearch = { navController.navigateToSearch() },
onNavigateToQrCodeScanner = navigateToQrCodeScanner,
onNavigateToManualKeyEntry = navigateToManualKeyEntry,
onNavigateToEditItemScreen = navigateToEditItem,
Expand All @@ -38,6 +41,9 @@ fun NavGraphBuilder.itemListingGraph(
editItemDestination(
onNavigateBack = { navController.popBackStack() },
)
itemSearchDestination(
onNavigateBack = { navController.popBackStack() }
)
qrCodeScanDestination(
onNavigateBack = { navController.popBackStack() },
onNavigateToManualCodeEntryScreen = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const val ITEM_LIST_ROUTE = "item_list"
*/
fun NavGraphBuilder.itemListingDestination(
onNavigateBack: () -> Unit = { },
onNavigateToSearch: () -> Unit,
onNavigateToQrCodeScanner: () -> Unit = { },
onNavigateToManualKeyEntry: () -> Unit = { },
onNavigateToEditItemScreen: (id: String) -> Unit = { },
Expand All @@ -21,6 +22,7 @@ fun NavGraphBuilder.itemListingDestination(
) {
ItemListingScreen(
onNavigateBack = onNavigateBack,
onNavigateToSearch = onNavigateToSearch,
onNavigateToQrCodeScanner = onNavigateToQrCodeScanner,
onNavigateToManualKeyEntry = onNavigateToManualKeyEntry,
onNavigateToEditItemScreen = onNavigateToEditItemScreen,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.x8bit.bitwarden.authenticator.ui.authenticator.feature.itemlisting

import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
Expand All @@ -13,6 +14,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
Expand Down Expand Up @@ -46,6 +48,8 @@ import com.x8bit.bitwarden.authenticator.ui.platform.components.dialog.Bitwarden
import com.x8bit.bitwarden.authenticator.ui.platform.components.dialog.LoadingDialogState
import com.x8bit.bitwarden.authenticator.ui.platform.components.fab.ExpandableFabIcon
import com.x8bit.bitwarden.authenticator.ui.platform.components.fab.ExpandableFloatingActionButton
import com.x8bit.bitwarden.authenticator.ui.platform.components.icon.BitwardenIcon
import com.x8bit.bitwarden.authenticator.ui.platform.components.model.IconData
import com.x8bit.bitwarden.authenticator.ui.platform.components.model.IconResource
import com.x8bit.bitwarden.authenticator.ui.platform.components.scaffold.BitwardenScaffold
import com.x8bit.bitwarden.authenticator.ui.platform.theme.Typography
Expand All @@ -58,6 +62,7 @@ import com.x8bit.bitwarden.authenticator.ui.platform.theme.Typography
fun ItemListingScreen(
viewModel: ItemListingViewModel = hiltViewModel(),
onNavigateBack: () -> Unit,
onNavigateToSearch: () -> Unit,
onNavigateToQrCodeScanner: () -> Unit,
onNavigateToManualKeyEntry: () -> Unit,
onNavigateToEditItemScreen: (id: String) -> Unit,
Expand All @@ -71,10 +76,11 @@ fun ItemListingScreen(

EventsEffect(viewModel = viewModel) { event ->
when (event) {
ItemListingEvent.NavigateBack -> onNavigateBack()
ItemListingEvent.DismissPullToRefresh -> pullToRefreshState.endRefresh()
ItemListingEvent.NavigateToQrCodeScanner -> onNavigateToQrCodeScanner()
ItemListingEvent.NavigateToManualAddItem -> onNavigateToManualKeyEntry()
is ItemListingEvent.NavigateBack -> onNavigateBack()
is ItemListingEvent.NavigateToSearch -> onNavigateToSearch()
is ItemListingEvent.DismissPullToRefresh -> pullToRefreshState.endRefresh()
is ItemListingEvent.NavigateToQrCodeScanner -> onNavigateToQrCodeScanner()
is ItemListingEvent.NavigateToManualAddItem -> onNavigateToManualKeyEntry()
is ItemListingEvent.ShowToast -> {
Toast
.makeText(
Expand All @@ -98,6 +104,17 @@ fun ItemListingScreen(
title = stringResource(id = R.string.verification_codes),
scrollBehavior = scrollBehavior,
navigationIcon = null,
actions = {
if (state.viewState !is ItemListingState.ViewState.NoItems) {
BitwardenIcon(
modifier = Modifier.clickable {
viewModel.trySendAction(ItemListingAction.SearchClick)
},
iconData = IconData.Local(R.drawable.ic_search_24px),
tint = MaterialTheme.colorScheme.surfaceTint
)
}
}
)
},
floatingActionButton = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,15 @@ class ItemListingViewModel @Inject constructor(
sendEvent(ItemListingEvent.NavigateBack)
}

is ItemListingAction.SearchClick -> {
sendEvent(ItemListingEvent.NavigateToSearch)
}

is ItemListingAction.ItemClick -> {
sendEvent(ItemListingEvent.NavigateToEditItem(action.id))
}

ItemListingAction.DialogDismiss -> {
is ItemListingAction.DialogDismiss -> {
handleDialogDismiss()
}

Expand Down Expand Up @@ -239,7 +243,9 @@ class ItemListingViewModel @Inject constructor(
}
}

private fun authenticatorNoNetworkReceive(state: DataState.NoNetwork<List<VerificationCodeItem>>) {
private fun authenticatorNoNetworkReceive(
state: DataState.NoNetwork<List<VerificationCodeItem>>,
) {
if (state.data != null) {
updateStateWithVerificationCodeItems(
authenticatorData = state.data,
Expand Down Expand Up @@ -414,6 +420,11 @@ sealed class ItemListingEvent {
*/
data object NavigateBack : ItemListingEvent()

/**
* Navigates to the Search screen.
*/
data object NavigateToSearch : ItemListingEvent()

/**
* Navigate to the QR Code Scanner screen.
*/
Expand Down Expand Up @@ -450,6 +461,11 @@ sealed class ItemListingAction {
*/
data object BackClick : ItemListingAction()

/**
* The user has clicked the search button.
*/
data object SearchClick : ItemListingAction()

/**
* The user clicked the Scan QR Code button.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search.handlers.SearchHandlers

/**
* The content state for the item search screen.
*/
@Composable
fun ItemSearchContent(
viewState: ItemSearchState.ViewState.Content,
searchHandlers: SearchHandlers,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier = modifier) {
items(viewState.displayItems) {
VaultVerificationCodeItem(
modifier = Modifier
.fillMaxWidth()
.padding(
start = 16.dp,
// There is some built-in padding to the menu button that makes up
// the visual difference here.
end = 12.dp,
),
authCode = it.authCode,
issuer = it.issuer,
periodSeconds = it.periodSeconds,
timeLeftSeconds = it.timeLeftSeconds,
alertThresholdSeconds = it.alertThresholdSeconds,
supportingLabel = it.supportingLabel,
startIcon = it.startIcon,
onCopyClick = { searchHandlers.onItemClick(it.id) },
onItemClick = { searchHandlers.onItemClick(it.id) },
)
}

item {
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
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.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.authenticator.R

/**
* The empty state for the item search screen.
*/
@Composable
fun ItemSearchEmptyContent(
viewState: ItemSearchState.ViewState.Empty,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
painter = painterResource(id = R.drawable.ic_search_24px),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier
.size(74.dp)
.padding(horizontal = 16.dp),
)

Spacer(modifier = Modifier.height(24.dp))

viewState.message?.let {
Text(
textAlign = TextAlign.Center,
modifier = Modifier
.semantics { testTag = "NoSearchResultsLabel" }
.fillMaxWidth()
.padding(horizontal = 16.dp),
text = it(),
style = MaterialTheme.typography.bodyMedium,
)
}

Spacer(modifier = Modifier.navigationBarsPadding())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.x8bit.bitwarden.authenticator.ui.authenticator.feature.search

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import com.x8bit.bitwarden.authenticator.ui.platform.base.util.composableWithSlideTransitions

const val ITEM_SEARCH_ROUTE = "item_search"

/**
* Add item search destination to the nav graph.
*/
fun NavGraphBuilder.itemSearchDestination(
onNavigateBack: () -> Unit,
) {
composableWithSlideTransitions(
route = ITEM_SEARCH_ROUTE,
) {
ItemSearchScreen(
onNavigateBack = onNavigateBack
)
}
}

/**
* Navigate to the item search screen.
*/
fun NavController.navigateToSearch() {
navigate(route = ITEM_SEARCH_ROUTE)
}
Loading

0 comments on commit a850807

Please sign in to comment.