Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,27 @@ import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.RadioButton
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -59,9 +67,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTextB
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.supportsDynamicTheming
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.LIGHT
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.DEFAULT
Expand All @@ -70,6 +75,7 @@ import com.google.samples.apps.nowinandroid.feature.settings.impl.R.string
import com.google.samples.apps.nowinandroid.feature.settings.impl.SettingsUiState.Loading
import com.google.samples.apps.nowinandroid.feature.settings.impl.SettingsUiState.Success


@Composable
fun SettingsDialog(
onDismiss: () -> Unit,
Expand Down Expand Up @@ -105,7 +111,7 @@ fun SettingsDialog(
*/
AlertDialog(
properties = DialogProperties(usePlatformDefaultWidth = false),
modifier = Modifier.widthIn(max = configuration.screenWidthDp.dp - 80.dp),
modifier = Modifier.widthIn(max = LocalWindowInfo.current.containerSize.width.dp - 80.dp),
onDismissRequest = { onDismiss() },
title = {
Text(
Expand Down Expand Up @@ -164,13 +170,14 @@ private fun ColumnScope.SettingsPanel(
onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit,
) {
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_impl_theme))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
Row(Modifier.selectableGroup()) {
SettingsDialogThemeRadioBtn(
text = stringResource(string.feature_settings_impl_brand_default),
selected = settings.brand == DEFAULT,
onClick = { onChangeThemeBrand(DEFAULT) },
)
SettingsDialogThemeChooserRow(
Spacer(Modifier.width(20.dp))
SettingsDialogThemeRadioBtn(
text = stringResource(string.feature_settings_impl_brand_android),
selected = settings.brand == ANDROID,
onClick = { onChangeThemeBrand(ANDROID) },
Expand All @@ -180,35 +187,38 @@ private fun ColumnScope.SettingsPanel(
Column {
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_impl_dynamic_color_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.feature_settings_impl_dynamic_color_yes),
selected = settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(true) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.feature_settings_impl_dynamic_color_no),
selected = !settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(false) },

SettingsDialogThemeDynamicColorRow(
options = listOf( stringResource(string.feature_settings_impl_dynamic_color_yes), stringResource(string.feature_settings_impl_dynamic_color_no)),
selectedIndex = if (settings.useDynamicColor) 0 else 1,
onOptionSelected = { index ->
onChangeDynamicColorPreference(index == 0)
}
)
}
}
}
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_impl_dark_mode_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.feature_settings_impl_dark_mode_config_system_default),
selected = settings.darkThemeConfig == FOLLOW_SYSTEM,
onClick = { onChangeDarkThemeConfig(FOLLOW_SYSTEM) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.feature_settings_impl_dark_mode_config_light),
selected = settings.darkThemeConfig == LIGHT,
onClick = { onChangeDarkThemeConfig(LIGHT) },
val darkModeOptions = listOf(
stringResource(string.feature_settings_impl_dark_mode_config_system_default),
stringResource(string.feature_settings_impl_dark_mode_config_light),
stringResource(string.feature_settings_impl_dark_mode_config_dark)
)
SettingsDialogThemeChooserRow(
text = stringResource(string.feature_settings_impl_dark_mode_config_dark),
selected = settings.darkThemeConfig == DARK,
onClick = { onChangeDarkThemeConfig(DARK) },

SettingsDialogThemeDarkModeRow(
options = darkModeOptions,
selectedIndex = when(settings.darkThemeConfig) {
DarkThemeConfig.FOLLOW_SYSTEM -> 0
DarkThemeConfig.LIGHT -> 1
DarkThemeConfig.DARK -> 2
},
onOptionSelected = { index ->val newConfig = when (index) {
0 -> DarkThemeConfig.FOLLOW_SYSTEM
1 -> DarkThemeConfig.LIGHT
else -> DarkThemeConfig.DARK
}
onChangeDarkThemeConfig(newConfig)}
)
}
}
Expand All @@ -223,20 +233,19 @@ private fun SettingsDialogSectionTitle(text: String) {
}

@Composable
fun SettingsDialogThemeChooserRow(
fun SettingsDialogThemeRadioBtn(
text: String,
selected: Boolean,
onClick: () -> Unit,
) {
Row(
Modifier
.fillMaxWidth()
.selectable(
selected = selected,
role = Role.RadioButton,
onClick = onClick,
)
.padding(12.dp),
.padding(5.dp),
verticalAlignment = Alignment.CenterVertically,
) {
RadioButton(
Expand All @@ -248,6 +257,73 @@ fun SettingsDialogThemeChooserRow(
}
}

@Composable
fun SettingsDialogThemeDynamicColorRow( options :List<String>,
selectedIndex :Int,
onOptionSelected : (Int) -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
options.forEachIndexed { index, stringId ->
val isSelected = index == selectedIndex

if (isSelected) {
Button(
onClick = { onOptionSelected(index) },
modifier = Modifier.weight(1f),
shape = CircleShape
) {
Spacer(Modifier.width(3.dp))
Text(text = stringId)
}
} else {
OutlinedButton(
onClick = { onOptionSelected(index) },
modifier = Modifier.weight(1f),
shape = CircleShape
) {
Spacer(Modifier.width(3.dp))
Text(text = stringId) }
}
}
}
}

@Composable
fun SettingsDialogThemeDarkModeRow(
options: List<String>,
selectedIndex: Int,
onOptionSelected: (Int) -> Unit
) {
SingleChoiceSegmentedButtonRow(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 1.dp)
) {
options.forEachIndexed { index, stringId ->
val isSelected = index == selectedIndex
SegmentedButton(
shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size),
onClick = { onOptionSelected(index) },
selected = isSelected,
label = {
Text(text = stringId, maxLines = 1)
},
colors = SegmentedButtonDefaults.colors(
activeContainerColor = MaterialTheme.colorScheme.primary ,
activeContentColor = MaterialTheme.colorScheme.onPrimary,
inactiveContainerColor = Color.Transparent,
inactiveContentColor = MaterialTheme.colorScheme.onSurface
),
icon = {}
) }
}
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun LinksPanel() {
Expand Down Expand Up @@ -294,7 +370,7 @@ private fun PreviewSettingsDialog() {
settingsUiState = Success(
UserEditableSettings(
brand = DEFAULT,
darkThemeConfig = FOLLOW_SYSTEM,
darkThemeConfig = DarkThemeConfig.FOLLOW_SYSTEM,
useDynamicColor = false,
),
),
Expand Down
2 changes: 1 addition & 1 deletion feature/settings/impl/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<string name="feature_settings_impl_brand_default">Default</string>
<string name="feature_settings_impl_brand_android">Android</string>
<string name="feature_settings_impl_dark_mode_preference">Dark mode preference</string>
<string name="feature_settings_impl_dark_mode_config_system_default">System default</string>
<string name="feature_settings_impl_dark_mode_config_system_default">System</string>
<string name="feature_settings_impl_dark_mode_config_light">Light</string>
<string name="feature_settings_impl_dark_mode_config_dark">Dark</string>
<string name="feature_settings_impl_dynamic_color_preference">Use Dynamic Color</string>
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
accompanist = "0.37.0"
androidDesugarJdkLibs = "2.1.4"
# AGP and tools should be updated together
androidGradlePlugin = "9.0.0"
androidTools = "32.0.0"
androidGradlePlugin = "9.0.1"
androidTools = "32.0.1"
androidxActivity = "1.9.3"
androidxAppCompat = "1.7.0"
androidxBrowser = "1.8.0"
Expand Down