From 7d83bca1fe7e05b25423efbe81a1f351455867ae Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 23 Mar 2024 13:44:53 +0100 Subject: [PATCH] fix: Properly concatenate in own thread wait for end properly Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../alibi/services/VideoRecorderService.kt | 2 +- .../organisms/RecorderEventsHandler.kt | 34 +++++++------------ .../alibi/ui/models/BaseRecorderModel.kt | 4 +-- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt index 06bcac8..4cfc641 100644 --- a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt +++ b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt @@ -132,7 +132,7 @@ class VideoRecorderService : _videoFinalizerListener = CompletableDeferred() 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) } } 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 688a33a..1737023 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 @@ -30,7 +30,7 @@ import app.myzel394.alibi.ui.models.AudioRecorderModel import app.myzel394.alibi.ui.models.BaseRecorderModel import app.myzel394.alibi.ui.models.VideoRecorderModel import app.myzel394.alibi.ui.utils.rememberFileSaverDialog -import kotlinx.coroutines.delay +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking 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 { isProcessing = true - // Give the user some time to see the processing dialog - delay(100) + val completer = CompletableDeferred() - return thread { + thread { runBlocking { try { if (recorder.isCurrentlyActivelyRecording) { @@ -230,22 +232,19 @@ fun RecorderEventsHandler( recorder.recorderService?.unlockFiles(cleanupOldFiles) } isProcessing = false + processingProgress = null + completer.complete(Unit) } } } + + return completer } // Register audio recorder events DisposableEffect(key1 = audioRecorder, key2 = settings) { 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, cleanupOldFiles).join() - } + saveRecording(audioRecorder as RecorderModel, cleanupOldFiles) } audioRecorder.onRecordingStart = { snackbarHostState.currentSnackbarData?.dismiss() @@ -288,14 +287,7 @@ fun RecorderEventsHandler( // Register video recorder events DisposableEffect(key1 = videoRecorder, key2 = settings) { 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, cleanupOldFiles).join() - } + saveRecording(videoRecorder as RecorderModel, cleanupOldFiles) } videoRecorder.onRecordingStart = { snackbarHostState.currentSnackbarData?.dismiss() 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 7796849..d625743 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 @@ -17,7 +17,7 @@ import app.myzel394.alibi.helpers.BatchesFolder import app.myzel394.alibi.services.IntervalRecorderService import app.myzel394.alibi.services.RecorderNotificationHelper import app.myzel394.alibi.services.RecorderService -import kotlinx.coroutines.Job +import kotlinx.coroutines.CompletableDeferred import kotlinx.serialization.json.Json abstract class BaseRecorderModel> : @@ -49,7 +49,7 @@ abstract class BaseRecorderModel Job = { + var onRecordingSave: (cleanupOldFiles: Boolean) -> CompletableDeferred = { throw NotImplementedError("onRecordingSave not implemented") } var onRecordingStart: () -> Unit = {}