1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-19 15:11:42 +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"> <project version="4">
<component name="DesignSurface"> <component name="DesignSurface">
<option name="filePathToZoomLevelMap"> <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 package com.pitchedapps.frost.compose.settings
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -28,19 +31,18 @@ import androidx.compose.ui.tooling.preview.Preview
import com.pitchedapps.frost.compose.FrostPreview import com.pitchedapps.frost.compose.FrostPreview
@Composable @Composable
fun SettingsListDsl( fun SettingsList(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
content: @Composable SettingsListDsl.() -> Unit data: List<SettingsListItemData>,
) { ) {
val items = SettingsDsl.settingsListDsl(content) LazyColumn(modifier = modifier) { items(data) { SettingsListItem(data = it) } }
LazyColumn(modifier = modifier) { items(items) { compose -> compose() } }
} }
@Preview @Preview
@Composable @Composable
fun SettingsListDslPreview() { fun SettingsListPreview() {
@Immutable
data class Model( data class Model(
val check1: Boolean = false, val check1: Boolean = false,
val switch1: Boolean = false, val switch1: Boolean = false,
@ -49,31 +51,37 @@ fun SettingsListDslPreview() {
var state by remember { mutableStateOf(Model()) } var state by remember { mutableStateOf(Model()) }
FrostPreview { val data by remember {
SettingsListDsl { derivedStateOf {
checkbox( listOf(
title = "Check 1", SettingsListItemData.Checkbox(
checked = state.check1, title = "Check 1",
onCheckedChanged = { state = state.copy(check1 = it) }, checked = state.check1,
) onCheckChanged = { state = state.copy(check1 = it) },
checkbox( ),
title = "Check 1", SettingsListItemData.Checkbox(
description = "Linked again", title = "Check 1",
checked = state.check1, description = "Linked again",
onCheckedChanged = { state = state.copy(check1 = it) }, checked = state.check1,
) onCheckChanged = { state = state.copy(check1 = it) },
switch( ),
title = "Switch 1", SettingsListItemData.Switch(
checked = state.switch1, title = "Switch 1",
onCheckedChanged = { state = state.copy(switch1 = it) }, checked = state.switch1,
) onCheckChanged = { state = state.copy(switch1 = it) },
switch( ),
title = "Switch 2", SettingsListItemData.Switch(
enabled = state.switch1, title = "Switch 2",
description = "Enabled by switch 1", enabled = state.switch1,
checked = state.switch2, description = "Enabled by switch 1",
onCheckedChanged = { state = state.copy(switch2 = it) }, 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.Checkbox
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue 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.optionalCompose
import com.pitchedapps.frost.ext.thenIf 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 */ /** Basic building block for settings */
@Composable @Composable
fun SettingsListItem( fun SettingsListItem(
modifier: Modifier = Modifier,
title: String, title: String,
modifier: Modifier = Modifier,
enabled: Boolean = true, enabled: Boolean = true,
icon: ImageVector? = null, icon: ImageVector? = null,
description: String? = null, description: String? = null,
@ -54,25 +106,27 @@ fun SettingsListItem(
val alpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled val alpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
ListItem( ListItem(
modifier = modifier =
modifier.thenIf(onClick != null) { modifier.thenIf(onClick != null) {
Modifier.clickable(enabled = enabled) { onClick?.invoke() } Modifier.clickable(enabled = enabled) { onClick?.invoke() }
}, },
leadingContent = leadingContent =
icon.optionalCompose { icon.optionalCompose {
Icon( Icon(
modifier = Modifier.size(24.dp).alpha(alpha), modifier = Modifier
imageVector = it, .size(24.dp)
contentDescription = null, .alpha(alpha),
) imageVector = it,
}, contentDescription = null,
)
},
headlineContent = { Text(modifier = Modifier.alpha(alpha), text = title) }, headlineContent = { Text(modifier = Modifier.alpha(alpha), text = title) },
supportingContent = supportingContent =
description.optionalCompose { description.optionalCompose {
Text( Text(
modifier = Modifier.alpha(alpha), modifier = Modifier.alpha(alpha),
text = it, text = it,
) )
}, },
trailingContent = content, 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 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.Icons.Outlined as MaterialIcons
import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Lock 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 androidx.compose.ui.tooling.preview.Preview
import com.pitchedapps.frost.R import com.pitchedapps.frost.R
import com.pitchedapps.frost.compose.FrostPreview 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 @Composable
fun MainSettingsScreen(modifier: Modifier = Modifier) { fun MainSettingsScreen(modifier: Modifier = Modifier) {
SettingsListDsl(modifier = modifier) {
item( val data = listOf(
SettingsListItemData.Item(
icon = MaterialIcons.Palette, icon = MaterialIcons.Palette,
title = stringResource(id = R.string.appearance), title = stringResource(id = R.string.appearance),
description = stringResource(id = R.string.appearance_desc), description = stringResource(id = R.string.appearance_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.TrendingUp, icon = MaterialIcons.TrendingUp,
title = stringResource(id = R.string.behaviour), title = stringResource(id = R.string.behaviour),
description = stringResource(id = R.string.behaviour_desc), description = stringResource(id = R.string.behaviour_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Newspaper, icon = MaterialIcons.Newspaper,
title = stringResource(id = R.string.newsfeed), title = stringResource(id = R.string.newsfeed),
description = stringResource(id = R.string.newsfeed_desc), description = stringResource(id = R.string.newsfeed_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Notifications, icon = MaterialIcons.Notifications,
title = stringResource(id = R.string.notifications), title = stringResource(id = R.string.notifications),
description = stringResource(id = R.string.notifications_desc), description = stringResource(id = R.string.notifications_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Lock, icon = MaterialIcons.Lock,
title = stringResource(id = R.string.security), title = stringResource(id = R.string.security),
description = stringResource(id = R.string.security_desc), description = stringResource(id = R.string.security_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Info, icon = MaterialIcons.Info,
title = stringResource(id = R.string.about_frost), title = stringResource(id = R.string.about_frost),
description = stringResource(id = R.string.about_frost_desc), description = stringResource(id = R.string.about_frost_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Translate, icon = MaterialIcons.Translate,
title = stringResource(id = R.string.help_translate), title = stringResource(id = R.string.help_translate),
description = stringResource(id = R.string.help_translate_desc), description = stringResource(id = R.string.help_translate_desc),
) ),
item( SettingsListItemData.Item(
icon = MaterialIcons.Replay, icon = MaterialIcons.Replay,
title = stringResource(id = R.string.replay_intro), title = stringResource(id = R.string.replay_intro),
) ),
// item( )
// icon = MaterialIcons.Science,
// title = stringResource(id = R.string.experimental), SettingsList(modifier = modifier, data = data)
// description = stringResource(id = R.string.experimental_desc),
// )
}
} }
@Preview @Preview
@Composable @Composable
fun MainSettingsScreenPreview() { fun MainSettingsScreenPreview() {
FrostPreview { MainSettingsScreen() } FrostPreview { MainSettingsScreen(modifier = Modifier.systemBarsPadding()) }
} }

View File

@ -8,7 +8,7 @@ buildscript {
plugins { plugins {
// https://mvnrepository.com/artifact/com.android.application/com.android.application.gradle.plugin?repo=google // 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 'com.android.library' version '8.0.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.21' 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 // https://mvnrepository.com/artifact/com.google.devtools.ksp/com.google.devtools.ksp.gradle.plugin