fix: Properly concatenate in own thread wait for end properly

Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
Myzel394 2024-03-23 13:44:53 +01:00
parent 24928661c5
commit 7d83bca1fe
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
3 changed files with 16 additions and 24 deletions

View File

@ -132,7 +132,7 @@ class VideoRecorderService :
_videoFinalizerListener = CompletableDeferred() _videoFinalizerListener = CompletableDeferred()
activeRecording = newRecording.start(ContextCompat.getMainExecutor(this)) { event -> activeRecording = newRecording.start(ContextCompat.getMainExecutor(this)) { event ->
if (event is VideoRecordEvent.Finalize && this@VideoRecorderService.state == RecorderState.STOPPED || this@VideoRecorderService.state == RecorderState.PAUSED) { if (event is VideoRecordEvent.Finalize && (this@VideoRecorderService.state == RecorderState.STOPPED || this@VideoRecorderService.state == RecorderState.PAUSED)) {
_videoFinalizerListener.complete(Unit) _videoFinalizerListener.complete(Unit)
} }
} }

View File

@ -30,7 +30,7 @@ import app.myzel394.alibi.ui.models.AudioRecorderModel
import app.myzel394.alibi.ui.models.BaseRecorderModel import app.myzel394.alibi.ui.models.BaseRecorderModel
import app.myzel394.alibi.ui.models.VideoRecorderModel import app.myzel394.alibi.ui.models.VideoRecorderModel
import app.myzel394.alibi.ui.utils.rememberFileSaverDialog import app.myzel394.alibi.ui.utils.rememberFileSaverDialog
import kotlinx.coroutines.delay import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -136,13 +136,15 @@ fun RecorderEventsHandler(
} }
} }
suspend fun saveRecording(recorder: RecorderModel, cleanupOldFiles: Boolean = false): Thread { fun saveRecording(
recorder: RecorderModel,
cleanupOldFiles: Boolean = false
): CompletableDeferred<Unit> {
isProcessing = true isProcessing = true
// Give the user some time to see the processing dialog val completer = CompletableDeferred<Unit>()
delay(100)
return thread { thread {
runBlocking { runBlocking {
try { try {
if (recorder.isCurrentlyActivelyRecording) { if (recorder.isCurrentlyActivelyRecording) {
@ -230,22 +232,19 @@ fun RecorderEventsHandler(
recorder.recorderService?.unlockFiles(cleanupOldFiles) recorder.recorderService?.unlockFiles(cleanupOldFiles)
} }
isProcessing = false isProcessing = false
processingProgress = null
completer.complete(Unit)
} }
} }
} }
return completer
} }
// Register audio recorder events // Register audio recorder events
DisposableEffect(key1 = audioRecorder, key2 = settings) { DisposableEffect(key1 = audioRecorder, key2 = settings) {
audioRecorder.onRecordingSave = { cleanupOldFiles -> audioRecorder.onRecordingSave = { cleanupOldFiles ->
// We create our own coroutine because we show our own dialog and we want to saveRecording(audioRecorder as RecorderModel, cleanupOldFiles)
// 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, cleanupOldFiles).join()
}
} }
audioRecorder.onRecordingStart = { audioRecorder.onRecordingStart = {
snackbarHostState.currentSnackbarData?.dismiss() snackbarHostState.currentSnackbarData?.dismiss()
@ -288,14 +287,7 @@ fun RecorderEventsHandler(
// Register video recorder events // Register video recorder events
DisposableEffect(key1 = videoRecorder, key2 = settings) { DisposableEffect(key1 = videoRecorder, key2 = settings) {
videoRecorder.onRecordingSave = { cleanupOldFiles -> videoRecorder.onRecordingSave = { cleanupOldFiles ->
// We create our own coroutine because we show our own dialog and we want to saveRecording(videoRecorder as RecorderModel, cleanupOldFiles)
// 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, cleanupOldFiles).join()
}
} }
videoRecorder.onRecordingStart = { videoRecorder.onRecordingStart = {
snackbarHostState.currentSnackbarData?.dismiss() snackbarHostState.currentSnackbarData?.dismiss()

View File

@ -17,7 +17,7 @@ import app.myzel394.alibi.helpers.BatchesFolder
import app.myzel394.alibi.services.IntervalRecorderService import app.myzel394.alibi.services.IntervalRecorderService
import app.myzel394.alibi.services.RecorderNotificationHelper import app.myzel394.alibi.services.RecorderNotificationHelper
import app.myzel394.alibi.services.RecorderService import app.myzel394.alibi.services.RecorderService
import kotlinx.coroutines.Job import kotlinx.coroutines.CompletableDeferred
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
abstract class BaseRecorderModel<I, B : BatchesFolder, T : IntervalRecorderService<I, B>> : abstract class BaseRecorderModel<I, B : BatchesFolder, T : IntervalRecorderService<I, B>> :
@ -49,7 +49,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: (cleanupOldFiles: Boolean) -> Job = { var onRecordingSave: (cleanupOldFiles: Boolean) -> CompletableDeferred<Unit> = {
throw NotImplementedError("onRecordingSave not implemented") throw NotImplementedError("onRecordingSave not implemented")
} }
var onRecordingStart: () -> Unit = {} var onRecordingStart: () -> Unit = {}