diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/SaveButton.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/SaveButton.kt index 28d960d..f8719c1 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/SaveButton.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/SaveButton.kt @@ -1,35 +1,51 @@ package app.myzel394.alibi.ui.components.RecorderScreen.atoms -import androidx.compose.material3.Button +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import app.myzel394.alibi.R +@OptIn(ExperimentalFoundationApi::class) @Composable fun SaveButton( modifier: Modifier = Modifier, onSave: () -> Unit, + onLongClick: () -> Unit = {}, ) { val label = stringResource(R.string.ui_recorder_action_save_label) - TextButton( + Box( modifier = Modifier + .clip(ButtonDefaults.textShape) .semantics { contentDescription = label } - .then(modifier), - onClick = onSave, + .combinedClickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(color = MaterialTheme.colorScheme.primary), + onClick = onSave, + onLongClick = onLongClick, + ) + .padding(ButtonDefaults.TextButtonContentPadding) + .then(modifier) ) { Text( label, - fontSize = MaterialTheme.typography.bodySmall.fontSize, + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.primary, ) } } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/RecordingControl.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/RecordingControl.kt index 8e1bdde..47764d5 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/RecordingControl.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/molecules/RecordingControl.kt @@ -35,7 +35,8 @@ fun RecordingControl( recordingTime: Long, onDelete: () -> Unit, onPauseResume: () -> Unit, - onSave: () -> Unit, + onSaveAndStop: () -> Unit, + onSaveCurrent: () -> Unit, ) { val animateIn = rememberInitialRecordingAnimation(recordingTime) @@ -106,7 +107,10 @@ fun RecordingControl( contentAlignment = Alignment.Center, ) { SaveButton( - onSave = onSave, + onSave = onSaveAndStop, + onLongClick = { + println("onLongClick") + }, modifier = Modifier.fillMaxWidth(), ) } @@ -170,7 +174,12 @@ fun RecordingControl( .alpha(saveButtonAlpha), contentAlignment = Alignment.Center, ) { - SaveButton(onSave = onSave) + SaveButton( + onSave = onSaveAndStop, + onLongClick = { + println("onLongClick") + }, + ) } } } diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/AudioRecordingStatus.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/AudioRecordingStatus.kt index bc97706..3fc4dba 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/AudioRecordingStatus.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/AudioRecordingStatus.kt @@ -144,7 +144,7 @@ fun _PrimitiveControls(audioRecorder: AudioRecorderModel) { audioRecorder.pauseRecording() } }, - onSave = { + onSaveAndStop = { scope.launch { audioRecorder.stopRecording(context) @@ -152,12 +152,13 @@ fun _PrimitiveControls(audioRecorder: AudioRecorderModel) { it.saveLastRecording(audioRecorder as RecorderModel) } - audioRecorder.onRecordingSave() + audioRecorder.onRecordingSave(false) runCatching { audioRecorder.destroyService(context) } } - } + }, + onSaveCurrent = {}, ) } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/RecorderEventsHandler.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/RecorderEventsHandler.kt index 15eb477..1af0f86 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/RecorderEventsHandler.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/RecorderEventsHandler.kt @@ -129,7 +129,7 @@ fun RecorderEventsHandler( } } - suspend fun saveRecording(recorder: RecorderModel): Thread { + suspend fun saveRecording(recorder: RecorderModel, cleanupOldFiles: Boolean = false): Thread { isProcessing = true // Give the user some time to see the processing dialog @@ -217,7 +217,7 @@ fun RecorderEventsHandler( } catch (error: Exception) { Log.getStackTraceString(error) } finally { - recorder.recorderService?.unlockFiles() + recorder.recorderService?.unlockFiles(cleanupOldFiles) isProcessing = false } } @@ -226,14 +226,14 @@ fun RecorderEventsHandler( // Register audio recorder events DisposableEffect(key1 = audioRecorder, key2 = settings) { - audioRecorder.onRecordingSave = { + audioRecorder.onRecordingSave = { cleanupOldFiles -> // We create our own coroutine because we show our own dialog and we want to // keep saving until it's finished. // So it's smarter to take things into our own hands and use our local coroutine, // instead of hoping that the coroutine from where this will be called will be alive // until the end of the saving process scope.launch { - saveRecording(audioRecorder as RecorderModel).join() + saveRecording(audioRecorder as RecorderModel, cleanupOldFiles).join() } } audioRecorder.onRecordingStart = { @@ -269,14 +269,14 @@ fun RecorderEventsHandler( // Register video recorder events DisposableEffect(key1 = videoRecorder, key2 = settings) { - videoRecorder.onRecordingSave = { + videoRecorder.onRecordingSave = { cleanupOldFiles -> // We create our own coroutine because we show our own dialog and we want to // keep saving until it's finished. // So it's smarter to take things into our own hands and use our local coroutine, // instead of hoping that the coroutine from where this will be called will be alive // until the end of the saving process scope.launch { - saveRecording(videoRecorder as RecorderModel).join() + saveRecording(videoRecorder as RecorderModel, cleanupOldFiles).join() } } videoRecorder.onRecordingStart = { diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt index ec5471b..4245f00 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt @@ -219,7 +219,7 @@ fun _PrimitiveControls(videoRecorder: VideoRecorderModel) { videoRecorder.pauseRecording() } }, - onSave = { + onSaveAndStop = { scope.launch { videoRecorder.stopRecording(context) @@ -227,12 +227,15 @@ fun _PrimitiveControls(videoRecorder: VideoRecorderModel) { it.saveLastRecording(videoRecorder as RecorderModel) } - videoRecorder.onRecordingSave().join() + videoRecorder.onRecordingSave(false).join() runCatching { videoRecorder.destroyService(context) } } + }, + onSaveCurrent = { + //TODO } ) } diff --git a/app/src/main/java/app/myzel394/alibi/ui/models/BaseRecorderModel.kt b/app/src/main/java/app/myzel394/alibi/ui/models/BaseRecorderModel.kt index 1b54229..e55ec83 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/models/BaseRecorderModel.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/models/BaseRecorderModel.kt @@ -46,7 +46,7 @@ abstract class BaseRecorderModel Job = { + var onRecordingSave: (cleanupOldFiles: Boolean) -> Job = { throw NotImplementedError("onRecordingSave not implemented") } var onRecordingStart: () -> Unit = {} diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/RecorderScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/RecorderScreen.kt index ae5cb01..a086840 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/screens/RecorderScreen.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/screens/RecorderScreen.kt @@ -120,10 +120,10 @@ fun RecorderScreen( scope.launch { when (settings.lastRecording!!.type) { RecordingInformation.Type.AUDIO -> - audioRecorder.onRecordingSave() + audioRecorder.onRecordingSave(false) RecordingInformation.Type.VIDEO -> - videoRecorder.onRecordingSave() + videoRecorder.onRecordingSave(false) } } },