mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add i18n
This commit is contained in:
parent
46f74e8a8b
commit
a8cb592632
@ -13,8 +13,10 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.services.RecorderService
|
import app.myzel394.locationtest.services.RecorderService
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -27,10 +29,10 @@ fun ConfirmDeletionDialog(
|
|||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
title = {
|
title = {
|
||||||
Text("Delete Recording?")
|
Text(stringResource(R.string.ui_audioRecorder_action_delete_confirm_title))
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
Text("Are you sure you want to delete this recording?")
|
Text(stringResource(R.string.ui_audioRecorder_action_delete_confirm_message))
|
||||||
},
|
},
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
Icon(
|
||||||
@ -39,10 +41,11 @@ fun ConfirmDeletionDialog(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
|
val label = stringResource(R.string.ui_audioRecorder_action_delete_label)
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = "Confirm Recording Deletion"
|
contentDescription = label
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
onConfirm()
|
onConfirm()
|
||||||
@ -54,14 +57,15 @@ fun ConfirmDeletionDialog(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Delete")
|
Text(label)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
|
val label = stringResource(R.string.dialog_close_cancel_label)
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = "Cancel Recording Deletion"
|
contentDescription = label
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
onDismiss()
|
onDismiss()
|
||||||
@ -74,7 +78,7 @@ fun ConfirmDeletionDialog(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Cancel")
|
Text(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -33,9 +33,11 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.services.RecorderService
|
import app.myzel394.locationtest.services.RecorderService
|
||||||
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.ConfirmDeletionDialog
|
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.ConfirmDeletionDialog
|
||||||
@ -124,10 +126,11 @@ fun RecordingStatus(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val label = stringResource(R.string.ui_audioRecorder_action_delete_label)
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = "Delete Recording"
|
contentDescription = label
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
showDeleteDialog = true
|
showDeleteDialog = true
|
||||||
@ -140,16 +143,17 @@ fun RecordingStatus(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Delete")
|
Text(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val label = stringResource(R.string.ui_audioRecorder_action_save_label)
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(BIG_PRIMARY_BUTTON_SIZE)
|
.height(BIG_PRIMARY_BUTTON_SIZE)
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = "Save Recording"
|
contentDescription = label
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
RecorderService.stopService(context)
|
RecorderService.stopService(context)
|
||||||
@ -163,7 +167,7 @@ fun RecordingStatus(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Save Recording")
|
Text(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,17 +25,18 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.services.RecorderService
|
import app.myzel394.locationtest.services.RecorderService
|
||||||
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.AudioVisualizer
|
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.AudioVisualizer
|
||||||
import app.myzel394.locationtest.ui.components.atoms.PermissionRequester
|
import app.myzel394.locationtest.ui.components.atoms.PermissionRequester
|
||||||
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.time.format.FormatStyle
|
||||||
val VISUALIZER_HEIGHT = 200.dp
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StartRecording(
|
fun StartRecording(
|
||||||
@ -66,13 +67,14 @@ fun StartRecording(
|
|||||||
RecorderService.startService(context, connection)
|
RecorderService.startService(context, connection)
|
||||||
},
|
},
|
||||||
) { trigger ->
|
) { trigger ->
|
||||||
|
val label = stringResource(R.string.ui_audioRecorder_action_start_label)
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
trigger()
|
trigger()
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.semantics {
|
.semantics {
|
||||||
contentDescription = "Start recording"
|
contentDescription = label
|
||||||
}
|
}
|
||||||
.size(200.dp)
|
.size(200.dp)
|
||||||
.clip(shape = CircleShape),
|
.clip(shape = CircleShape),
|
||||||
@ -89,7 +91,7 @@ fun StartRecording(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.height(ButtonDefaults.IconSpacing))
|
||||||
Text(
|
Text(
|
||||||
"Start Recording",
|
label,
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -124,7 +126,12 @@ fun StartRecording(
|
|||||||
.size(ButtonDefaults.IconSize),
|
.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Save Recording from ${service.recordingStart!!.format(DateTimeFormatter.ISO_DATE_TIME)}")
|
Text(
|
||||||
|
stringResource(
|
||||||
|
R.string.ui_audioRecorder_action_saveOldRecording_label,
|
||||||
|
DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(service.recordingStart!!),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -17,8 +17,10 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -55,13 +57,15 @@ fun BitrateTile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val notNumberLabel = stringResource(R.string.form_error_type_notNumber)
|
||||||
|
val notInRangeLabel = stringResource(R.string.form_error_value_notInRange, 1, 320)
|
||||||
InputDialog(
|
InputDialog(
|
||||||
state = showDialog,
|
state = showDialog,
|
||||||
selection = InputSelection(
|
selection = InputSelection(
|
||||||
input = listOf(
|
input = listOf(
|
||||||
InputTextField(
|
InputTextField(
|
||||||
header = InputHeader(
|
header = InputHeader(
|
||||||
title = "Set the bitrate for the audio recording",
|
title = stringResource(id = R.string.ui_settings_option_bitrate_explanation),
|
||||||
icon = IconSource(Icons.Default.Tune),
|
icon = IconSource(Icons.Default.Tune),
|
||||||
),
|
),
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
@ -73,14 +77,14 @@ fun BitrateTile() {
|
|||||||
val bitRate = text?.toIntOrNull()
|
val bitRate = text?.toIntOrNull()
|
||||||
|
|
||||||
if (bitRate == null) {
|
if (bitRate == null) {
|
||||||
ValidationResult.Invalid("Please enter a valid number")
|
ValidationResult.Invalid(notNumberLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitRate in 1..320) {
|
if (bitRate !in 1..320) {
|
||||||
ValidationResult.Valid
|
ValidationResult.Invalid(notInRangeLabel)
|
||||||
} else {
|
|
||||||
ValidationResult.Invalid("Please enter a number between 1 and 320")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValidationResult.Valid
|
||||||
},
|
},
|
||||||
key = "bitrate",
|
key = "bitrate",
|
||||||
)
|
)
|
||||||
@ -92,8 +96,8 @@ fun BitrateTile() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Bitrate",
|
title = stringResource(R.string.ui_settings_option_bitrate_title),
|
||||||
description = "A higher bitrate means better quality but also larger file size",
|
description = stringResource(R.string.ui_settings_option_bitrate_description),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Tune,
|
Icons.Default.Tune,
|
||||||
@ -109,7 +113,10 @@ fun BitrateTile() {
|
|||||||
shape = MaterialTheme.shapes.medium,
|
shape = MaterialTheme.shapes.medium,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "${settings.audioRecorderSettings.bitRate / 1000} KB/s",
|
stringResource(
|
||||||
|
R.string.format_kbps,
|
||||||
|
settings.audioRecorderSettings.bitRate / 1000,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -119,7 +126,10 @@ fun BitrateTile() {
|
|||||||
onItemSelected = ::updateValue,
|
onItemSelected = ::updateValue,
|
||||||
) {bitRate ->
|
) {bitRate ->
|
||||||
Text(
|
Text(
|
||||||
text = "${bitRate / 1000} KB/s",
|
stringResource(
|
||||||
|
R.string.format_kbps,
|
||||||
|
bitRate / 1000,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -60,7 +62,7 @@ fun EncoderTile() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Encoder",
|
title = stringResource(R.string.ui_settings_option_encoder_title),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Memory,
|
Icons.Default.Memory,
|
||||||
@ -77,7 +79,7 @@ fun EncoderTile() {
|
|||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = if (settings.audioRecorderSettings.encoder == null) {
|
text = if (settings.audioRecorderSettings.encoder == null) {
|
||||||
"Auto"
|
stringResource(R.string.ui_settings_value_auto_label)
|
||||||
} else {
|
} else {
|
||||||
AudioRecorderSettings.ENCODER_INDEX_TEXT_MAP[settings.audioRecorderSettings.encoder]!!
|
AudioRecorderSettings.ENCODER_INDEX_TEXT_MAP[settings.audioRecorderSettings.encoder]!!
|
||||||
}
|
}
|
||||||
@ -89,9 +91,7 @@ fun EncoderTile() {
|
|||||||
items = listOf(null),
|
items = listOf(null),
|
||||||
onItemSelected = ::updateValue,
|
onItemSelected = ::updateValue,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(stringResource(R.string.ui_settings_value_auto_label))
|
||||||
text = "Auto"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -11,6 +11,8 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -42,8 +44,8 @@ fun ForceExactMaxDurationTile() {
|
|||||||
|
|
||||||
|
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Force exact duration",
|
title = stringResource(R.string.ui_settings_option_forceExactDuration_title),
|
||||||
description = "Force to strip the output file to be the exactly specified duration. If this is disabled, the output file may be a bit longer due to batches of audio samples being encoded together.",
|
description = stringResource(R.string.ui_settings_option_forceExactDuration_description),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.GraphicEq,
|
Icons.Default.GraphicEq,
|
||||||
|
@ -17,7 +17,9 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -66,8 +68,8 @@ fun IntervalDurationTile() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Batch duration",
|
title = stringResource(R.string.ui_settings_option_intervalDuration_title),
|
||||||
description = "Record a single batch for this duration. Alibi records multiple batches and deletes the oldest one. When exporting the audio, all batches will be merged together",
|
description = stringResource(R.string.ui_settings_option_intervalDuration_description),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Mic,
|
Icons.Default.Mic,
|
||||||
|
@ -18,8 +18,10 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -74,8 +76,8 @@ fun MaxDurationTile() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Max duration",
|
title = stringResource(R.string.ui_settings_option_maxDuration_title),
|
||||||
description = "Set the maximum duration of the recording",
|
description = stringResource(R.string.ui_settings_option_maxDuration_description),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Timer,
|
Icons.Default.Timer,
|
||||||
|
@ -15,7 +15,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -70,7 +72,7 @@ fun OutputFormatTile() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Output Format",
|
title = stringResource(R.string.ui_settings_option_outputFormat_title),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.AudioFile,
|
Icons.Default.AudioFile,
|
||||||
@ -87,7 +89,7 @@ fun OutputFormatTile() {
|
|||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = if (settings.audioRecorderSettings.outputFormat == null) {
|
text = if (settings.audioRecorderSettings.outputFormat == null) {
|
||||||
"Auto"
|
stringResource(R.string.ui_settings_value_auto_label)
|
||||||
} else {
|
} else {
|
||||||
AudioRecorderSettings.OUTPUT_FORMAT_INDEX_TEXT_MAP[settings.audioRecorderSettings.outputFormat]!!
|
AudioRecorderSettings.OUTPUT_FORMAT_INDEX_TEXT_MAP[settings.audioRecorderSettings.outputFormat]!!
|
||||||
}
|
}
|
||||||
@ -99,9 +101,7 @@ fun OutputFormatTile() {
|
|||||||
items = listOf(null),
|
items = listOf(null),
|
||||||
onItemSelected = ::updateValue,
|
onItemSelected = ::updateValue,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(stringResource(R.string.ui_settings_value_auto_label))
|
||||||
text = "Auto"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -50,13 +52,15 @@ fun SamplingRateTile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val notNumberLabel = stringResource(R.string.form_error_type_notNumber)
|
||||||
|
val mustBeGreaterThanLabel = stringResource(R.string.form_error_value_mustBeGreaterThan, 1000)
|
||||||
InputDialog(
|
InputDialog(
|
||||||
state = showDialog,
|
state = showDialog,
|
||||||
selection = InputSelection(
|
selection = InputSelection(
|
||||||
input = listOf(
|
input = listOf(
|
||||||
InputTextField(
|
InputTextField(
|
||||||
header = InputHeader(
|
header = InputHeader(
|
||||||
title = "Set the sampling rate",
|
title = stringResource(R.string.ui_settings_option_samplingRate_explanation),
|
||||||
icon = IconSource(Icons.Default.RadioButtonChecked),
|
icon = IconSource(Icons.Default.RadioButtonChecked),
|
||||||
),
|
),
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
@ -68,11 +72,11 @@ fun SamplingRateTile() {
|
|||||||
val samplingRate = text?.toIntOrNull()
|
val samplingRate = text?.toIntOrNull()
|
||||||
|
|
||||||
if (samplingRate == null) {
|
if (samplingRate == null) {
|
||||||
ValidationResult.Invalid("Please enter a valid number")
|
ValidationResult.Invalid(notNumberLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samplingRate!! <= 1000) {
|
if (samplingRate!! <= 1000) {
|
||||||
ValidationResult.Invalid("Sampling rate must be greater than 1000")
|
ValidationResult.Invalid(mustBeGreaterThanLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidationResult.Valid
|
ValidationResult.Valid
|
||||||
@ -87,8 +91,8 @@ fun SamplingRateTile() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
SettingsTile(
|
SettingsTile(
|
||||||
title = "Sampling rate",
|
title = stringResource(R.string.ui_settings_option_samplingRate_title),
|
||||||
description = "Define how many samples per second are taken from the audio signal",
|
description = stringResource(R.string.ui_settings_option_samplingRate_description),
|
||||||
leading = {
|
leading = {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.RadioButtonChecked,
|
Icons.Default.RadioButtonChecked,
|
||||||
@ -104,7 +108,7 @@ fun SamplingRateTile() {
|
|||||||
shape = MaterialTheme.shapes.medium,
|
shape = MaterialTheme.shapes.medium,
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = (settings.audioRecorderSettings.samplingRate ?: "Auto").toString()
|
(settings.audioRecorderSettings.samplingRate ?: stringResource(R.string.ui_settings_value_auto_label)).toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -114,7 +118,7 @@ fun SamplingRateTile() {
|
|||||||
onItemSelected = ::updateValue,
|
onItemSelected = ::updateValue,
|
||||||
) {samplingRate ->
|
) {samplingRate ->
|
||||||
Text(
|
Text(
|
||||||
text = (samplingRate ?: "Auto").toString()
|
(samplingRate ?: stringResource(R.string.ui_settings_value_auto_label)).toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -50,12 +52,12 @@ fun ExplanationPage(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
Text(
|
Text(
|
||||||
"Welcome to Alibi!",
|
stringResource(R.string.ui_welcome_explanation_title),
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(
|
Text(
|
||||||
"Alibi is like a dashcam for your phone. It allows you to record your audio continuously and save the last 30 minutes when you need it.",
|
stringResource(R.string.ui_welcome_explanation_message),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
@ -72,7 +74,7 @@ fun ExplanationPage(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize)
|
modifier = Modifier.size(ButtonDefaults.IconSize)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Continue")
|
Text(stringResource(R.string.continue_label))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -48,12 +50,12 @@ fun ResponsibilityPage(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
Text(
|
Text(
|
||||||
"You are solely responsible for the use of this app",
|
stringResource(R.string.ui_welcome_responsibility_title),
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(
|
Text(
|
||||||
"Alibi does not take any responsibility for the use of this app. You are solely responsible. Use it at your own risk.",
|
stringResource(R.string.ui_welcome_responsibility_message),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
@ -70,7 +72,7 @@ fun ResponsibilityPage(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize)
|
modifier = Modifier.size(ButtonDefaults.IconSize)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Start Alibi")
|
Text(stringResource(R.string.ui_welcome_start_label))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,6 @@ import androidx.compose.material.icons.filled.OpenInNew
|
|||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -19,6 +18,8 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.ui.utils.PermissionHelper
|
import app.myzel394.locationtest.ui.utils.PermissionHelper
|
||||||
import app.myzel394.locationtest.ui.utils.openAppSystemSettings
|
import app.myzel394.locationtest.ui.utils.openAppSystemSettings
|
||||||
|
|
||||||
@ -51,10 +52,10 @@ fun PermissionRequester(
|
|||||||
},
|
},
|
||||||
icon = icon,
|
icon = icon,
|
||||||
title = {
|
title = {
|
||||||
Text("Permission denied")
|
Text(stringResource(R.string.ui_permissions_request_title))
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
Text("Please grant the permission to continue. You will be redirected to the app settings to grant the permission there.")
|
Text(stringResource(R.string.ui_permissions_request_message))
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(
|
Button(
|
||||||
@ -69,7 +70,7 @@ fun PermissionRequester(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("OK")
|
Text(stringResource(R.string.dialog_close_neutral_label))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
@ -85,7 +86,7 @@ fun PermissionRequester(
|
|||||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||||
Text("Cancel")
|
Text(stringResource(R.string.dialog_close_cancel_label))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -14,12 +14,14 @@ import androidx.compose.material3.TopAppBar
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import app.myzel394.locationtest.services.bindToRecorderService
|
import app.myzel394.locationtest.services.bindToRecorderService
|
||||||
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.RecordingStatus
|
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.RecordingStatus
|
||||||
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.StartRecording
|
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.StartRecording
|
||||||
import app.myzel394.locationtest.ui.enums.Screen
|
import app.myzel394.locationtest.ui.enums.Screen
|
||||||
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -34,7 +36,7 @@ fun AudioRecorder(
|
|||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text("Alibi")
|
Text(stringResource(R.string.app_name))
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -35,8 +35,10 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import app.myzel394.locationtest.R
|
||||||
import app.myzel394.locationtest.dataStore
|
import app.myzel394.locationtest.dataStore
|
||||||
import app.myzel394.locationtest.db.AppSettings
|
import app.myzel394.locationtest.db.AppSettings
|
||||||
import app.myzel394.locationtest.db.AudioRecorderSettings
|
import app.myzel394.locationtest.db.AudioRecorderSettings
|
||||||
@ -75,7 +77,7 @@ fun SettingsScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
LargeTopAppBar(
|
LargeTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text(text = "Settings")
|
Text(stringResource(R.string.ui_settings_title))
|
||||||
},
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = navController::popBackStack) {
|
IconButton(onClick = navController::popBackStack) {
|
||||||
@ -113,12 +115,12 @@ fun SettingsScreen(
|
|||||||
) {
|
) {
|
||||||
MessageBox(
|
MessageBox(
|
||||||
type = MessageType.WARNING,
|
type = MessageType.WARNING,
|
||||||
title = "You are recording",
|
title = stringResource(R.string.ui_settings_hint_recordingActive_title),
|
||||||
message = "Your changes will be applied the next time you start recording",
|
message = stringResource(R.string.ui_settings_hint_recordingActive_message),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GlobalSwitch(
|
GlobalSwitch(
|
||||||
label = "Advanced Settings",
|
label = stringResource(R.string.ui_settings_advancedSettings_label),
|
||||||
checked = settings.showAdvancedSettings,
|
checked = settings.showAdvancedSettings,
|
||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
@ -1,3 +1,48 @@
|
|||||||
<resources>
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="app_name">LocationTest</string>
|
<string name="app_name">LocationTest</string>
|
||||||
|
<string name="dialog_close_cancel_label">Cancel</string>
|
||||||
|
<string name="dialog_close_neutral_label">OK</string>
|
||||||
|
<string name="continue_label">Continue</string>
|
||||||
|
|
||||||
|
<string name="format_kbps"><xliff:g name="value">%s</xliff:g> KB/s</string>
|
||||||
|
<string name="form_error_type_notNumber">Please enter a valid number</string>
|
||||||
|
<string name="form_error_value_notInRange">Please enter a number between <xliff:g name="min">%s</xliff:g> and <xliff:g name="max">%s</xliff:g></string>
|
||||||
|
<string name="form_error_value_mustBeGreaterThan">Please enter a number greater than <xliff:g name="min">%s</xliff:g></string>
|
||||||
|
|
||||||
|
<string name="ui_permissions_request_title">Permission denied</string>
|
||||||
|
<string name="ui_permissions_request_message">Please grant the permission to continue. You will be redirected to the app settings to grant the permission there.</string>
|
||||||
|
|
||||||
|
<string name="ui_audioRecorder_action_start_label">Start Recording</string>
|
||||||
|
<string name="ui_audioRecorder_action_saveOldRecording_label">Save Recording from <xliff:g name="date">%s</xliff:g></string>
|
||||||
|
<string name="ui_audioRecorder_action_delete_label">Delete</string>
|
||||||
|
<string name="ui_audioRecorder_action_delete_confirm_title">Delete Recording?</string>
|
||||||
|
<string name="ui_audioRecorder_action_delete_confirm_message">Are you sure you want to delete this recording?</string>
|
||||||
|
<string name="ui_audioRecorder_action_save_label">Save Recording</string>
|
||||||
|
|
||||||
|
<string name="ui_welcome_explanation_title">Welcome to Alibi!</string>
|
||||||
|
<string name="ui_welcome_explanation_message">Alibi is like a dashcam for your phone. It allows you to record your audio continuously and save the last 30 minutes when you need it.</string>
|
||||||
|
<string name="ui_welcome_responsibility_title">You are solely responsible for the use of this app</string>
|
||||||
|
<string name="ui_welcome_responsibility_message">Alibi does not take any responsibility for the use of this app. You are solely responsible. Use it at your own risk.</string>
|
||||||
|
<string name="ui_welcome_start_label">Start Alibi</string>
|
||||||
|
|
||||||
|
<string name="ui_settings_title">Settings</string>
|
||||||
|
<string name="ui_settings_advancedSettings_label">Advanced Settings</string>
|
||||||
|
<string name="ui_settings_hint_recordingActive_title">You are recording</string>
|
||||||
|
<string name="ui_settings_hint_recordingActive_message">Your changes will be applied the next time you start recording</string>
|
||||||
|
<string name="ui_settings_option_maxDuration_title">Max duration</string>
|
||||||
|
<string name="ui_settings_option_maxDuration_description">Set the maximum duration of the recording</string>
|
||||||
|
<string name="ui_settings_option_intervalDuration_title">Batch duration</string>
|
||||||
|
<string name="ui_settings_option_intervalDuration_description">Record a single batch for this duration. Alibi records multiple batches and deletes the oldest one. When exporting the audio, all batches will be merged together</string>
|
||||||
|
<string name="ui_settings_option_forceExactDuration_title">Force exact duration</string>
|
||||||
|
<string name="ui_settings_option_forceExactDuration_description">Force to strip the output file to be the exactly specified duration. If this is disabled, the output file may be a bit longer due to batches of audio samples being encoded together.</string>
|
||||||
|
<string name="ui_settings_option_bitrate_title">Bitrate</string>
|
||||||
|
<string name="ui_settings_option_bitrate_description">A higher bitrate means better quality but also larger file size</string>
|
||||||
|
<string name="ui_settings_option_bitrate_explanation">Set the bitrate for the audio recording</string>
|
||||||
|
<string name="ui_settings_option_outputFormat_title">Output Format</string>
|
||||||
|
<string name="ui_settings_value_auto_label">Auto</string>
|
||||||
|
<string name="ui_settings_option_samplingRate_title">Sampling rate</string>
|
||||||
|
<string name="ui_settings_option_samplingRate_description">Define how many samples per second are taken from the audio signal</string>
|
||||||
|
<string name="ui_settings_option_samplingRate_explanation">Set the sampling rate</string>
|
||||||
|
<string name="ui_settings_option_encoder_title">Encoder</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user