mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-19 07:15:25 +02:00
feat: Add MaxDurationTile
This commit is contained in:
parent
df137be466
commit
f045e6f610
@ -27,6 +27,7 @@ data class AppSettings(
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class AudioRecorderSettings(
|
data class AudioRecorderSettings(
|
||||||
|
val maxDuration: Long = 30 * 60 * 1000L,
|
||||||
// 60 seconds
|
// 60 seconds
|
||||||
val intervalDuration: Long = 60 * 1000L,
|
val intervalDuration: Long = 60 * 1000L,
|
||||||
// 320 Kbps
|
// 320 Kbps
|
||||||
@ -59,24 +60,15 @@ data class AudioRecorderSettings(
|
|||||||
else
|
else
|
||||||
MediaRecorder.AudioEncoder.AMR_NB
|
MediaRecorder.AudioEncoder.AMR_NB
|
||||||
|
|
||||||
fun getFileExtensions(): String =
|
|
||||||
when(getOutputFormat()) {
|
|
||||||
MediaRecorder.OutputFormat.AAC_ADTS -> "aac"
|
|
||||||
MediaRecorder.OutputFormat.THREE_GPP -> "3gp"
|
|
||||||
MediaRecorder.OutputFormat.MPEG_4 -> "mp4"
|
|
||||||
MediaRecorder.OutputFormat.MPEG_2_TS -> "ts"
|
|
||||||
MediaRecorder.OutputFormat.WEBM -> "webm"
|
|
||||||
MediaRecorder.OutputFormat.AMR_NB -> "amr"
|
|
||||||
MediaRecorder.OutputFormat.AMR_WB -> "awb"
|
|
||||||
MediaRecorder.OutputFormat.OGG -> "ogg"
|
|
||||||
else -> "raw"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIntervalDuration(duration: Long): AudioRecorderSettings {
|
fun setIntervalDuration(duration: Long): AudioRecorderSettings {
|
||||||
if (duration < 30 * 1000L || duration > 60 * 60 * 1000L) {
|
if (duration < 30 * 1000L || duration > 60 * 60 * 1000L) {
|
||||||
throw Exception("Interval duration must be between 30 seconds and 1 hour")
|
throw Exception("Interval duration must be between 30 seconds and 1 hour")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (duration > maxDuration) {
|
||||||
|
throw Exception("Interval duration must be less than max duration")
|
||||||
|
}
|
||||||
|
|
||||||
return copy(intervalDuration = duration)
|
return copy(intervalDuration = duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +105,27 @@ data class AudioRecorderSettings(
|
|||||||
return copy(encoder = encoder)
|
return copy(encoder = encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setMaxDuration(duration: Long): AudioRecorderSettings {
|
||||||
|
if (duration < 60 * 1000L || duration > 60 * 60 * 1000L) {
|
||||||
|
throw Exception("Max duration must be between 1 minute and 1 hour")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duration < intervalDuration) {
|
||||||
|
throw Exception("Max duration must be greater than interval duration")
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy(maxDuration = duration)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
fun getDefaultInstance(): AudioRecorderSettings = AudioRecorderSettings()
|
||||||
|
val EXAMPLE_MAX_DURATIONS = listOf(
|
||||||
|
15 * 60 * 1000L,
|
||||||
|
30 * 60 * 1000L,
|
||||||
|
60 * 60 * 1000L,
|
||||||
|
2 * 60 * 60 * 1000L,
|
||||||
|
3 * 60 * 60 * 1000L,
|
||||||
|
)
|
||||||
val EXAMPLE_DURATION_TIMES = listOf(
|
val EXAMPLE_DURATION_TIMES = listOf(
|
||||||
60 * 1000L,
|
60 * 1000L,
|
||||||
60 * 5 * 1000L,
|
60 * 5 * 1000L,
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
package app.myzel394.locationtest.ui.components.SettingsScreen.atoms
|
||||||
|
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Mic
|
||||||
|
import androidx.compose.material.icons.filled.Timer
|
||||||
|
import androidx.compose.material.icons.filled.Tune
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.dataStore
|
||||||
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
|
import app.myzel394.locationtest.ui.components.atoms.ExampleListRoulette
|
||||||
|
import app.myzel394.locationtest.ui.components.atoms.SettingsTile
|
||||||
|
import app.myzel394.locationtest.ui.utils.formatDuration
|
||||||
|
import com.maxkeppeker.sheets.core.models.base.IconSource
|
||||||
|
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
|
||||||
|
import com.maxkeppeler.sheets.input.InputDialog
|
||||||
|
import com.maxkeppeler.sheets.input.models.InputHeader
|
||||||
|
import com.maxkeppeler.sheets.input.models.InputSelection
|
||||||
|
import com.maxkeppeler.sheets.input.models.InputTextField
|
||||||
|
import com.maxkeppeler.sheets.input.models.InputTextFieldType
|
||||||
|
import com.maxkeppeler.sheets.input.models.ValidationResult
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun MaxDurationTile() {
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val showDialog = rememberUseCaseState()
|
||||||
|
val dataStore = LocalContext.current.dataStore
|
||||||
|
val settings = dataStore
|
||||||
|
.data
|
||||||
|
.collectAsState(initial = AppSettings.getDefaultInstance())
|
||||||
|
.value
|
||||||
|
|
||||||
|
fun updateValue(maxDuration: Long) {
|
||||||
|
scope.launch {
|
||||||
|
dataStore.updateData {
|
||||||
|
it.setAudioRecorderSettings(
|
||||||
|
it.audioRecorderSettings.setMaxDuration(maxDuration)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDialog(
|
||||||
|
state = showDialog,
|
||||||
|
selection = InputSelection(
|
||||||
|
input = listOf(
|
||||||
|
InputTextField(
|
||||||
|
header = InputHeader(
|
||||||
|
title = "Set the maximum duration",
|
||||||
|
icon = IconSource(Icons.Default.Timer),
|
||||||
|
),
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = KeyboardType.Number,
|
||||||
|
),
|
||||||
|
type = InputTextFieldType.OUTLINED,
|
||||||
|
text = settings.audioRecorderSettings.maxDuration.toString(),
|
||||||
|
validationListener = { text ->
|
||||||
|
val maxDuration = text?.toLongOrNull()
|
||||||
|
|
||||||
|
if (maxDuration == null) {
|
||||||
|
ValidationResult.Invalid("Please enter a valid number")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDuration !in (60 * 1000L)..(60 * 60 * 1000L)) {
|
||||||
|
ValidationResult.Invalid("Please enter a number between 1 minute and 1 hour")
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult.Valid
|
||||||
|
},
|
||||||
|
key = "maxDuration",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
) { result ->
|
||||||
|
val maxDuration = result.getString("maxDuration")?.toLongOrNull() ?: throw IllegalStateException("Invalid maxDuration")
|
||||||
|
|
||||||
|
updateValue(maxDuration)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
SettingsTile(
|
||||||
|
title = "Max duration",
|
||||||
|
description = "Set the maximum duration of the recording",
|
||||||
|
leading = {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Timer,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailing = {
|
||||||
|
Button(
|
||||||
|
onClick = showDialog::show,
|
||||||
|
colors = ButtonDefaults.filledTonalButtonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||||
|
),
|
||||||
|
shape = MaterialTheme.shapes.medium,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = formatDuration(settings.audioRecorderSettings.maxDuration),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extra = {
|
||||||
|
ExampleListRoulette(
|
||||||
|
items = AudioRecorderSettings.EXAMPLE_MAX_DURATIONS,
|
||||||
|
onItemSelected = ::updateValue,
|
||||||
|
) {maxDuration ->
|
||||||
|
Text(
|
||||||
|
text = formatDuration(maxDuration),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user