Move title declaration to each preference pages

This commit is contained in:
Suphon Thanakornpakapong
2021-04-30 11:56:10 +07:00
parent 95d509e624
commit 7ea4724b91
11 changed files with 124 additions and 51 deletions
@@ -34,6 +34,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getFormattedVersionName
import com.android.launcher3.R
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
@@ -114,6 +116,7 @@ val teamMembers = listOf(
fun About() {
val context = LocalContext.current
pageMeta.provide(Meta(title = stringResource(id = R.string.about_label)))
Column(
modifier = Modifier
.fillMaxWidth()
@@ -19,6 +19,8 @@ package app.lawnchair.ui.preferences
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getAdapter
import app.lawnchair.util.preferences.preferenceManager
import com.android.launcher3.R
@@ -27,6 +29,7 @@ import com.android.launcher3.R
@Composable
fun AppDrawerPreferences() {
val prefs = preferenceManager()
pageMeta.provide(Meta(title = stringResource(id = R.string.app_drawer_label)))
PreferenceLayout {
PreferenceGroup(heading = stringResource(id = R.string.general_label), isFirstChild = true) {
SliderPreference(
@@ -19,6 +19,8 @@ package app.lawnchair.ui.preferences
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getAdapter
import app.lawnchair.util.preferences.preferenceManager
import com.android.launcher3.R
@@ -26,6 +28,7 @@ import com.android.launcher3.R
@ExperimentalAnimationApi
@Composable
fun DockPreferences() {
pageMeta.provide(Meta(title = stringResource(id = R.string.dock_label)))
PreferenceLayout {
PreferenceGroup(heading = stringResource(id = R.string.grid), isFirstChild = true) {
SliderPreference(
@@ -19,6 +19,8 @@ package app.lawnchair.ui.preferences
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getAdapter
import app.lawnchair.util.preferences.preferenceManager
import com.android.launcher3.R
@@ -26,6 +28,7 @@ import com.android.launcher3.R
@ExperimentalAnimationApi
@Composable
fun FolderPreferences() {
pageMeta.provide(Meta(title = stringResource(id = R.string.folders_label)))
PreferenceLayout {
val prefs = preferenceManager()
PreferenceGroup(heading = stringResource(id = R.string.grid), isFirstChild = true) {
@@ -21,6 +21,8 @@ import androidx.compose.animation.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.*
import com.android.launcher3.R
@@ -28,6 +30,7 @@ import com.android.launcher3.R
@Composable
fun GeneralPreferences(navController: NavController, interactor: PreferenceInteractor) {
val prefs = preferenceManager()
pageMeta.provide(Meta(title = stringResource(id = R.string.general_label)))
PreferenceLayout {
PreferenceGroup(isFirstChild = true) {
SwitchPreference(
@@ -19,6 +19,8 @@ package app.lawnchair.ui.preferences
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getAdapter
import app.lawnchair.util.preferences.preferenceManager
import com.android.launcher3.R
@@ -27,6 +29,7 @@ import com.android.launcher3.R
@Composable
fun HomeScreenPreferences() {
val prefs = preferenceManager()
pageMeta.provide(Meta(title = stringResource(id = R.string.home_screen_label)))
PreferenceLayout {
PreferenceGroup(heading = "General", isFirstChild = true) {
SwitchPreference(
@@ -30,8 +30,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getAdapter
import app.lawnchair.util.preferences.preferenceManager
import com.android.launcher3.R
@@ -44,6 +47,7 @@ fun IconPackPreferences(interactor: PreferenceInteractor) {
val iconPacks = interactor.getIconPacks().values.toList()
val iconPackPackage = preferenceManager().iconPackPackage.getAdapter()
pageMeta.provide(Meta(title = stringResource(id = R.string.icon_pack)))
PreferenceLayout {
PreferenceGroup(isFirstChild = true) {
// TODO: Use `LazyColumn` if possible.
@@ -26,10 +26,13 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import app.lawnchair.util.Meta
import app.lawnchair.util.pageMeta
import app.lawnchair.util.preferences.getMajorVersion
import com.android.launcher3.R
@@ -44,18 +47,6 @@ object Routes {
const val ICON_PACK: String = "iconPack"
}
fun getRoutesToLabels(context: Context) =
mapOf(
Routes.PREFERENCES to context.getString(R.string.settings),
Routes.GENERAL to context.getString(R.string.general_label),
Routes.ABOUT to context.getString(R.string.about_label),
Routes.HOME_SCREEN to context.getString(R.string.home_screen_label),
Routes.DOCK to context.getString(R.string.dock_label),
Routes.APP_DRAWER to context.getString(R.string.app_drawer_label),
Routes.FOLDERS to context.getString(R.string.folders_label),
Routes.ICON_PACK to context.getString(R.string.icon_pack)
)
sealed class PreferenceCategory(
val label: String,
val description: String,
@@ -63,42 +54,42 @@ sealed class PreferenceCategory(
val route: String
) {
class General(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.GENERAL]!!,
label = context.getString(R.string.settings),
description = context.getString(R.string.general_description),
iconResource = R.drawable.ic_general,
route = Routes.GENERAL
)
class HomeScreen(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.HOME_SCREEN]!!,
label = context.getString(R.string.home_screen_label),
description = context.getString(R.string.home_screen_description),
iconResource = R.drawable.ic_home_screen,
route = Routes.HOME_SCREEN
)
class Dock(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.DOCK]!!,
label = context.getString(R.string.dock_label),
description = context.getString(R.string.dock_description),
iconResource = R.drawable.ic_dock,
route = Routes.DOCK
)
class AppDrawer(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.APP_DRAWER]!!,
label = context.getString(R.string.app_drawer_label),
description = context.getString(R.string.app_drawer_description),
iconResource = R.drawable.ic_app_drawer,
route = Routes.APP_DRAWER
)
class Folders(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.FOLDERS]!!,
label = context.getString(R.string.folders_label),
description = context.getString(R.string.folders_description),
iconResource = R.drawable.ic_folder,
route = Routes.FOLDERS
)
class About(context: Context) : PreferenceCategory(
label = getRoutesToLabels(context)[Routes.ABOUT]!!,
label = context.getString(R.string.about_label),
description = "${context.getString(R.string.derived_app_name)} ${getMajorVersion(context)}",
iconResource = R.drawable.ic_about,
route = Routes.ABOUT
@@ -127,7 +118,10 @@ fun Preferences(interactor: PreferenceInteractor = viewModel<PreferenceViewModel
) {
TopBar(navController = navController)
NavHost(navController = navController, startDestination = "preferences") {
composable(route = Routes.PREFERENCES) { PreferenceCategoryList(navController) }
composable(route = Routes.PREFERENCES) {
pageMeta.provide(Meta(title = stringResource(id = R.string.settings)))
PreferenceCategoryList(navController)
}
composable(route = Routes.HOME_SCREEN) { HomeScreenPreferences() }
composable(route = Routes.ICON_PACK) { IconPackPreferences(interactor = interactor) }
composable(route = Routes.DOCK) { DockPreferences() }
@@ -31,13 +31,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.KEY_ROUTE
import androidx.navigation.compose.currentBackStackEntryAsState
import app.lawnchair.util.pageMeta
import com.android.launcher3.R
@ExperimentalAnimationApi
@@ -45,38 +44,38 @@ import com.android.launcher3.R
fun TopBar(navController: NavController) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)
val context = LocalContext.current
val title = getRoutesToLabels(context)[currentRoute]
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.background(MaterialTheme.colors.background)
) {
AnimatedVisibility(visible = currentRoute != Routes.PREFERENCES && currentRoute != null) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(start = 8.dp)
.height(40.dp)
.width(40.dp)
.clip(CircleShape)
.clickable { navController.popBackStack() }
) {
Image(
painter = painterResource(id = R.drawable.ic_arrow_back),
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colors.onBackground)
)
pageMeta.consume { state ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.background(MaterialTheme.colors.background)
) {
AnimatedVisibility(visible = currentRoute != Routes.PREFERENCES && currentRoute != null) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(start = 8.dp)
.height(40.dp)
.width(40.dp)
.clip(CircleShape)
.clickable { navController.popBackStack() }
) {
Image(
painter = painterResource(id = R.drawable.ic_arrow_back),
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colors.onBackground)
)
}
}
Text(
text = state.title,
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(start = 16.dp),
color = MaterialTheme.colors.onSurface,
)
}
Text(
text = title ?: "",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(start = 16.dp),
color = MaterialTheme.colors.onSurface,
)
}
}
@@ -0,0 +1,46 @@
package app.lawnchair.util
import androidx.compose.runtime.*
class PropsContainer<P>(var props: P)
class SideEffect<S, P>(
val consume: @Composable (@Composable (S) -> Unit) -> Unit,
val provide: @Composable (P) -> Unit)
inline fun <S, P> createSideEffect(crossinline reducePropsToState: (List<P>) -> S): SideEffect<S, P> {
val mountedInstances = mutableListOf<PropsContainer<P>>()
var currentState = reducePropsToState(emptyList())
var onChangeHandler: (() -> Unit)? = null
val emitChange = {
currentState = reducePropsToState(mountedInstances.map { it.props })
onChangeHandler?.invoke()
}
return SideEffect(
consume = @Composable { block ->
val localState = remember { mutableStateOf(currentState) }
DisposableEffect(null) {
onChangeHandler = { localState.value = currentState }
onDispose { onChangeHandler = null }
}
block(localState.value)
},
provide = @Composable { props ->
val currentProps = remember { PropsContainer(props) }
DisposableEffect(key1 = currentProps) {
mountedInstances.add(currentProps)
onDispose {
mountedInstances.remove(currentProps)
emitChange()
}
}
DisposableEffect(key1 = props) {
currentProps.props = props
emitChange()
onDispose { }
}
}
)
}
@@ -0,0 +1,12 @@
package app.lawnchair.util
class MetaState(val title: String)
class Meta(val title: String?)
private fun getTitleFromPropsList(propsList: List<Meta>): String {
return propsList.lastOrNull()?.title ?: ""
}
val pageMeta = createSideEffect<MetaState, Meta> { propsList ->
MetaState(title = getTitleFromPropsList(propsList))
}