mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
refactor: Move recording save stuff out to audio and video recording statuses component
Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
parent
0a626e5f66
commit
671c8da56a
@ -11,6 +11,7 @@ import app.myzel394.alibi.helpers.AudioBatchesFolder
|
||||
import app.myzel394.alibi.helpers.VideoBatchesFolder
|
||||
import app.myzel394.alibi.ui.RECORDER_MEDIA_SELECTED_VALUE
|
||||
import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.RecorderModel
|
||||
import app.myzel394.alibi.ui.utils.PermissionHelper
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -102,6 +103,16 @@ data class AppSettings(
|
||||
return copy(appLockSettings = appLockSettings)
|
||||
}
|
||||
|
||||
fun saveLastRecording(recorder: RecorderModel): AppSettings {
|
||||
return if (deleteRecordingsImmediately) {
|
||||
this
|
||||
} else {
|
||||
setLastRecording(
|
||||
recorder.recorderService!!.getRecordingInformation()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// If the object is present, biometric authentication is enabled.
|
||||
// To disable biometric authentication, set the instance to null.
|
||||
fun isAppLockEnabled() = appLockSettings != null
|
||||
|
@ -22,6 +22,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.myzel394.alibi.dataStore
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.RealtimeAudioVisualizer
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.MicrophoneStatus
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.RecordingControl
|
||||
@ -39,8 +40,6 @@ fun AudioRecordingStatus(
|
||||
val context = LocalContext.current
|
||||
val configuration = LocalConfiguration.current.orientation
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var now by remember { mutableStateOf(LocalDateTime.now()) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
@ -90,34 +89,7 @@ fun AudioRecordingStatus(
|
||||
MicrophoneStatus(audioRecorder)
|
||||
}
|
||||
|
||||
RecordingControl(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
isPaused = audioRecorder.isPaused,
|
||||
recordingTime = audioRecorder.recordingTime,
|
||||
onDelete = {
|
||||
scope.launch {
|
||||
runCatching {
|
||||
audioRecorder.stopRecording(context)
|
||||
}
|
||||
runCatching {
|
||||
audioRecorder.destroyService(context)
|
||||
}
|
||||
audioRecorder.batchesFolder!!.deleteRecordings()
|
||||
}
|
||||
},
|
||||
onPauseResume = {
|
||||
if (audioRecorder.isPaused) {
|
||||
audioRecorder.resumeRecording()
|
||||
} else {
|
||||
audioRecorder.pauseRecording()
|
||||
}
|
||||
},
|
||||
onSave = {
|
||||
audioRecorder.onRecordingSave(false)
|
||||
}
|
||||
)
|
||||
_PrimitiveControls(audioRecorder)
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,33 +110,54 @@ fun AudioRecordingStatus(
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
RecordingControl(
|
||||
isPaused = audioRecorder.isPaused,
|
||||
recordingTime = audioRecorder.recordingTime,
|
||||
onDelete = {
|
||||
scope.launch {
|
||||
runCatching {
|
||||
audioRecorder.stopRecording(context)
|
||||
}
|
||||
runCatching {
|
||||
audioRecorder.destroyService(context)
|
||||
}
|
||||
audioRecorder.batchesFolder!!.deleteRecordings()
|
||||
}
|
||||
},
|
||||
onPauseResume = {
|
||||
if (audioRecorder.isPaused) {
|
||||
audioRecorder.resumeRecording()
|
||||
} else {
|
||||
audioRecorder.pauseRecording()
|
||||
}
|
||||
},
|
||||
onSave = {
|
||||
audioRecorder.onRecordingSave(false)
|
||||
}
|
||||
)
|
||||
_PrimitiveControls(audioRecorder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun _PrimitiveControls(audioRecorder: AudioRecorderModel) {
|
||||
val context = LocalContext.current
|
||||
val dataStore = context.dataStore
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
RecordingControl(
|
||||
isPaused = audioRecorder.isPaused,
|
||||
recordingTime = audioRecorder.recordingTime,
|
||||
onDelete = {
|
||||
scope.launch {
|
||||
runCatching {
|
||||
audioRecorder.stopRecording(context)
|
||||
}
|
||||
runCatching {
|
||||
audioRecorder.destroyService(context)
|
||||
}
|
||||
audioRecorder.batchesFolder!!.deleteRecordings()
|
||||
}
|
||||
},
|
||||
onPauseResume = {
|
||||
if (audioRecorder.isPaused) {
|
||||
audioRecorder.resumeRecording()
|
||||
} else {
|
||||
audioRecorder.pauseRecording()
|
||||
}
|
||||
},
|
||||
onSave = {
|
||||
scope.launch {
|
||||
audioRecorder.stopRecording(context)
|
||||
|
||||
dataStore.updateData {
|
||||
it.saveLastRecording(audioRecorder as RecorderModel)
|
||||
}
|
||||
|
||||
audioRecorder.onRecordingSave()
|
||||
|
||||
runCatching {
|
||||
audioRecorder.destroyService(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@ -30,7 +30,6 @@ 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.CompletableDeferred
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@ -224,26 +223,15 @@ fun RecorderEventsHandler(
|
||||
|
||||
// Register audio recorder events
|
||||
DisposableEffect(key1 = audioRecorder, key2 = settings) {
|
||||
audioRecorder.onRecordingSave = { justSave ->
|
||||
val completer = CompletableDeferred<Unit>()
|
||||
|
||||
audioRecorder.onRecordingSave = {
|
||||
// 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 {
|
||||
if (justSave) {
|
||||
saveRecording(audioRecorder as RecorderModel)
|
||||
} else {
|
||||
audioRecorder.stopRecording(context)
|
||||
|
||||
saveAsLastRecording(audioRecorder as RecorderModel)
|
||||
|
||||
saveRecording(audioRecorder)
|
||||
|
||||
audioRecorder.destroyService(context)
|
||||
}
|
||||
|
||||
completer.complete(Unit)
|
||||
saveRecording(audioRecorder as RecorderModel)
|
||||
}
|
||||
|
||||
completer
|
||||
}
|
||||
audioRecorder.onRecordingStart = {
|
||||
snackbarHostState.currentSnackbarData?.dismiss()
|
||||
@ -278,26 +266,15 @@ fun RecorderEventsHandler(
|
||||
|
||||
// Register video recorder events
|
||||
DisposableEffect(key1 = videoRecorder, key2 = settings) {
|
||||
videoRecorder.onRecordingSave = { justSave ->
|
||||
val completer = CompletableDeferred<Unit>()
|
||||
|
||||
videoRecorder.onRecordingSave = {
|
||||
// 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 {
|
||||
if (justSave) {
|
||||
saveRecording(videoRecorder as RecorderModel)
|
||||
} else {
|
||||
videoRecorder.stopRecording(context)
|
||||
|
||||
saveAsLastRecording(videoRecorder as RecorderModel)
|
||||
|
||||
saveRecording(videoRecorder)
|
||||
|
||||
videoRecorder.destroyService(context)
|
||||
}
|
||||
|
||||
completer.complete(Unit)
|
||||
saveRecording(videoRecorder as RecorderModel)
|
||||
}
|
||||
|
||||
completer
|
||||
}
|
||||
videoRecorder.onRecordingStart = {
|
||||
snackbarHostState.currentSnackbarData?.dismiss()
|
||||
|
@ -32,6 +32,7 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.myzel394.alibi.R
|
||||
import app.myzel394.alibi.dataStore
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.TorchStatus
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.RecordingControl
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.RecordingStatus
|
||||
@ -189,6 +190,7 @@ fun _VideoRecordingStatus(videoRecorder: VideoRecorderModel) {
|
||||
@Composable
|
||||
fun _PrimitiveControls(videoRecorder: VideoRecorderModel) {
|
||||
val context = LocalContext.current
|
||||
val dataStore = context.dataStore
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
RecordingControl(
|
||||
@ -218,7 +220,19 @@ fun _PrimitiveControls(videoRecorder: VideoRecorderModel) {
|
||||
}
|
||||
},
|
||||
onSave = {
|
||||
videoRecorder.onRecordingSave(false)
|
||||
scope.launch {
|
||||
videoRecorder.stopRecording(context)
|
||||
|
||||
dataStore.updateData {
|
||||
it.saveLastRecording(videoRecorder as RecorderModel)
|
||||
}
|
||||
|
||||
videoRecorder.onRecordingSave()
|
||||
|
||||
runCatching {
|
||||
videoRecorder.destroyService(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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.CompletableDeferred
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
abstract class BaseRecorderModel<I, B : BatchesFolder, T : IntervalRecorderService<I, B>> :
|
||||
@ -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: (isSavingAsOldRecording: Boolean) -> CompletableDeferred<Unit> = {
|
||||
var onRecordingSave: () -> Job = {
|
||||
throw NotImplementedError("onRecordingSave not implemented")
|
||||
}
|
||||
var onRecordingStart: () -> Unit = {}
|
||||
|
@ -16,22 +16,26 @@ import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavController
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.AudioRecordingStatus
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.StartRecording
|
||||
import app.myzel394.alibi.ui.enums.Screen
|
||||
import app.myzel394.alibi.R
|
||||
import app.myzel394.alibi.dataStore
|
||||
import app.myzel394.alibi.db.AppSettings
|
||||
import app.myzel394.alibi.db.RecordingInformation
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.AudioRecordingStatus
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.RecorderEventsHandler
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.StartRecording
|
||||
import app.myzel394.alibi.ui.components.RecorderScreen.organisms.VideoRecordingStatus
|
||||
import app.myzel394.alibi.ui.models.AudioRecorderModel
|
||||
import app.myzel394.alibi.ui.models.VideoRecorderModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -43,6 +47,7 @@ fun RecorderScreen(
|
||||
) {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
RecorderEventsHandler(
|
||||
settings = settings,
|
||||
@ -112,12 +117,14 @@ fun RecorderScreen(
|
||||
videoRecorder = videoRecorder,
|
||||
appSettings = appSettings,
|
||||
onSaveLastRecording = {
|
||||
when (settings.lastRecording!!.type) {
|
||||
RecordingInformation.Type.AUDIO ->
|
||||
audioRecorder.onRecordingSave(true)
|
||||
scope.launch {
|
||||
when (settings.lastRecording!!.type) {
|
||||
RecordingInformation.Type.AUDIO ->
|
||||
audioRecorder.onRecordingSave()
|
||||
|
||||
RecordingInformation.Type.VIDEO ->
|
||||
videoRecorder.onRecordingSave(true)
|
||||
RecordingInformation.Type.VIDEO ->
|
||||
videoRecorder.onRecordingSave()
|
||||
}
|
||||
}
|
||||
},
|
||||
showAudioRecorder = topBarVisible,
|
||||
|
Loading…
x
Reference in New Issue
Block a user