Prompt for camera permissions from item listing screen (#34)

This commit is contained in:
Patrick Honkonen
2024-04-16 23:19:51 -04:00
committed by GitHub
parent 736761ee93
commit de02a6999d
2 changed files with 61 additions and 1 deletions

View File

@@ -1,5 +1,9 @@
package com.x8bit.bitwarden.authenticator.ui.authenticator.feature.itemlisting
import android.Manifest
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@@ -21,7 +25,10 @@ import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -38,6 +45,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.x8bit.bitwarden.authenticator.R
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.itemlisting.model.ItemListingExpandableFabAction
import com.x8bit.bitwarden.authenticator.ui.authenticator.feature.manualcodeentry.ManualCodeEntryAction
import com.x8bit.bitwarden.authenticator.ui.platform.base.util.EventsEffect
import com.x8bit.bitwarden.authenticator.ui.platform.base.util.asText
import com.x8bit.bitwarden.authenticator.ui.platform.components.appbar.BitwardenTopAppBar
@@ -54,6 +62,10 @@ import com.x8bit.bitwarden.authenticator.ui.platform.components.icon.BitwardenIc
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.manager.intent.IntentManager
import com.x8bit.bitwarden.authenticator.ui.platform.manager.permissions.PermissionsManager
import com.x8bit.bitwarden.authenticator.ui.platform.theme.LocalIntentManager
import com.x8bit.bitwarden.authenticator.ui.platform.theme.LocalPermissionsManager
import com.x8bit.bitwarden.authenticator.ui.platform.theme.Typography
/**
@@ -63,6 +75,8 @@ import com.x8bit.bitwarden.authenticator.ui.platform.theme.Typography
@Composable
fun ItemListingScreen(
viewModel: ItemListingViewModel = hiltViewModel(),
intentManager: IntentManager = LocalIntentManager.current,
permissionsManager: PermissionsManager = LocalPermissionsManager.current,
onNavigateBack: () -> Unit,
onNavigateToSearch: () -> Unit,
onNavigateToQrCodeScanner: () -> Unit,
@@ -75,6 +89,14 @@ fun ItemListingScreen(
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val pullToRefreshState = rememberPullToRefreshState()
val context = LocalContext.current
var shouldShowPermissionDialog by rememberSaveable { mutableStateOf(false) }
val launcher = permissionsManager.getLauncher { isGranted ->
if (isGranted) {
viewModel.trySendAction(ItemListingAction.ScanQrCodeClick)
} else {
shouldShowPermissionDialog = true
}
}
EventsEffect(viewModel = viewModel) { event ->
when (event) {
@@ -94,9 +116,29 @@ fun ItemListingScreen(
}
is ItemListingEvent.NavigateToEditItem -> onNavigateToEditItemScreen(event.id)
is ItemListingEvent.NavigateToAppSettings -> {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:" + context.packageName)
intentManager.startActivity(intent = intent)
}
}
}
if (shouldShowPermissionDialog) {
BitwardenTwoButtonDialog(
message = stringResource(id = R.string.enable_camera_permission_to_use_the_scanner),
confirmButtonText = stringResource(id = R.string.settings),
dismissButtonText = stringResource(id = R.string.no_thanks),
onConfirmClick = remember(viewModel) {
{ viewModel.trySendAction(ItemListingAction.SettingsClick) }
},
onDismissClick = { shouldShowPermissionDialog = false },
onDismissRequest = { shouldShowPermissionDialog = false },
title = null,
)
}
ItemListingDialogs(
dialog = state.dialog,
onDismissRequest = remember(viewModel) {
@@ -152,7 +194,7 @@ fun ItemListingScreen(
testTag = "ScanQRCodeButton",
),
onScanQrCodeClick = {
viewModel.trySendAction(ItemListingAction.ScanQrCodeClick)
launcher.launch(Manifest.permission.CAMERA)
}
),
ItemListingExpandableFabAction.EnterSetupKey(

View File

@@ -106,12 +106,20 @@ class ItemListingViewModel @Inject constructor(
handleDialogDismiss()
}
is ItemListingAction.SettingsClick -> {
handleSettingsClick()
}
is ItemListingAction.Internal -> {
handleInternalAction(action)
}
}
}
private fun handleSettingsClick() {
sendEvent(ItemListingEvent.NavigateToAppSettings)
}
private fun handleItemClick(action: ItemListingAction.ItemClick) {
clipboardManager.setText(action.authCode)
sendEvent(
@@ -533,6 +541,11 @@ sealed class ItemListingEvent {
val id: String,
) : ItemListingEvent()
/**
* Navigate to the app settings.
*/
data object NavigateToAppSettings : ItemListingEvent()
/**
* Show a Toast with [message].
*/
@@ -582,6 +595,11 @@ sealed class ItemListingAction {
*/
data object DialogDismiss : ItemListingAction()
/**
* The user has clicked the settings button
*/
data object SettingsClick : ItemListingAction()
/**
* Models actions that [ItemListingScreen] itself may send.
*/