feat: Add onLongClick to SaveButton

Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
Myzel394 2024-03-16 19:14:59 +01:00
parent 6627289666
commit fe24f3473f
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
7 changed files with 52 additions and 23 deletions

View File

@ -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,
)
}
}

View File

@ -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")
},
)
}
}
}

View File

@ -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 = {},
)
}

View File

@ -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 = {

View File

@ -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
}
)
}

View File

@ -46,7 +46,7 @@ abstract class BaseRecorderModel<I, B : BatchesFolder, T : IntervalRecorderServi
// If `isSavingAsOldRecording` is true, the user is saving an old recording,
// thus the service is not running and thus doesn't need to be stopped or destroyed
var onRecordingSave: () -> Job = {
var onRecordingSave: (cleanupOldFiles: Boolean) -> Job = {
throw NotImplementedError("onRecordingSave not implemented")
}
var onRecordingStart: () -> Unit = {}

View File

@ -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)
}
}
},