feat: redesign settings screen

This commit is contained in:
2026-05-23 12:55:37 +00:00
parent d81c382ba5
commit ef56db5d16
8 changed files with 109 additions and 31 deletions

View File

@@ -24,12 +24,10 @@ android {
buildTypes { buildTypes {
debug { debug {
applicationIdSuffix = ".debug" applicationIdSuffix = ".debug"
versionCode = providers.gradleProperty("purefinDebugVersionCode").get().toInt()
versionNameSuffix = "-debug" versionNameSuffix = "-debug"
manifestPlaceholders["updateManifestUrl"] = "https://apks.t.bbara.hu/apps/purefin-app-debug/update.json" manifestPlaceholders["updateManifestUrl"] = "https://apks.t.bbara.hu/apps/purefin-app-debug/update.json"
} }
release { release {
versionCode = providers.gradleProperty("purefinReleaseVersionCode").get().toInt()
// Enables code-related app optimization. // Enables code-related app optimization.
isMinifyEnabled = true isMinifyEnabled = true
@@ -51,6 +49,19 @@ android {
} }
} }
androidComponents {
onVariants(selector().withBuildType("debug")) { variant ->
variant.outputs.forEach { output ->
output.versionCode.set(providers.gradleProperty("purefinDebugVersionCode").map { it.toInt() })
}
}
onVariants(selector().withBuildType("release")) { variant ->
variant.outputs.forEach { output ->
output.versionCode.set(providers.gradleProperty("purefinReleaseVersionCode").map { it.toInt() })
}
}
}
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget.set(JvmTarget.JVM_11) jvmTarget.set(JvmTarget.JVM_11)

View File

@@ -1,12 +1,18 @@
package hu.bbara.purefin.ui.screen.settings package hu.bbara.purefin.ui.screen.settings
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize 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.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
@@ -61,30 +67,52 @@ fun SettingsScreen(
} }
) { innerPadding -> ) { innerPadding ->
LazyColumn( LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp), contentPadding = PaddingValues(horizontal = 16.dp, vertical = 16.dp),
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(innerPadding) .padding(innerPadding)
) { ) {
settingGroups.forEach { group -> settingGroups.forEachIndexed { groupIndex, group ->
group.title?.let { title -> group.title?.let { title ->
item { item(key = "${groupIndex}-title") {
Text( Text(
text = title, text = title,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp) modifier = Modifier.padding(
start = 16.dp,
top = 8.dp,
end = 16.dp,
bottom = 4.dp
)
) )
} }
} }
group.options.forEach { option -> itemsIndexed(
item(key = option.key) { items = group.options,
key = { _, option -> option.key }
) { index, option ->
Card(
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
),
shape = groupedSettingItemShape(
index = index,
itemCount = group.options.size
),
modifier = Modifier.fillMaxWidth()
) {
SettingOptionItem( SettingOptionItem(
option = option, option = option,
viewModel = viewModel viewModel = viewModel
) )
HorizontalDivider() }
}
if (groupIndex < settingGroups.lastIndex) {
item(key = "${groupIndex}-spacer") {
Spacer(modifier = Modifier.height(16.dp))
} }
} }
} }
@@ -92,6 +120,31 @@ fun SettingsScreen(
} }
} }
private fun groupedSettingItemShape(
index: Int,
itemCount: Int
): RoundedCornerShape {
val cornerRadius = 12.dp
return when {
itemCount == 1 -> RoundedCornerShape(cornerRadius)
index == 0 -> RoundedCornerShape(
topStart = cornerRadius,
topEnd = cornerRadius,
bottomStart = 0.dp,
bottomEnd = 0.dp
)
index == itemCount - 1 -> RoundedCornerShape(
topStart = 0.dp,
topEnd = 0.dp,
bottomStart = cornerRadius,
bottomEnd = cornerRadius
)
else -> RoundedCornerShape(0.dp)
}
}
@Composable @Composable
private fun SettingOptionItem( private fun SettingOptionItem(
option: SettingOption<*>, option: SettingOption<*>,

View File

@@ -1,19 +1,22 @@
package hu.bbara.purefin.ui.screen.settings.components package hu.bbara.purefin.ui.screen.settings.components
import androidx.compose.foundation.clickable import androidx.compose.foundation.selection.toggleable
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
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.graphics.Color
import androidx.compose.ui.semantics.Role
@Composable @Composable
fun BooleanSettingItem( fun BooleanSettingItem(
title: String, title: String,
value: Boolean, value: Boolean,
onValueChange: (Boolean) -> Unit, onValueChange: (Boolean) -> Unit,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
ListItem( ListItem(
headlineContent = { headlineContent = {
@@ -25,9 +28,14 @@ fun BooleanSettingItem(
trailingContent = { trailingContent = {
Switch( Switch(
checked = value, checked = value,
onCheckedChange = onValueChange onCheckedChange = null
) )
}, },
modifier = modifier.clickable { onValueChange(!value) } colors = ListItemDefaults.colors(containerColor = Color.Transparent),
modifier = modifier.toggleable(
value = value,
role = Role.Switch,
onValueChange = onValueChange
)
) )
} }

View File

@@ -23,7 +23,7 @@ fun <T> DropdownSettingItem(
value: T, value: T,
options: List<T>, options: List<T>,
onValueChange: (T) -> Unit, onValueChange: (T) -> Unit,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
@@ -32,7 +32,7 @@ fun <T> DropdownSettingItem(
onExpandedChange = { expanded = it }, onExpandedChange = { expanded = it },
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp) .padding(horizontal = 16.dp, vertical = 12.dp)
) { ) {
OutlinedTextField( OutlinedTextField(
value = value.toString(), value = value.toString(),

View File

@@ -22,7 +22,7 @@ fun RangeSettingItem(
value: Double, value: Double,
valueRange: ClosedFloatingPointRange<Double>, valueRange: ClosedFloatingPointRange<Double>,
onValueChange: (Double) -> Unit, onValueChange: (Double) -> Unit,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
var sliderValue by remember(value) { mutableStateOf(value.toFloat()) } var sliderValue by remember(value) { mutableStateOf(value.toFloat()) }
@@ -30,14 +30,14 @@ fun RangeSettingItem(
verticalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp) .padding(horizontal = 16.dp, vertical = 12.dp)
) { ) {
Text( Text(
text = title, text = title,
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.bodyLarge
) )
Text( Text(
text = String.Companion.format(Locale.US, "%.1f", sliderValue), text = String.format(Locale.US, "%.1f", sliderValue),
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
@@ -46,7 +46,7 @@ fun RangeSettingItem(
onValueChange = { sliderValue = it }, onValueChange = { sliderValue = it },
onValueChangeFinished = { onValueChange(sliderValue.toDouble()) }, onValueChangeFinished = { onValueChange(sliderValue.toDouble()) },
valueRange = valueRange.start.toFloat()..valueRange.endInclusive.toFloat(), valueRange = valueRange.start.toFloat()..valueRange.endInclusive.toFloat(),
modifier = Modifier.Companion.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
} }
} }

View File

@@ -1,16 +1,18 @@
package hu.bbara.purefin.ui.screen.settings.components package hu.bbara.purefin.ui.screen.settings.components
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
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.graphics.Color
@Composable @Composable
fun ReadOnlySettingItem( fun ReadOnlySettingItem(
title: String, title: String,
value: String, value: String,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
ListItem( ListItem(
headlineContent = { headlineContent = {
@@ -19,13 +21,14 @@ fun ReadOnlySettingItem(
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.bodyLarge
) )
}, },
trailingContent = { supportingContent = {
Text( Text(
text = value, text = value,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
}, },
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
modifier = modifier modifier = modifier
) )
} }

View File

@@ -15,7 +15,7 @@ fun StringSettingItem(
title: String, title: String,
value: String, value: String,
onValueChange: (String) -> Unit, onValueChange: (String) -> Unit,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
OutlinedTextField( OutlinedTextField(
value = value, value = value,
@@ -23,10 +23,10 @@ fun StringSettingItem(
label = { Text(title) }, label = { Text(title) },
singleLine = true, singleLine = true,
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Companion.Words capitalization = KeyboardCapitalization.Words
), ),
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp) .padding(horizontal = 16.dp, vertical = 12.dp)
) )
} }

View File

@@ -2,16 +2,18 @@ package hu.bbara.purefin.ui.screen.settings.components
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
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.graphics.Color
@Composable @Composable
fun VoidSettingItem( fun VoidSettingItem(
title: String, title: String,
onClick: () -> Unit, onClick: () -> Unit,
modifier: Modifier = Modifier.Companion modifier: Modifier = Modifier
) { ) {
ListItem( ListItem(
headlineContent = { headlineContent = {
@@ -20,6 +22,7 @@ fun VoidSettingItem(
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.bodyLarge
) )
}, },
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
modifier = modifier.clickable(onClick = onClick) modifier = modifier.clickable(onClick = onClick)
) )
} }