feat: Add progress bar; Closes #64

This commit is contained in:
Myzel394 2024-01-05 13:43:50 +01:00
parent e8df9fbc28
commit c6932fd31d
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
7 changed files with 51 additions and 23 deletions

View File

@ -253,7 +253,7 @@ abstract class BatchesFolder(
disableCache: Boolean = false, disableCache: Boolean = false,
onNextParameterTry: (String) -> Unit = {}, onNextParameterTry: (String) -> Unit = {},
durationPerBatchInMilliseconds: Long = 0, durationPerBatchInMilliseconds: Long = 0,
onProgress: (Float) -> Unit = {}, onProgress: (Float?) -> Unit = {},
): String { ): String {
if (!disableCache && checkIfOutputAlreadyExists(recordingStart, extension)) { if (!disableCache && checkIfOutputAlreadyExists(recordingStart, extension)) {
return getOutputFileForFFmpeg( return getOutputFileForFFmpeg(
@ -265,6 +265,7 @@ abstract class BatchesFolder(
for (parameter in ffmpegParameters) { for (parameter in ffmpegParameters) {
Log.i("Concatenation", "Trying parameter $parameter") Log.i("Concatenation", "Trying parameter $parameter")
onNextParameterTry(parameter) onNextParameterTry(parameter)
onProgress(null)
try { try {
val filePaths = getBatchesForFFmpeg() val filePaths = getBatchesForFFmpeg()
@ -293,7 +294,13 @@ abstract class BatchesFolder(
parameter parameter
) { time -> ) { time ->
if (fullTime != null) { if (fullTime != null) {
println("**************** check24")
println(time)
println(fullTime)
onProgress(time / fullTime!!) onProgress(time / fullTime!!)
} else {
onProgress(null)
println("----------------- nonono")
} }
}.await() }.await()
return outputFile return outputFile

View File

@ -92,8 +92,6 @@ class MediaConverter {
"-protocol_whitelist saf,concat,content,file,subfile" + "-protocol_whitelist saf,concat,content,file,subfile" +
" -i 'concat:$filePathsConcatenated'" + " -i 'concat:$filePathsConcatenated'" +
extraCommand + extraCommand +
" -nostats" +
" -loglevel error" +
" -y" + " -y" +
" $outputFile" " $outputFile"
@ -150,8 +148,6 @@ class MediaConverter {
" -i ${listFile.absolutePath}" + " -i ${listFile.absolutePath}" +
extraCommand + extraCommand +
" -strict normal" + " -strict normal" +
" -nostats" +
" -loglevel error" +
" -y" + " -y" +
" $outputFile" " $outputFile"

View File

@ -41,10 +41,10 @@ fun RecorderProcessingDialog(
stringResource(R.string.ui_recorder_action_save_processing_dialog_description), stringResource(R.string.ui_recorder_action_save_processing_dialog_description),
) )
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
if (progress != null) if (progress == null)
LinearProgressIndicator(progress = progress)
else
LinearProgressIndicator() LinearProgressIndicator()
else
LinearProgressIndicator(progress = progress)
} }
}, },
confirmButton = {} confirmButton = {}

View File

@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -34,6 +35,10 @@ import app.myzel394.alibi.ui.SUPPORTS_SCOPED_STORAGE
import app.myzel394.alibi.ui.components.atoms.PermissionRequester import app.myzel394.alibi.ui.components.atoms.PermissionRequester
import app.myzel394.alibi.ui.models.AudioRecorderModel import app.myzel394.alibi.ui.models.AudioRecorderModel
import app.myzel394.alibi.ui.utils.PermissionHelper import app.myzel394.alibi.ui.utils.PermissionHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@Composable @Composable
fun AudioRecordingStart( fun AudioRecordingStart(
@ -54,6 +59,17 @@ fun AudioRecordingStart(
} }
} }
println("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww app: ${appSettings.saveFolder}")
val requiresExternalPerm = rememberSaveable {
appSettings.requiresExternalStoragePermission(context)
}
println("hasGranted ${requiresExternalPerm}")
val scope = rememberCoroutineScope()
fun test() {
println("appSäääääääääääääääääääääääääääääääättings ${appSettings.saveFolder}")
}
PermissionRequester( PermissionRequester(
permission = Manifest.permission.WRITE_EXTERNAL_STORAGE, permission = Manifest.permission.WRITE_EXTERNAL_STORAGE,
icon = Icons.Default.InsertDriveFile, icon = Icons.Default.InsertDriveFile,
@ -65,11 +81,8 @@ fun AudioRecordingStart(
permission = Manifest.permission.RECORD_AUDIO, permission = Manifest.permission.RECORD_AUDIO,
icon = Icons.Default.Mic, icon = Icons.Default.Mic,
onPermissionAvailable = { onPermissionAvailable = {
if (!SUPPORTS_SCOPED_STORAGE && !PermissionHelper.hasGranted( test()
context, if (appSettings.requiresExternalStoragePermission(context)) {
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
) {
triggerExternalStorage() triggerExternalStorage()
} else { } else {
startRecording = true startRecording = true

View File

@ -80,11 +80,6 @@ fun VideoRecordingStart(
) )
} }
val hasGrantedStorage = SUPPORTS_SCOPED_STORAGE || PermissionHelper.hasGranted(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
PermissionRequester( PermissionRequester(
permission = Manifest.permission.WRITE_EXTERNAL_STORAGE, permission = Manifest.permission.WRITE_EXTERNAL_STORAGE,
icon = Icons.Default.InsertDriveFile, icon = Icons.Default.InsertDriveFile,
@ -112,7 +107,7 @@ fun VideoRecordingStart(
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(color = MaterialTheme.colorScheme.primary), indication = rememberRipple(color = MaterialTheme.colorScheme.primary),
onClick = { onClick = {
if (!hasGrantedStorage) { if (appSettings.requiresExternalStoragePermission(context)) {
triggerExternalStorage() triggerExternalStorage()
return@combinedClickable return@combinedClickable
} }

View File

@ -58,7 +58,7 @@ fun RecorderEventsHandler(
var showRecorderError by remember { mutableStateOf(false) } var showRecorderError by remember { mutableStateOf(false) }
var showBatchesInaccessibleError by remember { mutableStateOf(false) } var showBatchesInaccessibleError by remember { mutableStateOf(false) }
var processingProgress by remember { mutableFloatStateOf(0.0f) } var processingProgress by remember { mutableStateOf<Float?>(null) }
val saveAudioFile = rememberFileSaverDialog(settings.audioRecorderSettings.getMimeType()) { val saveAudioFile = rememberFileSaverDialog(settings.audioRecorderSettings.getMimeType()) {
if (settings.deleteRecordingsImmediately) { if (settings.deleteRecordingsImmediately) {

View File

@ -24,6 +24,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
@ -45,15 +46,22 @@ fun PermissionRequester(
var isGranted by remember { mutableStateOf(PermissionHelper.hasGranted(context, permission)) } var isGranted by remember { mutableStateOf(PermissionHelper.hasGranted(context, permission)) }
var visibleDialog by remember { mutableStateOf<VisibleDialog?>(null) } var visibleDialog by remember { mutableStateOf<VisibleDialog?>(null) }
var _runFunc by rememberSaveable { mutableStateOf(false) }
val requestPermission = rememberLauncherForActivityResult( val requestPermission = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission(), contract = ActivityResultContracts.RequestPermission(),
onResult = { isPermissionGranted: Boolean -> onResult = { isPermissionGranted: Boolean ->
isGranted = isPermissionGranted isGranted = isPermissionGranted
if (isGranted) { if (isGranted) {
onPermissionAvailable() _runFunc = true
} else { } else {
if (ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, permission)) { if (ActivityCompat.shouldShowRequestPermissionRationale(
context as Activity,
permission
)
) {
visibleDialog = VisibleDialog.REQUEST visibleDialog = VisibleDialog.REQUEST
} else { } else {
visibleDialog = VisibleDialog.PERMANENTLY_DENIED visibleDialog = VisibleDialog.PERMANENTLY_DENIED
@ -64,12 +72,21 @@ fun PermissionRequester(
fun callback() { fun callback() {
if (isGranted) { if (isGranted) {
onPermissionAvailable() _runFunc = true
} else { } else {
requestPermission.launch(permission) requestPermission.launch(permission)
} }
} }
// No idea but this hacky way is required to make sure the callback
// `onPermissionAvailable` can access other values such as the app settings.
LaunchedEffect(_runFunc) {
if (_runFunc) {
_runFunc = false
onPermissionAvailable()
}
}
if (visibleDialog == VisibleDialog.REQUEST) { if (visibleDialog == VisibleDialog.REQUEST) {
AlertDialog( AlertDialog(
onDismissRequest = { onDismissRequest = {