mirror of
https://github.com/bitwarden/android.git
synced 2026-07-31 10:09:53 -05:00
Add the overflow menu to the send screen (#469)
This commit is contained in:
committed by
Álison Fernandes
parent
cf2e87c9f5
commit
7a8da67944
@@ -16,40 +16,58 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
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.IntSize
|
||||
import androidx.core.net.toUri
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenMediumTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenSearchActionItem
|
||||
import com.x8bit.bitwarden.ui.platform.components.OverflowMenuItemData
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
* UI for the send screen.
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SendScreen(
|
||||
onNavigateNewSend: () -> Unit,
|
||||
viewModel: SendViewModel = hiltViewModel(),
|
||||
intentHandler: IntentHandler = IntentHandler(context = LocalContext.current),
|
||||
) {
|
||||
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||
val scrollBehavior =
|
||||
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState())
|
||||
val context = LocalContext.current
|
||||
EventsEffect(viewModel = viewModel) { event ->
|
||||
when (event) {
|
||||
is SendEvent.NavigateNewSend -> onNavigateNewSend()
|
||||
is SendEvent.ShowToast -> Toast
|
||||
.makeText(context, event.messsage(context.resources), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
|
||||
is SendEvent.NavigateToAboutSend -> {
|
||||
intentHandler.launchUri("https://bitwarden.com/products/send".toUri())
|
||||
}
|
||||
|
||||
is SendEvent.ShowToast -> {
|
||||
Toast
|
||||
.makeText(context, event.message(context.resources), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
|
||||
state = rememberTopAppBarState(),
|
||||
)
|
||||
BitwardenScaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
BitwardenMediumTopAppBar(
|
||||
title = stringResource(id = R.string.send),
|
||||
@@ -61,6 +79,28 @@ fun SendScreen(
|
||||
{ viewModel.trySendAction(SendAction.SearchClick) }
|
||||
},
|
||||
)
|
||||
BitwardenOverflowActionItem(
|
||||
menuItemDataList = persistentListOf(
|
||||
OverflowMenuItemData(
|
||||
text = stringResource(id = R.string.sync),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(SendAction.SyncClick) }
|
||||
},
|
||||
),
|
||||
OverflowMenuItemData(
|
||||
text = stringResource(id = R.string.lock),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(SendAction.LockClick) }
|
||||
},
|
||||
),
|
||||
OverflowMenuItemData(
|
||||
text = stringResource(id = R.string.about_send),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(SendAction.AboutSendClick) }
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
@@ -86,7 +126,7 @@ fun SendScreen(
|
||||
}
|
||||
},
|
||||
) { padding ->
|
||||
Box(Modifier.padding(padding)) {
|
||||
Box(modifier = Modifier.padding(padding)) {
|
||||
when (state) {
|
||||
SendState.Empty -> SendEmpty(
|
||||
remember(viewModel) {
|
||||
|
||||
@@ -2,13 +2,11 @@ package com.x8bit.bitwarden.ui.tools.feature.send
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -20,19 +18,29 @@ private const val KEY_STATE = "state"
|
||||
@HiltViewModel
|
||||
class SendViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val vaultRepo: VaultRepository,
|
||||
) : BaseViewModel<SendState, SendEvent, SendAction>(
|
||||
// We load the state from the savedStateHandle for testing purposes.
|
||||
initialState = savedStateHandle[KEY_STATE] ?: SendState.Empty,
|
||||
) {
|
||||
|
||||
init {
|
||||
stateFlow
|
||||
.onEach { savedStateHandle[KEY_STATE] = it }
|
||||
.launchIn(viewModelScope)
|
||||
override fun handleAction(action: SendAction): Unit = when (action) {
|
||||
SendAction.AboutSendClick -> handleAboutSendClick()
|
||||
SendAction.AddSendClick -> handleAddSendClick()
|
||||
SendAction.LockClick -> handleLockClick()
|
||||
SendAction.SearchClick -> handleSearchClick()
|
||||
SendAction.SyncClick -> handleSyncClick()
|
||||
}
|
||||
|
||||
override fun handleAction(action: SendAction): Unit = when (action) {
|
||||
SendAction.AddSendClick -> handleSendClick()
|
||||
SendAction.SearchClick -> handleSearchClick()
|
||||
private fun handleAboutSendClick() {
|
||||
sendEvent(SendEvent.NavigateToAboutSend)
|
||||
}
|
||||
|
||||
private fun handleAddSendClick() {
|
||||
sendEvent(SendEvent.NavigateNewSend)
|
||||
}
|
||||
|
||||
private fun handleLockClick() {
|
||||
vaultRepo.lockVaultForCurrentUser()
|
||||
}
|
||||
|
||||
private fun handleSearchClick() {
|
||||
@@ -40,7 +48,10 @@ class SendViewModel @Inject constructor(
|
||||
sendEvent(SendEvent.ShowToast("Search Not Implemented".asText()))
|
||||
}
|
||||
|
||||
private fun handleSendClick() = sendEvent(SendEvent.NavigateNewSend)
|
||||
private fun handleSyncClick() {
|
||||
// TODO: Add loading dialog state BIT-481
|
||||
vaultRepo.sync()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,15 +69,30 @@ sealed class SendState : Parcelable {
|
||||
* Models actions for the send screen.
|
||||
*/
|
||||
sealed class SendAction {
|
||||
/**
|
||||
* User clicked the about send button.
|
||||
*/
|
||||
data object AboutSendClick : SendAction()
|
||||
|
||||
/**
|
||||
* User clicked add a send.
|
||||
*/
|
||||
data object AddSendClick : SendAction()
|
||||
|
||||
/**
|
||||
* User clicked the lock button.
|
||||
*/
|
||||
data object LockClick : SendAction()
|
||||
|
||||
/**
|
||||
* User clicked search button.
|
||||
*/
|
||||
data object SearchClick : SendAction()
|
||||
|
||||
/**
|
||||
* User clicked the sync button.
|
||||
*/
|
||||
data object SyncClick : SendAction()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,8 +104,13 @@ sealed class SendEvent {
|
||||
*/
|
||||
data object NavigateNewSend : SendEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the about send screen.
|
||||
*/
|
||||
data object NavigateToAboutSend : SendEvent()
|
||||
|
||||
/**
|
||||
* Show a toast to the user.
|
||||
*/
|
||||
data class ShowToast(val messsage: Text) : SendEvent()
|
||||
data class ShowToast(val message: Text) : SendEvent()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user