1
0
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:
Allan Wang 2023-07-28 17:03:33 -07:00
parent 29dc22655d
commit 1bc2b30815
8 changed files with 173 additions and 287 deletions

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">

View File

@ -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,
)
}

View File

@ -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)
}
}

View File

@ -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,
)
}

View File

@ -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
}

View File

@ -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,
)
}
}
}

View File

@ -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()) }
}

View File

@ -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