mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-09-18 21:12:24 +02:00
Remove dsl
This commit is contained in:
parent
29dc22655d
commit
1bc2b30815
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Allan Wang
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.pitchedapps.frost.compose.settings
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
|
||||
@DslMarker annotation class SettingsDslMarker
|
||||
|
||||
@SettingsDslMarker
|
||||
interface SettingsDsl {
|
||||
/** Entry point to avoid cluttering the global namespace. */
|
||||
companion object : SettingsDsl
|
||||
}
|
||||
|
||||
/** Dsl for creating individual entries in a list */
|
||||
@SettingsDslMarker
|
||||
interface SettingsListDsl {
|
||||
|
||||
/**
|
||||
* Sub list with group title
|
||||
*
|
||||
* TODO support collapsed and/or shown?
|
||||
*/
|
||||
// fun group(title: String, enabled: Boolean = true, action: SettingsListDsl.() -> Unit)
|
||||
|
||||
/** Generic item without content */
|
||||
fun item(
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
description: String? = null,
|
||||
onClick: (() -> Unit)? = null
|
||||
)
|
||||
|
||||
/** Long, non clickable content */
|
||||
fun description(text: String, icon: ImageVector? = null)
|
||||
|
||||
fun checkbox(
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
description: String? = null,
|
||||
checked: Boolean,
|
||||
onCheckedChanged: (Boolean) -> Unit,
|
||||
)
|
||||
|
||||
fun switch(
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
description: String? = null,
|
||||
checked: Boolean,
|
||||
onCheckedChanged: (Boolean) -> Unit,
|
||||
)
|
||||
|
||||
fun custom(
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
description: String? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
content: @Composable () -> Unit,
|
||||
)
|
||||
}
|
@ -16,9 +16,12 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.compose.settings
|
||||
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@ -28,19 +31,18 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.pitchedapps.frost.compose.FrostPreview
|
||||
|
||||
@Composable
|
||||
fun SettingsListDsl(
|
||||
fun SettingsList(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable SettingsListDsl.() -> Unit
|
||||
data: List<SettingsListItemData>,
|
||||
) {
|
||||
val items = SettingsDsl.settingsListDsl(content)
|
||||
|
||||
LazyColumn(modifier = modifier) { items(items) { compose -> compose() } }
|
||||
LazyColumn(modifier = modifier) { items(data) { SettingsListItem(data = it) } }
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun SettingsListDslPreview() {
|
||||
fun SettingsListPreview() {
|
||||
|
||||
@Immutable
|
||||
data class Model(
|
||||
val check1: Boolean = false,
|
||||
val switch1: Boolean = false,
|
||||
@ -49,31 +51,37 @@ fun SettingsListDslPreview() {
|
||||
|
||||
var state by remember { mutableStateOf(Model()) }
|
||||
|
||||
FrostPreview {
|
||||
SettingsListDsl {
|
||||
checkbox(
|
||||
title = "Check 1",
|
||||
checked = state.check1,
|
||||
onCheckedChanged = { state = state.copy(check1 = it) },
|
||||
)
|
||||
checkbox(
|
||||
title = "Check 1",
|
||||
description = "Linked again",
|
||||
checked = state.check1,
|
||||
onCheckedChanged = { state = state.copy(check1 = it) },
|
||||
)
|
||||
switch(
|
||||
title = "Switch 1",
|
||||
checked = state.switch1,
|
||||
onCheckedChanged = { state = state.copy(switch1 = it) },
|
||||
)
|
||||
switch(
|
||||
title = "Switch 2",
|
||||
enabled = state.switch1,
|
||||
description = "Enabled by switch 1",
|
||||
checked = state.switch2,
|
||||
onCheckedChanged = { state = state.copy(switch2 = it) },
|
||||
val data by remember {
|
||||
derivedStateOf {
|
||||
listOf(
|
||||
SettingsListItemData.Checkbox(
|
||||
title = "Check 1",
|
||||
checked = state.check1,
|
||||
onCheckChanged = { state = state.copy(check1 = it) },
|
||||
),
|
||||
SettingsListItemData.Checkbox(
|
||||
title = "Check 1",
|
||||
description = "Linked again",
|
||||
checked = state.check1,
|
||||
onCheckChanged = { state = state.copy(check1 = it) },
|
||||
),
|
||||
SettingsListItemData.Switch(
|
||||
title = "Switch 1",
|
||||
checked = state.switch1,
|
||||
onCheckChanged = { state = state.copy(switch1 = it) },
|
||||
),
|
||||
SettingsListItemData.Switch(
|
||||
title = "Switch 2",
|
||||
enabled = state.switch1,
|
||||
description = "Enabled by switch 1",
|
||||
checked = state.switch2,
|
||||
onCheckChanged = { state = state.copy(switch2 = it) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FrostPreview {
|
||||
SettingsList(modifier = Modifier.systemBarsPadding(), data = data)
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import androidx.compose.material.icons.outlined.Person
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -40,11 +41,62 @@ import com.pitchedapps.frost.compose.FrostPreview
|
||||
import com.pitchedapps.frost.ext.optionalCompose
|
||||
import com.pitchedapps.frost.ext.thenIf
|
||||
|
||||
/**
|
||||
* Settings list item based on [SettingsListItemData]
|
||||
*/
|
||||
@Composable
|
||||
fun SettingsListItem(
|
||||
data: SettingsListItemData,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val onClick: (() -> Unit)?
|
||||
val content: (@Composable () -> Unit)?
|
||||
|
||||
when (data) {
|
||||
is SettingsListItemData.Item -> {
|
||||
onClick = null
|
||||
content = null
|
||||
}
|
||||
|
||||
is SettingsListItemData.Checkbox -> {
|
||||
onClick = { data.onCheckChanged(!data.checked) }
|
||||
content = {
|
||||
Checkbox(
|
||||
enabled = data.enabled,
|
||||
checked = data.checked,
|
||||
onCheckedChange = data.onCheckChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is SettingsListItemData.Switch -> {
|
||||
onClick = { data.onCheckChanged(!data.checked) }
|
||||
content = {
|
||||
Switch(
|
||||
enabled = data.enabled,
|
||||
checked = data.checked,
|
||||
onCheckedChange = data.onCheckChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsListItem(
|
||||
title = data.title,
|
||||
modifier = modifier,
|
||||
enabled = data.enabled,
|
||||
icon = data.icon,
|
||||
description = data.description,
|
||||
onClick = onClick,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
/** Basic building block for settings */
|
||||
@Composable
|
||||
fun SettingsListItem(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
description: String? = null,
|
||||
@ -54,25 +106,27 @@ fun SettingsListItem(
|
||||
val alpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
|
||||
ListItem(
|
||||
modifier =
|
||||
modifier.thenIf(onClick != null) {
|
||||
Modifier.clickable(enabled = enabled) { onClick?.invoke() }
|
||||
},
|
||||
modifier.thenIf(onClick != null) {
|
||||
Modifier.clickable(enabled = enabled) { onClick?.invoke() }
|
||||
},
|
||||
leadingContent =
|
||||
icon.optionalCompose {
|
||||
Icon(
|
||||
modifier = Modifier.size(24.dp).alpha(alpha),
|
||||
imageVector = it,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
icon.optionalCompose {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.alpha(alpha),
|
||||
imageVector = it,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
headlineContent = { Text(modifier = Modifier.alpha(alpha), text = title) },
|
||||
supportingContent =
|
||||
description.optionalCompose {
|
||||
Text(
|
||||
modifier = Modifier.alpha(alpha),
|
||||
text = it,
|
||||
)
|
||||
},
|
||||
description.optionalCompose {
|
||||
Text(
|
||||
modifier = Modifier.alpha(alpha),
|
||||
text = it,
|
||||
)
|
||||
},
|
||||
trailingContent = content,
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.pitchedapps.frost.compose.settings
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
|
||||
@Immutable
|
||||
sealed interface SettingsListItemData {
|
||||
val title: String
|
||||
val enabled: Boolean
|
||||
val icon: ImageVector?
|
||||
val description: String?
|
||||
|
||||
data class Item(
|
||||
override val title: String,
|
||||
override val enabled: Boolean = true,
|
||||
override val icon: ImageVector? = null,
|
||||
override val description: String? = null,
|
||||
val onClick: (() -> Unit)? = null,
|
||||
) : SettingsListItemData
|
||||
|
||||
data class Checkbox(
|
||||
override val title: String,
|
||||
override val enabled: Boolean = true,
|
||||
override val icon: ImageVector? = null,
|
||||
override val description: String? = null,
|
||||
val checked: Boolean,
|
||||
val onCheckChanged: (Boolean) -> Unit,
|
||||
) : SettingsListItemData
|
||||
|
||||
data class Switch(
|
||||
override val title: String,
|
||||
override val enabled: Boolean = true,
|
||||
override val icon: ImageVector? = null,
|
||||
override val description: String? = null,
|
||||
val checked: Boolean,
|
||||
val onCheckChanged: (Boolean) -> Unit,
|
||||
) : SettingsListItemData
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Allan Wang
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.pitchedapps.frost.compose.settings
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
|
||||
@Composable
|
||||
fun LazyListScope.settingsListDsl(content: @Composable SettingsListDsl.() -> Unit) {
|
||||
val items = SettingsDsl.settingsListDsl(content)
|
||||
items(items) { compose -> compose() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsDsl.settingsListDsl(
|
||||
content: @Composable SettingsListDsl.() -> Unit
|
||||
): List<@Composable () -> Unit> {
|
||||
val data = SettingsListDslData()
|
||||
data.content()
|
||||
return data.items
|
||||
}
|
||||
|
||||
private class SettingsListDslData : SettingsListDsl {
|
||||
val items: MutableList<@Composable () -> Unit> = mutableListOf()
|
||||
|
||||
private fun addCompose(content: @Composable () -> Unit) {
|
||||
items.add(content)
|
||||
}
|
||||
|
||||
override fun item(
|
||||
title: String,
|
||||
enabled: Boolean,
|
||||
icon: ImageVector?,
|
||||
description: String?,
|
||||
onClick: (() -> Unit)?
|
||||
) {
|
||||
addCompose {
|
||||
SettingsListItem(
|
||||
icon = icon,
|
||||
title = title,
|
||||
enabled = enabled,
|
||||
description = description,
|
||||
onClick = onClick,
|
||||
content = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun description(text: String, icon: ImageVector?) {}
|
||||
|
||||
override fun checkbox(
|
||||
title: String,
|
||||
enabled: Boolean,
|
||||
icon: ImageVector?,
|
||||
description: String?,
|
||||
checked: Boolean,
|
||||
onCheckedChanged: (Boolean) -> Unit
|
||||
) {
|
||||
custom(
|
||||
icon = icon,
|
||||
title = title,
|
||||
enabled = enabled,
|
||||
description = description,
|
||||
onClick = { onCheckedChanged(!checked) },
|
||||
) {
|
||||
Checkbox(
|
||||
enabled = enabled,
|
||||
checked = checked,
|
||||
onCheckedChange = onCheckedChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun switch(
|
||||
title: String,
|
||||
enabled: Boolean,
|
||||
icon: ImageVector?,
|
||||
description: String?,
|
||||
checked: Boolean,
|
||||
onCheckedChanged: (Boolean) -> Unit
|
||||
) {
|
||||
custom(
|
||||
icon = icon,
|
||||
title = title,
|
||||
enabled = enabled,
|
||||
description = description,
|
||||
onClick = { onCheckedChanged(!checked) },
|
||||
) {
|
||||
Switch(
|
||||
enabled = enabled,
|
||||
checked = checked,
|
||||
onCheckedChange = onCheckedChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun custom(
|
||||
title: String,
|
||||
enabled: Boolean,
|
||||
icon: ImageVector?,
|
||||
description: String?,
|
||||
onClick: (() -> Unit)?,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
addCompose {
|
||||
SettingsListItem(
|
||||
icon = icon,
|
||||
title = title,
|
||||
enabled = enabled,
|
||||
description = description,
|
||||
onClick = onClick,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.pitchedapps.frost.settings.screens
|
||||
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.material.icons.Icons.Outlined as MaterialIcons
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.Lock
|
||||
@ -31,60 +32,59 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.compose.FrostPreview
|
||||
import com.pitchedapps.frost.compose.settings.SettingsListDsl
|
||||
import com.pitchedapps.frost.compose.settings.SettingsList
|
||||
import com.pitchedapps.frost.compose.settings.SettingsListItemData
|
||||
|
||||
@Composable
|
||||
fun MainSettingsScreen(modifier: Modifier = Modifier) {
|
||||
SettingsListDsl(modifier = modifier) {
|
||||
item(
|
||||
|
||||
val data = listOf(
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Palette,
|
||||
title = stringResource(id = R.string.appearance),
|
||||
description = stringResource(id = R.string.appearance_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.TrendingUp,
|
||||
title = stringResource(id = R.string.behaviour),
|
||||
description = stringResource(id = R.string.behaviour_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Newspaper,
|
||||
title = stringResource(id = R.string.newsfeed),
|
||||
description = stringResource(id = R.string.newsfeed_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Notifications,
|
||||
title = stringResource(id = R.string.notifications),
|
||||
description = stringResource(id = R.string.notifications_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Lock,
|
||||
title = stringResource(id = R.string.security),
|
||||
description = stringResource(id = R.string.security_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Info,
|
||||
title = stringResource(id = R.string.about_frost),
|
||||
description = stringResource(id = R.string.about_frost_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Translate,
|
||||
title = stringResource(id = R.string.help_translate),
|
||||
description = stringResource(id = R.string.help_translate_desc),
|
||||
)
|
||||
item(
|
||||
),
|
||||
SettingsListItemData.Item(
|
||||
icon = MaterialIcons.Replay,
|
||||
title = stringResource(id = R.string.replay_intro),
|
||||
)
|
||||
// item(
|
||||
// icon = MaterialIcons.Science,
|
||||
// title = stringResource(id = R.string.experimental),
|
||||
// description = stringResource(id = R.string.experimental_desc),
|
||||
// )
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
SettingsList(modifier = modifier, data = data)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MainSettingsScreenPreview() {
|
||||
FrostPreview { MainSettingsScreen() }
|
||||
FrostPreview { MainSettingsScreen(modifier = Modifier.systemBarsPadding()) }
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
// https://mvnrepository.com/artifact/com.android.application/com.android.application.gradle.plugin?repo=google
|
||||
id 'com.android.application' version '8.1.0-beta04' apply false
|
||||
id 'com.android.application' version '8.1.0-beta01' apply false
|
||||
id 'com.android.library' version '8.0.2' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.8.21' apply false
|
||||
// https://mvnrepository.com/artifact/com.google.devtools.ksp/com.google.devtools.ksp.gradle.plugin
|
||||
|
Loading…
Reference in New Issue
Block a user