mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-19 07:15:25 +02:00
feat: Add onLongClick to SaveButton
Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
parent
6627289666
commit
fe24f3473f
@ -1,35 +1,51 @@
|
|||||||
package app.myzel394.alibi.ui.components.RecorderScreen.atoms
|
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.ButtonDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import app.myzel394.alibi.R
|
import app.myzel394.alibi.R
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SaveButton(
|
fun SaveButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onSave: () -> Unit,
|
onSave: () -> Unit,
|
||||||
|
onLongClick: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val label = stringResource(R.string.ui_recorder_action_save_label)
|
val label = stringResource(R.string.ui_recorder_action_save_label)
|
||||||
|
|
||||||
TextButton(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.clip(ButtonDefaults.textShape)
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = label
|
contentDescription = label
|
||||||
}
|
}
|
||||||
.then(modifier),
|
.combinedClickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = rememberRipple(color = MaterialTheme.colorScheme.primary),
|
||||||
onClick = onSave,
|
onClick = onSave,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
)
|
||||||
|
.padding(ButtonDefaults.TextButtonContentPadding)
|
||||||
|
.then(modifier)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,7 +35,8 @@ fun RecordingControl(
|
|||||||
recordingTime: Long,
|
recordingTime: Long,
|
||||||
onDelete: () -> Unit,
|
onDelete: () -> Unit,
|
||||||
onPauseResume: () -> Unit,
|
onPauseResume: () -> Unit,
|
||||||
onSave: () -> Unit,
|
onSaveAndStop: () -> Unit,
|
||||||
|
onSaveCurrent: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val animateIn = rememberInitialRecordingAnimation(recordingTime)
|
val animateIn = rememberInitialRecordingAnimation(recordingTime)
|
||||||
|
|
||||||
@ -106,7 +107,10 @@ fun RecordingControl(
|
|||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
SaveButton(
|
SaveButton(
|
||||||
onSave = onSave,
|
onSave = onSaveAndStop,
|
||||||
|
onLongClick = {
|
||||||
|
println("onLongClick")
|
||||||
|
},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -170,7 +174,12 @@ fun RecordingControl(
|
|||||||
.alpha(saveButtonAlpha),
|
.alpha(saveButtonAlpha),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
SaveButton(onSave = onSave)
|
SaveButton(
|
||||||
|
onSave = onSaveAndStop,
|
||||||
|
onLongClick = {
|
||||||
|
println("onLongClick")
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ fun _PrimitiveControls(audioRecorder: AudioRecorderModel) {
|
|||||||
audioRecorder.pauseRecording()
|
audioRecorder.pauseRecording()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSave = {
|
onSaveAndStop = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
audioRecorder.stopRecording(context)
|
audioRecorder.stopRecording(context)
|
||||||
|
|
||||||
@ -152,12 +152,13 @@ fun _PrimitiveControls(audioRecorder: AudioRecorderModel) {
|
|||||||
it.saveLastRecording(audioRecorder as RecorderModel)
|
it.saveLastRecording(audioRecorder as RecorderModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
audioRecorder.onRecordingSave()
|
audioRecorder.onRecordingSave(false)
|
||||||
|
|
||||||
runCatching {
|
runCatching {
|
||||||
audioRecorder.destroyService(context)
|
audioRecorder.destroyService(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
onSaveCurrent = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -129,7 +129,7 @@ fun RecorderEventsHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun saveRecording(recorder: RecorderModel): Thread {
|
suspend fun saveRecording(recorder: RecorderModel, cleanupOldFiles: Boolean = false): Thread {
|
||||||
isProcessing = true
|
isProcessing = true
|
||||||
|
|
||||||
// Give the user some time to see the processing dialog
|
// Give the user some time to see the processing dialog
|
||||||
@ -217,7 +217,7 @@ fun RecorderEventsHandler(
|
|||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
Log.getStackTraceString(error)
|
Log.getStackTraceString(error)
|
||||||
} finally {
|
} finally {
|
||||||
recorder.recorderService?.unlockFiles()
|
recorder.recorderService?.unlockFiles(cleanupOldFiles)
|
||||||
isProcessing = false
|
isProcessing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,14 +226,14 @@ fun RecorderEventsHandler(
|
|||||||
|
|
||||||
// Register audio recorder events
|
// Register audio recorder events
|
||||||
DisposableEffect(key1 = audioRecorder, key2 = settings) {
|
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
|
// We create our own coroutine because we show our own dialog and we want to
|
||||||
// keep saving until it's finished.
|
// keep saving until it's finished.
|
||||||
// So it's smarter to take things into our own hands and use our local coroutine,
|
// 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
|
// instead of hoping that the coroutine from where this will be called will be alive
|
||||||
// until the end of the saving process
|
// until the end of the saving process
|
||||||
scope.launch {
|
scope.launch {
|
||||||
saveRecording(audioRecorder as RecorderModel).join()
|
saveRecording(audioRecorder as RecorderModel, cleanupOldFiles).join()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audioRecorder.onRecordingStart = {
|
audioRecorder.onRecordingStart = {
|
||||||
@ -269,14 +269,14 @@ fun RecorderEventsHandler(
|
|||||||
|
|
||||||
// Register video recorder events
|
// Register video recorder events
|
||||||
DisposableEffect(key1 = videoRecorder, key2 = settings) {
|
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
|
// We create our own coroutine because we show our own dialog and we want to
|
||||||
// keep saving until it's finished.
|
// keep saving until it's finished.
|
||||||
// So it's smarter to take things into our own hands and use our local coroutine,
|
// 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
|
// instead of hoping that the coroutine from where this will be called will be alive
|
||||||
// until the end of the saving process
|
// until the end of the saving process
|
||||||
scope.launch {
|
scope.launch {
|
||||||
saveRecording(videoRecorder as RecorderModel).join()
|
saveRecording(videoRecorder as RecorderModel, cleanupOldFiles).join()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
videoRecorder.onRecordingStart = {
|
videoRecorder.onRecordingStart = {
|
||||||
|
@ -219,7 +219,7 @@ fun _PrimitiveControls(videoRecorder: VideoRecorderModel) {
|
|||||||
videoRecorder.pauseRecording()
|
videoRecorder.pauseRecording()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSave = {
|
onSaveAndStop = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
videoRecorder.stopRecording(context)
|
videoRecorder.stopRecording(context)
|
||||||
|
|
||||||
@ -227,12 +227,15 @@ fun _PrimitiveControls(videoRecorder: VideoRecorderModel) {
|
|||||||
it.saveLastRecording(videoRecorder as RecorderModel)
|
it.saveLastRecording(videoRecorder as RecorderModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
videoRecorder.onRecordingSave().join()
|
videoRecorder.onRecordingSave(false).join()
|
||||||
|
|
||||||
runCatching {
|
runCatching {
|
||||||
videoRecorder.destroyService(context)
|
videoRecorder.destroyService(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onSaveCurrent = {
|
||||||
|
//TODO
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ abstract class BaseRecorderModel<I, B : BatchesFolder, T : IntervalRecorderServi
|
|||||||
|
|
||||||
// If `isSavingAsOldRecording` is true, the user is saving an old recording,
|
// 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
|
// 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")
|
throw NotImplementedError("onRecordingSave not implemented")
|
||||||
}
|
}
|
||||||
var onRecordingStart: () -> Unit = {}
|
var onRecordingStart: () -> Unit = {}
|
||||||
|
@ -120,10 +120,10 @@ fun RecorderScreen(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
when (settings.lastRecording!!.type) {
|
when (settings.lastRecording!!.type) {
|
||||||
RecordingInformation.Type.AUDIO ->
|
RecordingInformation.Type.AUDIO ->
|
||||||
audioRecorder.onRecordingSave()
|
audioRecorder.onRecordingSave(false)
|
||||||
|
|
||||||
RecordingInformation.Type.VIDEO ->
|
RecordingInformation.Type.VIDEO ->
|
||||||
videoRecorder.onRecordingSave()
|
videoRecorder.onRecordingSave(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user