feat: Add TimeSettingsPage

Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
Myzel394 2024-03-21 22:36:48 +01:00
parent 5cdbb605f2
commit 6687b173a5
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
7 changed files with 237 additions and 19 deletions

View File

@ -31,7 +31,7 @@ data class AppSettings(
/// Recording information
// 30 minutes
val maxDuration: Long = 30 * 60 * 1000L,
val maxDuration: Long = 15 * 60 * 1000L,
// 60 seconds
val intervalDuration: Long = 60 * 1000L,

View File

@ -0,0 +1,98 @@
package app.myzel394.alibi.ui.components.WelcomeScreen.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.rememberCoroutineScope
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.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import kotlinx.coroutines.launch
const val MINUTES_5 = 1000 * 60 * 5L
const val MINUTES_15 = 1000 * 60 * 15L
const val MINUTES_30 = 1000 * 60 * 30L
const val HOURS_1 = 1000 * 60 * 60L
@Composable
fun TimeSelector(
modifier: Modifier = Modifier,
) {
val OPTIONS = mapOf<Long, String>(
MINUTES_5 to stringResource(R.string.ui_welcome_timeSettings_values_5min),
MINUTES_15 to stringResource(R.string.ui_welcome_timeSettings_values_15min),
MINUTES_30 to stringResource(R.string.ui_welcome_timeSettings_values_30min),
HOURS_1 to stringResource(R.string.ui_welcome_timeSettings_values_1hour),
)
val scope = rememberCoroutineScope()
val dataStore = LocalContext.current.dataStore
var selectedDuration by rememberSaveable { mutableLongStateOf(MINUTES_15) };
// Make sure appSettings is updated properly
LaunchedEffect(selectedDuration) {
scope.launch {
dataStore.updateData {
it.setMaxDuration(selectedDuration)
}
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.clip(MaterialTheme.shapes.medium)
.background(MaterialTheme.colorScheme.surfaceContainer)
.then(modifier),
verticalArrangement = Arrangement.Center,
) {
for ((duration, label) in OPTIONS) {
val a11yLabel = stringResource(
R.string.ui_welcome_timeSettings_selectTime,
label
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.fillMaxWidth()
.clip(MaterialTheme.shapes.medium)
.semantics {
contentDescription = a11yLabel
}
.clickable {
selectedDuration = duration
}
.padding(16.dp)
) {
RadioButton(
selected = selectedDuration == duration,
onClick = { selectedDuration = duration },
)
Text(label)
}
}
}
}

View File

@ -1,4 +1,4 @@
package app.myzel394.alibi.ui.components.WelcomeScreen.atoms
package app.myzel394.alibi.ui.components.WelcomeScreen.pages
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column

View File

@ -1,4 +1,4 @@
package app.myzel394.alibi.ui.components.WelcomeScreen.atoms
package app.myzel394.alibi.ui.components.WelcomeScreen.pages
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
@ -59,7 +59,7 @@ fun ResponsibilityPage(
}
Spacer(modifier = Modifier.weight(1f))
Button(
onClick = { onContinue() },
onClick = onContinue,
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
@ -67,12 +67,12 @@ fun ResponsibilityPage(
contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
) {
Icon(
Icons.Default.Check,
Icons.Default.ChevronRight,
contentDescription = null,
modifier = Modifier.size(ButtonDefaults.IconSize)
)
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.ui_welcome_start_label))
Text(stringResource(R.string.continue_label))
}
}
}

View File

@ -0,0 +1,100 @@
package app.myzel394.alibi.ui.components.WelcomeScreen.pages
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
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.material.icons.Icons
import androidx.compose.material.icons.filled.AccessTime
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.myzel394.alibi.R
import app.myzel394.alibi.ui.BIG_PRIMARY_BUTTON_SIZE
import app.myzel394.alibi.ui.components.WelcomeScreen.atoms.TimeSelector
import app.myzel394.alibi.ui.components.atoms.MessageBox
import app.myzel394.alibi.ui.components.atoms.MessageType
import app.myzel394.alibi.ui.components.atoms.VisualDensity
@Composable
fun TimeSettingsPage(
onContinue: () -> Unit,
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.weight(1f))
Column(
modifier = Modifier
.padding(horizontal = 32.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
Icons.Default.AccessTime,
contentDescription = null,
tint = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.size(128.dp),
)
Spacer(modifier = Modifier.height(32.dp))
Text(
stringResource(R.string.ui_welcome_timeSettings_title),
style = MaterialTheme.typography.titleLarge,
)
Spacer(modifier = Modifier.height(16.dp))
Text(
stringResource(R.string.ui_welcome_timeSettings_message),
)
}
Spacer(modifier = Modifier.weight(2f))
Box(
modifier = Modifier.widthIn(max = 400.dp)
) {
TimeSelector()
}
Spacer(modifier = Modifier.weight(1f))
Box(
modifier = Modifier.widthIn(max = 400.dp)
) {
MessageBox(
type = MessageType.INFO,
message = stringResource(R.string.ui_welcome_timeSettings_changeableHint),
density = VisualDensity.DENSE,
)
}
Spacer(modifier = Modifier.weight(2f))
Button(
onClick = { onContinue() },
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.height(BIG_PRIMARY_BUTTON_SIZE),
contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
) {
Icon(
Icons.Default.ChevronRight,
contentDescription = null,
modifier = Modifier.size(ButtonDefaults.IconSize)
)
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.continue_label))
}
}
}

View File

@ -13,11 +13,10 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavController
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.ui.components.WelcomeScreen.atoms.ExplanationPage
import app.myzel394.alibi.ui.components.WelcomeScreen.atoms.ResponsibilityPage
import app.myzel394.alibi.ui.enums.Screen
import app.myzel394.alibi.ui.components.WelcomeScreen.pages.ExplanationPage
import app.myzel394.alibi.ui.components.WelcomeScreen.pages.ResponsibilityPage
import app.myzel394.alibi.ui.components.WelcomeScreen.pages.TimeSettingsPage
import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class)
@ -35,31 +34,44 @@ fun WelcomeScreen(
val pagerState = rememberPagerState(
initialPage = 0,
initialPageOffsetFraction = 0f,
pageCount = {2}
pageCount = { 4 }
)
Scaffold() {padding ->
fun finishTutorial() {
scope.launch {
dataStore.updateData {
settings.setHasSeenOnboarding(true)
}
onNavigateToAudioRecorderScreen()
}
}
Scaffold() { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding),
horizontalAlignment = Alignment.CenterHorizontally,
) {
HorizontalPager(state = pagerState) {position ->
HorizontalPager(state = pagerState) { position ->
when (position) {
0 -> ExplanationPage(
onContinue = {
scope.launch {
pagerState.animateScrollToPage(2)
pagerState.animateScrollToPage(1)
}
}
)
1 -> ResponsibilityPage {
scope.launch {
dataStore.updateData {
settings.setHasSeenOnboarding(true)
}
onNavigateToAudioRecorderScreen()
pagerState.animateScrollToPage(2)
}
}
2 -> TimeSettingsPage {
scope.launch {
pagerState.animateScrollToPage(3)
}
}
}

View File

@ -195,4 +195,12 @@
<string name="ui_recorder_action_saveCurrent_explanation">You can save the current ongoing recording by pressing and holding down on the save button. The recording will continue in the background.</string>
<string name="ui_recorder_lowOnStorage_hint">You are low on storage. Alibi may not function properly. Please free up some space.</string>
<string name="ui_recorder_lowOnStorage_hintANDswitchSaveFolder">You are low on storage. Alibi may not function properly. Please free up some space. Alternatively, change the batches folder to a different location in the settings.</string>
<string name="ui_welcome_timeSettings_title">How long should Alibi remember?</string>
<string name="ui_welcome_timeSettings_message">Alibi will continuously record and delete old recordings to make space for new ones. You decide how long Alibi should remember the past.</string>
<string name="ui_welcome_timeSettings_values_5min">5 Minutes</string>
<string name="ui_welcome_timeSettings_values_15min">15 minutes</string>
<string name="ui_welcome_timeSettings_values_30min">30 minutes</string>
<string name="ui_welcome_timeSettings_values_1hour">1 hour</string>
<string name="ui_welcome_timeSettings_selectTime">Select %s</string>
<string name="ui_welcome_timeSettings_changeableHint">You can change this anytime</string>
</resources>