From 0b525e4a00f66e20818f393df461736a25112d46 Mon Sep 17 00:00:00 2001 From: Kimberly Crevecoeur Date: Tue, 25 Jul 2023 13:49:33 -0700 Subject: [PATCH] enable double-tap to flip camera directions (#23) --- .../feature/preview/PreviewScreen.kt | 23 ++++--- .../feature/preview/PreviewViewModel.kt | 61 +++++++++++-------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt index d0bb854b9..5ea4fadba 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewScreen.kt @@ -25,9 +25,9 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas import androidx.compose.foundation.border import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.gestures.rememberTransformableState import androidx.compose.foundation.gestures.transformable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -36,7 +36,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -46,8 +45,8 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -114,18 +113,18 @@ fun PreviewScreen( modifier = Modifier .fillMaxSize() .transformable(state = transformableState) + .pointerInput(Unit) { + detectTapGestures( + onDoubleTap = { offset -> + Log.d(TAG, "onDoubleTap $offset") + viewModel.flipCamera() + } + ) + } ) { CameraPreview( modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onDoubleTap = { offset -> - Log.d(TAG, "onDoubleTap $offset") - viewModel.flipCamera() - } - ) - }, + .fillMaxSize(), onSurfaceProviderReady = onSurfaceProviderReady, onRequestBitmapReady = { val bitmap = it.invoke() diff --git a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt index 724402d00..641d04f5e 100644 --- a/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt +++ b/feature/preview/src/main/java/com/google/jetpackcamera/feature/preview/PreviewViewModel.kt @@ -22,15 +22,15 @@ import androidx.camera.core.Preview.SurfaceProvider import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.jetpackcamera.domain.camera.CameraUseCase +import com.google.jetpackcamera.settings.SettingsRepository +import com.google.jetpackcamera.settings.model.DEFAULT_CAMERA_APP_SETTINGS +import com.google.jetpackcamera.settings.model.FlashModeStatus import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject -import com.google.jetpackcamera.settings.SettingsRepository -import com.google.jetpackcamera.settings.model.DEFAULT_CAMERA_APP_SETTINGS -import com.google.jetpackcamera.settings.model.FlashModeStatus private const val TAG = "PreviewViewModel" @@ -49,15 +49,16 @@ class PreviewViewModel @Inject constructor( val previewUiState: StateFlow = _previewUiState var runningCameraJob: Job? = null - private var recordingJob : Job? = null + private var recordingJob: Job? = null init { viewModelScope.launch { settingsRepository.cameraAppSettings.collect { //TODO: only update settings that were actually changed // currently resets all "quick" settings to stored settings - settings -> _previewUiState - .emit(previewUiState.value.copy(currentCameraSettings = settings)) + settings -> + _previewUiState + .emit(previewUiState.value.copy(currentCameraSettings = settings)) } } initializeCamera() @@ -97,15 +98,15 @@ class PreviewViewModel @Inject constructor( } } - fun setFlash(flashModeStatus: FlashModeStatus){ + fun setFlash(flashModeStatus: FlashModeStatus) { //update viewmodel value viewModelScope.launch { _previewUiState.emit( previewUiState.value.copy( currentCameraSettings = - previewUiState.value.currentCameraSettings.copy( - flash_mode_status = flashModeStatus - ) + previewUiState.value.currentCameraSettings.copy( + flash_mode_status = flashModeStatus + ) ) ) // apply to cameraUseCase @@ -115,24 +116,33 @@ class PreviewViewModel @Inject constructor( // flips the camera opposite to its current direction fun flipCamera() { - flipCamera(!previewUiState.value - .currentCameraSettings.default_front_camera) + flipCamera( + !previewUiState.value + .currentCameraSettings.default_front_camera + ) } + // sets the camera to a designated direction fun flipCamera(isFacingFront: Boolean) { - //update viewmodel value - viewModelScope.launch { - _previewUiState.emit( - previewUiState.value.copy( - currentCameraSettings = - previewUiState.value.currentCameraSettings.copy( - default_front_camera = isFacingFront - ) - ) - ) - // apply to cameraUseCase - cameraUseCase.flipCamera(previewUiState.value.currentCameraSettings.default_front_camera) - } + // only flip if 2 directions are available + if (previewUiState.value.currentCameraSettings.back_camera_available + && previewUiState.value.currentCameraSettings.front_camera_available + ) { + + //update viewmodel value + viewModelScope.launch { + _previewUiState.emit( + previewUiState.value.copy( + currentCameraSettings = + previewUiState.value.currentCameraSettings.copy( + default_front_camera = isFacingFront + ) + ) + ) + // apply to cameraUseCase + cameraUseCase.flipCamera(previewUiState.value.currentCameraSettings.default_front_camera) + } + } } fun captureImage() { @@ -188,6 +198,7 @@ class PreviewViewModel @Inject constructor( fun toggleQuickSettings() { toggleQuickSettings(!previewUiState.value.quickSettingsIsOpen) } + fun toggleQuickSettings(isOpen: Boolean) { viewModelScope.launch { _previewUiState.emit(