Merge pull request #2907 from vitorpamplona/claude/improve-compose-settings-NKNWr
Refactor ComposeSettingsScreen to use unified tile components
This commit is contained in:
+88
-60
@@ -20,8 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
@@ -30,11 +31,13 @@ import androidx.compose.material3.Switch
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol
|
||||||
|
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||||
import com.vitorpamplona.amethyst.model.BooleanType
|
import com.vitorpamplona.amethyst.model.BooleanType
|
||||||
import com.vitorpamplona.amethyst.model.UiSettingsFlow
|
import com.vitorpamplona.amethyst.model.UiSettingsFlow
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
@@ -42,10 +45,7 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size20dp
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -57,18 +57,12 @@ fun ComposeSettingsScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
TopBarWithBackButton(stringRes(id = R.string.compose_settings), nav)
|
TopBarWithBackButton(stringRes(id = R.string.compose_settings), nav)
|
||||||
},
|
},
|
||||||
) {
|
) { padding ->
|
||||||
Column(Modifier.padding(it)) {
|
ComposeSettingsContent(
|
||||||
ComposeSettingsContent(accountViewModel.settings.uiSettingsFlow, accountViewModel)
|
sharedPrefs = accountViewModel.settings.uiSettingsFlow,
|
||||||
}
|
accountViewModel = accountViewModel,
|
||||||
}
|
modifier = Modifier.padding(padding),
|
||||||
}
|
)
|
||||||
|
|
||||||
@Preview(device = "spec:width=2160px,height=2340px,dpi=440")
|
|
||||||
@Composable
|
|
||||||
fun ComposeSettingsScreenPreview() {
|
|
||||||
ThemeComparisonRow {
|
|
||||||
ComposeSettingsContent(UiSettingsFlow(), mockAccountViewModel())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,65 +70,99 @@ fun ComposeSettingsScreenPreview() {
|
|||||||
fun ComposeSettingsContent(
|
fun ComposeSettingsContent(
|
||||||
sharedPrefs: UiSettingsFlow,
|
sharedPrefs: UiSettingsFlow,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
modifier =
|
||||||
.fillMaxSize()
|
modifier
|
||||||
.padding(top = Size10dp, start = Size20dp, end = Size20dp)
|
.verticalScroll(rememberScrollState())
|
||||||
.verticalScroll(rememberScrollState()),
|
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||||
verticalArrangement = RowColSpacing,
|
|
||||||
) {
|
) {
|
||||||
BooleanSwitchRow(
|
SettingsSection(R.string.compose_settings) {
|
||||||
sharedPrefs.automaticallyCreateDrafts,
|
BooleanSwitchTile(
|
||||||
R.string.auto_create_drafts_setting_title,
|
flow = sharedPrefs.automaticallyCreateDrafts,
|
||||||
R.string.auto_create_drafts_setting_description,
|
icon = MaterialSymbols.Drafts,
|
||||||
)
|
title = R.string.auto_create_drafts_setting_title,
|
||||||
BooleanSwitchRow(
|
description = R.string.auto_create_drafts_setting_description,
|
||||||
sharedPrefs.automaticallyProposeAiImprovements,
|
)
|
||||||
R.string.ai_writing_setting_title,
|
SettingsDivider()
|
||||||
R.string.ai_writing_setting_description,
|
BooleanSwitchTile(
|
||||||
)
|
flow = sharedPrefs.automaticallyProposeAiImprovements,
|
||||||
BooleanSwitchRow(
|
icon = MaterialSymbols.AutoAwesome,
|
||||||
sharedPrefs.useTrackedBroadcasts,
|
title = R.string.ai_writing_setting_title,
|
||||||
R.string.tracked_broadcasts_setting_title,
|
description = R.string.ai_writing_setting_description,
|
||||||
R.string.tracked_broadcasts_setting_description,
|
)
|
||||||
)
|
SettingsDivider()
|
||||||
AddClientTagRow(accountViewModel)
|
BooleanSwitchTile(
|
||||||
|
flow = sharedPrefs.useTrackedBroadcasts,
|
||||||
|
icon = MaterialSymbols.CellTower,
|
||||||
|
title = R.string.tracked_broadcasts_setting_title,
|
||||||
|
description = R.string.tracked_broadcasts_setting_description,
|
||||||
|
)
|
||||||
|
SettingsDivider()
|
||||||
|
AddClientTagTile(accountViewModel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AddClientTagRow(accountViewModel: AccountViewModel) {
|
private fun AddClientTagTile(accountViewModel: AccountViewModel) {
|
||||||
val addClientTag by accountViewModel.account.settings.syncedSettings.security
|
val addClientTag by accountViewModel.account.settings.syncedSettings.security
|
||||||
.addClientTag
|
.addClientTag
|
||||||
.collectAsStateWithLifecycle()
|
.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
SettingsRow(
|
SwitchTile(
|
||||||
R.string.add_client_tag_title,
|
icon = MaterialSymbols.Code,
|
||||||
R.string.add_client_tag_explainer,
|
title = R.string.add_client_tag_title,
|
||||||
) {
|
description = R.string.add_client_tag_explainer,
|
||||||
Switch(
|
checked = addClientTag,
|
||||||
checked = addClientTag,
|
onCheckedChange = accountViewModel::updateAddClientTag,
|
||||||
onCheckedChange = accountViewModel::updateAddClientTag,
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun BooleanSwitchRow(
|
private fun BooleanSwitchTile(
|
||||||
flow: MutableStateFlow<BooleanType>,
|
flow: MutableStateFlow<BooleanType>,
|
||||||
title: Int,
|
icon: MaterialSymbol,
|
||||||
description: Int,
|
@StringRes title: Int,
|
||||||
|
@StringRes description: Int,
|
||||||
) {
|
) {
|
||||||
val value by flow.collectAsState()
|
val value by flow.collectAsState()
|
||||||
|
|
||||||
SettingsRow(title, description) {
|
SwitchTile(
|
||||||
Switch(
|
icon = icon,
|
||||||
checked = value == BooleanType.ALWAYS,
|
title = title,
|
||||||
onCheckedChange = { isOn ->
|
description = description,
|
||||||
flow.tryEmit(if (isOn) BooleanType.ALWAYS else BooleanType.NEVER)
|
checked = value == BooleanType.ALWAYS,
|
||||||
},
|
onCheckedChange = { isOn ->
|
||||||
)
|
flow.tryEmit(if (isOn) BooleanType.ALWAYS else BooleanType.NEVER)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SwitchTile(
|
||||||
|
icon: MaterialSymbol,
|
||||||
|
@StringRes title: Int,
|
||||||
|
@StringRes description: Int,
|
||||||
|
checked: Boolean,
|
||||||
|
onCheckedChange: (Boolean) -> Unit,
|
||||||
|
) {
|
||||||
|
SettingsControlRow(
|
||||||
|
icon = icon,
|
||||||
|
title = stringRes(title),
|
||||||
|
description = stringRes(description),
|
||||||
|
onClick = { onCheckedChange(!checked) },
|
||||||
|
) {
|
||||||
|
Switch(checked = checked, onCheckedChange = onCheckedChange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(device = "spec:width=2160px,height=2340px,dpi=440")
|
||||||
|
@Composable
|
||||||
|
fun ComposeSettingsScreenPreview() {
|
||||||
|
ThemeComparisonColumn {
|
||||||
|
ComposeSettingsContent(UiSettingsFlow(), mockAccountViewModel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user