From ed2d29ffc546bfd4e82a4c88ca1f09459d6855b8 Mon Sep 17 00:00:00 2001 From: tapframe <85391825+tapframe@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:39:20 +0530 Subject: [PATCH] Fix appearance theme grid layout --- .../settings/AppearanceSettingsPage.kt | 108 ++++++++++++------ 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/AppearanceSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/AppearanceSettingsPage.kt index abbf58e7..157bed8e 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/AppearanceSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/AppearanceSettingsPage.kt @@ -5,9 +5,9 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -38,6 +38,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.nuvio.app.core.ui.AppTheme import com.nuvio.app.core.ui.NuvioBottomSheetActionRow @@ -67,7 +68,6 @@ import org.jetbrains.compose.resources.stringResource import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberModalBottomSheetState -@OptIn(ExperimentalLayoutApi::class) internal fun LazyListScope.appearanceSettingsContent( isTablet: Boolean, selectedTheme: AppTheme, @@ -89,28 +89,50 @@ internal fun LazyListScope.appearanceSettingsContent( ) { SettingsGroup(isTablet = isTablet) { val themes = listOf(AppTheme.WHITE) + AppTheme.entries.filterNot { it == AppTheme.WHITE } - FlowRow( + val horizontalPadding = if (isTablet) 20.dp else 16.dp + val verticalPadding = if (isTablet) 18.dp else 14.dp + val themeSpacing = if (isTablet) 16.dp else 12.dp + BoxWithConstraints( modifier = Modifier .fillMaxWidth() .padding( - horizontal = if (isTablet) 20.dp else 16.dp, - vertical = if (isTablet) 18.dp else 14.dp, + horizontal = horizontalPadding, + vertical = verticalPadding, ), - horizontalArrangement = Arrangement.spacedBy(if (isTablet) 16.dp else 12.dp), - verticalArrangement = Arrangement.spacedBy(if (isTablet) 16.dp else 12.dp), ) { - themes.forEach { theme -> - ThemeChip( - theme = theme, - isSelected = theme == selectedTheme, - onClick = { onThemeSelected(theme) }, - ) + val preferredColumns = if (isTablet) 4 else 3 + val minThemeCellWidth = if (isTablet) 92.dp else 78.dp + val themeColumns = ((maxWidth + themeSpacing) / (minThemeCellWidth + themeSpacing)) + .toInt() + .coerceAtLeast(1) + .coerceAtMost(preferredColumns) + + Column( + verticalArrangement = Arrangement.spacedBy(themeSpacing), + ) { + themes.chunked(themeColumns).forEach { rowThemes -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(themeSpacing), + ) { + rowThemes.forEach { theme -> + ThemeChip( + theme = theme, + isSelected = theme == selectedTheme, + onClick = { onThemeSelected(theme) }, + modifier = Modifier.weight(1f), + ) + } + repeat(themeColumns - rowThemes.size) { + Spacer(modifier = Modifier.weight(1f)) + } + } + } } } } } } - item { var showLanguageSheet by remember { mutableStateOf(false) } SettingsSection( @@ -262,41 +284,48 @@ private fun ThemeChip( theme: AppTheme, isSelected: Boolean, onClick: () -> Unit, + modifier: Modifier = Modifier, ) { val palette = ThemeColors.getColorPalette(theme) Column( - modifier = Modifier + modifier = modifier .clip(RoundedCornerShape(12.dp)) .clickable(onClick = onClick) - .then( - if (isSelected) { - Modifier.border( - width = 1.5.dp, - color = palette.focusRing, - shape = RoundedCornerShape(12.dp), - ) - } else { - Modifier - }, - ) - .padding(horizontal = 12.dp, vertical = 10.dp), + .padding(horizontal = 4.dp, vertical = 8.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Box( modifier = Modifier - .size(44.dp) - .clip(CircleShape) - .background(palette.secondary), + .size(56.dp) + .then( + if (isSelected) { + Modifier.border( + width = 1.5.dp, + color = palette.focusRing, + shape = RoundedCornerShape(14.dp), + ) + } else { + Modifier + }, + ), contentAlignment = Alignment.Center, ) { - if (isSelected) { - Icon( - imageVector = Icons.Default.Check, - contentDescription = stringResource(Res.string.cd_selected), - tint = palette.onSecondary, - modifier = Modifier.size(22.dp), - ) + Box( + modifier = Modifier + .size(44.dp) + .clip(CircleShape) + .background(palette.secondary), + contentAlignment = Alignment.Center, + ) { + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = stringResource(Res.string.cd_selected), + tint = palette.onSecondary, + modifier = Modifier.size(22.dp), + ) + } } } @@ -312,6 +341,9 @@ private fun ThemeChip( }, fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Medium, textAlign = TextAlign.Center, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.fillMaxWidth(), ) Spacer(modifier = Modifier.height(4.dp))