feat: Add QuickMaxDurationSelector; closes #57

This commit is contained in:
Myzel394 2023-12-15 22:05:04 +01:00
parent f462d5ff50
commit 39895bcd40
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
3 changed files with 153 additions and 13 deletions

View File

@ -0,0 +1,95 @@
package app.myzel394.alibi.ui.components.RecorderScreen.molecules
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.db.AudioRecorderSettings.Companion.EXAMPLE_MAX_DURATIONS
import app.myzel394.alibi.ui.utils.formatDuration
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun QuickMaxDurationSelector(
settings: AppSettings,
onDismiss: () -> Unit,
) {
val scope = rememberCoroutineScope()
val dataStore = LocalContext.current.dataStore
val sheetState = rememberModalBottomSheetState(true)
ModalBottomSheet(
onDismissRequest = onDismiss,
sheetState = sheetState,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
Box(
modifier = Modifier
.widthIn(max = 400.dp)
.padding(16.dp),
) {
Text(
stringResource(R.string.ui_recorder_action_changeMaxDuration_title),
style = MaterialTheme.typography.headlineMedium,
textAlign = TextAlign.Center,
)
}
Column {
for (duration in EXAMPLE_MAX_DURATIONS) {
Button(
onClick = {
scope.launch {
// TODO: Add hide to microphone selection
sheetState.hide()
onDismiss()
}
scope.launch {
dataStore.updateData {
it.setMaxDuration(duration)
}
}
},
colors = ButtonDefaults.textButtonColors(),
modifier = Modifier
.fillMaxWidth()
.height(64.dp),
) {
Text(
formatDuration(duration)
)
}
}
}
Spacer(modifier = Modifier.height(32.dp))
}
}
}

View File

@ -2,7 +2,6 @@ package app.myzel394.alibi.ui.components.RecorderScreen.organisms
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -13,7 +12,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.Button
@ -22,21 +22,28 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import app.myzel394.alibi.R
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.ui.BIG_PRIMARY_BUTTON_SIZE
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.AudioRecordingStart
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.QuickMaxDurationSelector
import app.myzel394.alibi.ui.components.RecorderScreen.molecules.VideoRecordingStart
import app.myzel394.alibi.ui.effects.rememberForceUpdateOnLifeCycleChange
import app.myzel394.alibi.ui.models.AudioRecorderModel
@ -125,18 +132,51 @@ fun StartRecording(
.size(24.dp)
)
Text(
stringResource(
R.string.ui_audioRecorder_action_start_description,
appSettings.maxDuration / 1000 / 60
),
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
),
val label = stringResource(
R.string.ui_audioRecorder_action_start_description_2,
appSettings.maxDuration / 1000 / 60
)
val annotatedDescription = buildAnnotatedString {
append(stringResource(R.string.ui_audioRecorder_action_start_description_1))
withStyle(SpanStyle(background = MaterialTheme.colorScheme.surfaceVariant)) {
pushStringAnnotation(
tag = "minutes",
annotation = label,
)
append(label)
}
append(stringResource(R.string.ui_audioRecorder_action_start_description_3))
}
var showQuickMaxDurationSelector by rememberSaveable {
mutableStateOf(false)
}
if (showQuickMaxDurationSelector) {
QuickMaxDurationSelector(
settings = appSettings,
onDismiss = {
showQuickMaxDurationSelector = false
},
)
}
ClickableText(
text = annotatedDescription,
onClick = { textIndex ->
if (annotatedDescription.getStringAnnotations(textIndex, textIndex)
.firstOrNull()?.tag == "minutes"
) {
showQuickMaxDurationSelector = true
}
},
modifier = Modifier
.widthIn(max = 300.dp)
.fillMaxWidth(),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
),
)
}
}

View File

@ -26,7 +26,11 @@
<string name="ui_audioRecorder_action_pause_label">Pause</string>
<string name="ui_audioRecorder_action_resume_label">Resume</string>
<string name="ui_audioRecorder_action_save_label">Save Recording</string>
<string name="ui_audioRecorder_action_start_description">Alibi will continue recording in the background and store the last <xliff:g name="durationInMinutes">%s</xliff:g> minutes at your request</string>
<string name="ui_audioRecorder_action_start_description_1">Alibi will continue recording in the background and store the last\u0020</string>
<string name="ui_audioRecorder_action_start_description_2"><xliff:g name="durationInMinutes">%s</xliff:g> minutes</string>
<string name="ui_audioRecorder_action_start_description_3">\u0020at your request</string>
<string name="ui_audioRecorder_action_save_processing_dialog_title">Processing</string>
<string name="ui_audioRecorder_action_save_processing_dialog_description">Processing your recording, do not close Alibi! You will automatically be prompted to save the file once it\'s ready</string>
@ -151,4 +155,5 @@
<string name="ui_videoRecorder_action_torch_off">Disable Torch</string>
<string name="ui_videoRecorder_action_torch_on">Enable Torch</string>
<string name="ui_videoRecorder_action_configure_label">Press long for configuration</string>
<string name="ui_recorder_action_changeMaxDuration_title">When stopped, save the last...</string>
</resources>