diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchNavigation.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchNavigation.kt index f68411268f..2d5d839b3e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchNavigation.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchNavigation.kt @@ -48,6 +48,7 @@ data class SearchArgs( */ fun NavGraphBuilder.searchDestination( onNavigateBack: () -> Unit, + onNavigateToEditSend: (sendId: String) -> Unit, ) { composableWithSlideTransitions( route = SEARCH_ROUTE, @@ -61,6 +62,7 @@ fun NavGraphBuilder.searchDestination( ) { SearchScreen( onNavigateBack = onNavigateBack, + onNavigateToEditSend = onNavigateToEditSend, ) } } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreen.kt index ec817235ca..4dc948c9b3 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreen.kt @@ -1,5 +1,6 @@ package com.x8bit.bitwarden.ui.platform.feature.search +import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -19,6 +20,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -29,6 +31,8 @@ import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar import com.x8bit.bitwarden.ui.platform.components.NavigationIcon +import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager +import com.x8bit.bitwarden.ui.platform.theme.LocalIntentManager /** * The search UI for vault items or send items. @@ -37,12 +41,22 @@ import com.x8bit.bitwarden.ui.platform.components.NavigationIcon @Composable fun SearchScreen( onNavigateBack: () -> Unit, + onNavigateToEditSend: (sendId: String) -> Unit, + intentManager: IntentManager = LocalIntentManager.current, viewModel: SearchViewModel = hiltViewModel(), ) { val state by viewModel.stateFlow.collectAsStateWithLifecycle() + val context = LocalContext.current EventsEffect(viewModel = viewModel) { event -> when (event) { SearchEvent.NavigateBack -> onNavigateBack() + is SearchEvent.NavigateToEditSend -> onNavigateToEditSend(event.sendId) + is SearchEvent.ShowShareSheet -> intentManager.shareText(event.content) + is SearchEvent.ShowToast -> { + Toast + .makeText(context, event.message(context.resources), Toast.LENGTH_SHORT) + .show() + } } } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt index 6e245bd17b..b0b8e5fcce 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt @@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.platform.feature.search import android.os.Parcelable import androidx.lifecycle.SavedStateHandle import com.x8bit.bitwarden.ui.platform.base.BaseViewModel +import com.x8bit.bitwarden.ui.platform.base.util.Text import com.x8bit.bitwarden.ui.platform.feature.search.model.SearchType import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.parcelize.Parcelize @@ -60,4 +61,25 @@ sealed class SearchEvent { * Navigates back to the previous screen. */ data object NavigateBack : SearchEvent() + + /** + * Navigates to edit a send. + */ + data class NavigateToEditSend( + val sendId: String, + ) : SearchEvent() + + /** + * Shares the [content] with share sheet. + */ + data class ShowShareSheet( + val content: String, + ) : SearchEvent() + + /** + * Show a toast with the given [message]. + */ + data class ShowToast( + val message: Text, + ) : SearchEvent() } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlocked/VaultUnlockedNavigation.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlocked/VaultUnlockedNavigation.kt index 94dd0ab0d4..d73741a39d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlocked/VaultUnlockedNavigation.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/vaultunlocked/VaultUnlockedNavigation.kt @@ -99,7 +99,6 @@ fun NavGraphBuilder.vaultUnlockedGraph( } else { VaultAddEditType.EditItem(vaultItemId) }, - ) }, onNavigateToMoveToOrganization = { @@ -125,7 +124,10 @@ fun NavGraphBuilder.vaultUnlockedGraph( passwordHistoryDestination(onNavigateBack = { navController.popBackStack() }) foldersDestination(onNavigateBack = { navController.popBackStack() }) generatorModalDestination(onNavigateBack = { navController.popBackStack() }) - searchDestination(onNavigateBack = { navController.popBackStack() }) + searchDestination( + onNavigateBack = { navController.popBackStack() }, + onNavigateToEditSend = { navController.navigateToAddSend(AddSendType.EditItem(it)) }, + ) } } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt index f08ce8b356..227ddd8c85 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt @@ -3,9 +3,14 @@ package com.x8bit.bitwarden.ui.platform.feature.search import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest import com.x8bit.bitwarden.ui.platform.feature.search.model.SearchType +import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import io.mockk.every +import io.mockk.just import io.mockk.mockk +import io.mockk.runs +import io.mockk.verify import kotlinx.coroutines.flow.MutableStateFlow +import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test @@ -17,15 +22,21 @@ class SearchScreenTest : BaseComposeTest() { every { eventFlow } returns mutableEventFlow every { stateFlow } returns mutableStateFlow } + private val intentManager: IntentManager = mockk { + every { shareText(any()) } just runs + } private var onNavigateBackCalled = false + private var onNavigateToEditSendId: String? = null @Before fun setup() { composeTestRule.setContent { SearchScreen( viewModel = viewModel, + intentManager = intentManager, onNavigateBack = { onNavigateBackCalled = true }, + onNavigateToEditSend = { onNavigateToEditSendId = it }, ) } } @@ -35,6 +46,22 @@ class SearchScreenTest : BaseComposeTest() { mutableEventFlow.tryEmit(SearchEvent.NavigateBack) assertTrue(onNavigateBackCalled) } + + @Test + fun `NavigateToEditSend should call onNavigateToEditSend`() { + val sendId = "sendId" + mutableEventFlow.tryEmit(SearchEvent.NavigateToEditSend(sendId)) + assertEquals(sendId, onNavigateToEditSendId) + } + + @Test + fun `ShowShareSheet should call onNavigateBack`() { + val sendUrl = "www.test.com" + mutableEventFlow.tryEmit(SearchEvent.ShowShareSheet(sendUrl)) + verify { + intentManager.shareText(sendUrl) + } + } } private val DEFAULT_STATE: SearchState = SearchState(