From 8a3bfcae4d2d171faf10bc29151bc39d7b5196e4 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:27:28 +0100 Subject: [PATCH] fix: Improve camera-info.kt and CamerasSelection --- .../atoms/CameraSelectionButton.kt | 4 +- .../molecules/CamerasSelection.kt | 15 +- .../VideoRecorderPreparationSheet.kt | 176 +++++++++--------- .../ui/models/VideoRecorderSettingsModel.kt | 8 +- .../myzel394/alibi/ui/utils/camera-info.kt | 21 ++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 121 insertions(+), 104 deletions(-) diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraSelectionButton.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraSelectionButton.kt index 7a13c3c..47e340b 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraSelectionButton.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraSelectionButton.kt @@ -1,5 +1,4 @@ -package app.myzel394.alibi.ui.components.RecorderScreen.atoms - +import androidx.camera.core.ExperimentalLensFacing import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring @@ -28,6 +27,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import app.myzel394.alibi.ui.utils.CameraInfo + @Composable fun CameraSelectionButton( cameraID: CameraInfo.Lens, diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/CamerasSelection.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/CamerasSelection.kt index 764498e..d25bf00 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/CamerasSelection.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/CamerasSelection.kt @@ -1,10 +1,13 @@ package app.myzel394.alibi.ui.components.RecorderScreen.molecules +import CameraSelectionButton +import androidx.annotation.OptIn +import androidx.camera.core.CameraSelector +import androidx.camera.core.ExperimentalLensFacing import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import app.myzel394.alibi.R -import app.myzel394.alibi.ui.components.RecorderScreen.atoms.CameraSelectionButton import app.myzel394.alibi.ui.models.VideoRecorderSettingsModel import app.myzel394.alibi.ui.utils.CameraInfo @@ -24,23 +27,23 @@ fun CamerasSelection( CameraSelectionButton( cameraID = CameraInfo.Lens.BACK, label = stringResource(R.string.ui_videoRecorder_action_start_settings_cameraLens_back_label), - selected = videoSettings.cameraID == 0, + selected = videoSettings.cameraID == CameraInfo.Lens.BACK.androidValue, onSelected = { - videoSettings.cameraID = 0 + videoSettings.cameraID = CameraInfo.Lens.BACK.androidValue }, ) CameraSelectionButton( cameraID = CameraInfo.Lens.FRONT, label = stringResource(R.string.ui_videoRecorder_action_start_settings_cameraLens_front_label), - selected = videoSettings.cameraID == 1, + selected = videoSettings.cameraID == CameraInfo.Lens.FRONT.androidValue, onSelected = { - videoSettings.cameraID = 1 + videoSettings.cameraID = CameraInfo.Lens.FRONT.androidValue }, ) } else { cameras.forEach { camera -> CameraSelectionButton( - cameraID = CameraInfo.CAMERA_INT_TO_LENS_MAP[camera.id]!!, + cameraID = camera.lens, selected = videoSettings.cameraID == camera.id, onSelected = { videoSettings.cameraID = camera.id diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/VideoRecorderPreparationSheet.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/VideoRecorderPreparationSheet.kt index ea79548..7dd9754 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/VideoRecorderPreparationSheet.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/VideoRecorderPreparationSheet.kt @@ -1,6 +1,7 @@ package app.myzel394.alibi.ui.components.RecorderScreen.molecules import android.Manifest +import androidx.camera.core.CameraSelector import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.gestures.awaitEachGesture @@ -10,6 +11,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -26,6 +28,10 @@ import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -45,12 +51,12 @@ import app.myzel394.alibi.ui.BIG_PRIMARY_BUTTON_SIZE import app.myzel394.alibi.ui.components.RecorderScreen.atoms.CameraPreview import app.myzel394.alibi.ui.components.atoms.GlobalSwitch import app.myzel394.alibi.ui.components.atoms.PermissionRequester +import app.myzel394.alibi.ui.effects.rememberPrevious import app.myzel394.alibi.ui.models.VideoRecorderSettingsModel import app.myzel394.alibi.ui.utils.CameraInfo @OptIn( - ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class, - ExperimentalComposeUiApi::class + ExperimentalMaterial3Api::class, ) @Composable fun VideoRecorderPreparationSheet( @@ -69,19 +75,34 @@ fun VideoRecorderPreparationSheet( videoSettings.init(context) } - if (showPreview) - CameraPreview( + ModalBottomSheet( + onDismissRequest = onDismiss, + sheetState = sheetState, + dragHandle = if (showPreview) { + null + } else null, + ) { + Box( modifier = Modifier - .fillMaxWidth() - .fillMaxHeight() - ) - else { - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = sheetState, + .pointerInput(Unit) { + awaitEachGesture { + while (true) { + val event = awaitPointerEvent() + if (!event.changes.elementAt(0).pressed) { + onPreviewHidden() + break + } + } + } + } ) { - Box( - ) { + if (showPreview) { + CameraPreview( + modifier = Modifier + .fillMaxSize(), + cameraSelector = videoSettings.cameraSelector, + ) + } else Column( modifier = Modifier .padding(horizontal = 16.dp, vertical = 24.dp), @@ -119,80 +140,63 @@ fun VideoRecorderPreparationSheet( ) } - Text( - stringResource(R.string.ui_videoRecorder_action_start_settings_cameraLens_selection_label), - style = MaterialTheme.typography.labelLarge, - textAlign = TextAlign.Start, - modifier = Modifier.fillMaxWidth() - ) - CamerasSelection( - cameras = cameras, - videoSettings = videoSettings, - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(BIG_PRIMARY_BUTTON_SIZE) - ) - } - - } - } - } - - Popup( - alignment = Alignment.BottomCenter, - ) { - val label = - stringResource(R.string.ui_videoRecorder_action_start_settings_start_label) - - Box( - modifier = Modifier - .pointerInput(Unit) { - awaitEachGesture { - while (true) { - val event = awaitPointerEvent() - // consume all changes - - if (!event.changes.elementAt(0).pressed) { - onPreviewHidden() - break - } - } - } - } - .let { - if (showPreview) it.alpha(0.2f) else it - } - ) { - Row( - modifier = Modifier - .padding(16.dp) - .fillMaxWidth() - .height(BIG_PRIMARY_BUTTON_SIZE) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .padding(16.dp) - .semantics { - contentDescription = label - } - .pointerInput(Unit) { - detectTapGestures( - onLongPress = { - onPreviewVisible() - } + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + stringResource(R.string.ui_videoRecorder_action_start_settings_cameraLens_selection_label), + style = MaterialTheme.typography.labelLarge, + textAlign = TextAlign.Start, + modifier = Modifier.fillMaxWidth() ) - }, - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - label, - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onPrimary, - ) - } + CamerasSelection( + cameras = cameras, + videoSettings = videoSettings, + ) + } + + val label = + stringResource(R.string.ui_videoRecorder_action_start_settings_start_label) + + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .height(BIG_PRIMARY_BUTTON_SIZE) + .clip(CircleShape) + .background(MaterialTheme.colorScheme.primary) + .padding(16.dp) + .semantics { + contentDescription = label + } + .pointerInput(Unit) { + detectTapGestures( + onLongPress = { + onPreviewVisible() + } + ) + }, + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + label, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.onPrimary, + ) + } + Text( + stringResource( + R.string.ui_videoRecorder_action_preview_label + ), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } } } } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/models/VideoRecorderSettingsModel.kt b/app/src/main/java/app/myzel394/alibi/ui/models/VideoRecorderSettingsModel.kt index d755c5b..f2c2e25 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/models/VideoRecorderSettingsModel.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/models/VideoRecorderSettingsModel.kt @@ -11,14 +11,18 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel +import app.myzel394.alibi.ui.utils.CameraInfo import app.myzel394.alibi.ui.utils.PermissionHelper class VideoRecorderSettingsModel : ViewModel() { var enableAudio by mutableStateOf(true) - var cameraID by mutableIntStateOf(CameraSelector.LENS_FACING_BACK) + var cameraID by mutableIntStateOf(CameraInfo.Lens.BACK.androidValue) + + val cameraSelector: CameraSelector + get() = CameraSelector.Builder().requireLensFacing(cameraID).build() fun init(context: Context) { enableAudio = PermissionHelper.hasGranted(context, Manifest.permission.RECORD_AUDIO) - cameraID = CameraSelector.LENS_FACING_BACK + cameraID = CameraInfo.Lens.BACK.androidValue } } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/utils/camera-info.kt b/app/src/main/java/app/myzel394/alibi/ui/utils/camera-info.kt index 050c467..5e6be2f 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/utils/camera-info.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/utils/camera-info.kt @@ -4,22 +4,28 @@ import android.content.Context import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraMetadata +import androidx.annotation.OptIn +import androidx.camera.core.CameraSelector +import androidx.camera.core.ExperimentalLensFacing +@OptIn(ExperimentalLensFacing::class) data class CameraInfo( - val lens: Lens, val id: Int, ) { enum class Lens(val androidValue: Int) { - BACK(CameraMetadata.LENS_FACING_BACK), - FRONT(CameraMetadata.LENS_FACING_FRONT), - EXTERNAL(CameraMetadata.LENS_FACING_EXTERNAL), + BACK(CameraSelector.LENS_FACING_BACK), + FRONT(CameraSelector.LENS_FACING_FRONT), + EXTERNAL(CameraSelector.LENS_FACING_EXTERNAL), } + val lens: Lens + get() = CAMERA_INT_TO_LENS_MAP[id]!! + companion object { val CAMERA_INT_TO_LENS_MAP = mapOf( - 0 to Lens.BACK, - 1 to Lens.FRONT, - 2 to Lens.EXTERNAL, + CameraSelector.LENS_FACING_BACK to Lens.BACK, + CameraSelector.LENS_FACING_FRONT to Lens.FRONT, + CameraSelector.LENS_FACING_EXTERNAL to Lens.EXTERNAL, ) fun queryAvailableCameras(context: Context): List { @@ -36,7 +42,6 @@ data class CameraInfo( fun fromCameraId(cameraId: String, lensFacing: Int): CameraInfo { return CameraInfo( - lens = CAMERA_INT_TO_LENS_MAP[lensFacing]!!, id = cameraId.toInt(), ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c8e98dd..475505b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -147,4 +147,5 @@ Start Recording Prepare your recording Select camera + Hold down on button to preview your camera \ No newline at end of file