Merge pull request #2139
This commit is contained in:
@@ -201,7 +201,7 @@
|
||||
|
||||
<activity
|
||||
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
||||
android:theme="@style/Theme.AppCompat.DayNight" />
|
||||
android:theme="@style/Theme.Acknowledgements" />
|
||||
|
||||
<activity
|
||||
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
|
||||
|
||||
@@ -6,4 +6,10 @@
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
||||
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Acknowledgements" parent="Base.Theme.Acknowledgements">
|
||||
<item name="android:colorBackground">@color/black_900</item>
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
|
||||
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -13,4 +13,16 @@
|
||||
<item name="android:navigationBarColor" tools:ignore="NewApi">?android:attr/colorBackground</item>
|
||||
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
<style name="Theme.Acknowledgements" parent="Base.Theme.Acknowledgements">
|
||||
<item name="android:colorBackground">@color/white_50</item>
|
||||
</style>
|
||||
|
||||
<style name="Base.Theme.Acknowledgements" parent="Theme.AppCompat.DayNight">
|
||||
<item name="android:statusBarColor" tools:ignore="NewApi">?android:attr/colorBackground</item>
|
||||
<item name="colorPrimary">?android:attr/colorBackground</item>
|
||||
<item name="android:windowLightStatusBar" tools:ignore="NewApi">true</item>
|
||||
<item name="android:navigationBarColor" tools:ignore="NewApi">?android:attr/colorBackground</item>
|
||||
<item name="android:windowLightNavigationBar" tools:ignore="NewApi">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -19,14 +19,26 @@ package app.lawnchair.ui.preferences
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.SliderPreference
|
||||
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
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.appDrawerGraph(route: String) {
|
||||
preferenceGraph(route, { AppDrawerPreferences() })
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@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,13 +19,25 @@ package app.lawnchair.ui.preferences
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.SliderPreference
|
||||
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
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.dockGraph(route: String) {
|
||||
preferenceGraph(route, { DockPreferences() })
|
||||
}
|
||||
|
||||
@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,13 +19,25 @@ package app.lawnchair.ui.preferences
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.SliderPreference
|
||||
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
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.folderGraph(route: String) {
|
||||
preferenceGraph(route, { FolderPreferences() })
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
||||
@@ -20,14 +20,34 @@ import android.os.Build
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.NavigationActionPreference
|
||||
import app.lawnchair.ui.preferences.components.NotificationDotsPreference
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.SliderPreference
|
||||
import app.lawnchair.ui.preferences.components.SwitchPreference
|
||||
import app.lawnchair.util.Meta
|
||||
import app.lawnchair.util.pageMeta
|
||||
import app.lawnchair.util.preferences.*
|
||||
import com.android.launcher3.R
|
||||
|
||||
object GeneralRoutes {
|
||||
const val ICON_PACK = "iconPack"
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.generalGraph(route: String) {
|
||||
preferenceGraph(route, { GeneralPreferences() }) { subRoute ->
|
||||
iconPackGraph(route = subRoute(GeneralRoutes.ICON_PACK))
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun GeneralPreferences(navController: NavController, interactor: PreferenceInteractor) {
|
||||
fun GeneralPreferences() {
|
||||
val prefs = preferenceManager()
|
||||
pageMeta.provide(Meta(title = stringResource(id = R.string.general_label)))
|
||||
PreferenceLayout {
|
||||
PreferenceGroup(isFirstChild = true) {
|
||||
SwitchPreference(
|
||||
@@ -35,11 +55,10 @@ fun GeneralPreferences(navController: NavController, interactor: PreferenceInter
|
||||
label = stringResource(id = R.string.home_screen_rotation_label),
|
||||
description = stringResource(id = R.string.home_screen_rotaton_description)
|
||||
)
|
||||
NotificationDotsPreference(interactor)
|
||||
NotificationDotsPreference()
|
||||
NavigationActionPreference(
|
||||
label = stringResource(id = R.string.icon_pack),
|
||||
navController = navController,
|
||||
destination = Routes.ICON_PACK,
|
||||
destination = subRoute(name = GeneralRoutes.ICON_PACK),
|
||||
showDivider = false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,14 +19,27 @@ package app.lawnchair.ui.preferences
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.SliderPreference
|
||||
import app.lawnchair.ui.preferences.components.SwitchPreference
|
||||
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
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.homeScreenGraph(route: String) {
|
||||
preferenceGraph(route, { HomeScreenPreferences() })
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun HomeScreenPreferences() {
|
||||
val prefs = preferenceManager()
|
||||
pageMeta.provide(Meta(title = stringResource(id = R.string.home_screen_label)))
|
||||
PreferenceLayout {
|
||||
PreferenceGroup(heading = "General", isFirstChild = true) {
|
||||
SwitchPreference(
|
||||
|
||||
@@ -25,25 +25,40 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
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 androidx.navigation.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.components.PreferenceTemplate
|
||||
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
|
||||
|
||||
data class IconPackInfo(val name: String, val packageName: String, val icon: Drawable)
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.iconPackGraph(route: String) {
|
||||
preferenceGraph(route, { IconPackPreferences() })
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun IconPackPreferences(interactor: PreferenceInteractor) {
|
||||
val iconPacks = interactor.getIconPacks().values.toList()
|
||||
fun IconPackPreferences() {
|
||||
val interactor = LocalPreferenceInteractor.current
|
||||
val iconPacks = remember { interactor.getIconPacks() }
|
||||
val iconPackPackage = preferenceManager().iconPackPackage.getAdapter()
|
||||
|
||||
pageMeta.provide(Meta(title = stringResource(id = R.string.icon_pack)))
|
||||
PreferenceLayout {
|
||||
PreferenceGroup(isFirstChild = true) {
|
||||
// TODO: Use `LazyColumn` if possible.
|
||||
|
||||
@@ -21,5 +21,5 @@ import androidx.compose.runtime.State
|
||||
interface PreferenceInteractor {
|
||||
val notificationDotsEnabled: State<Boolean>
|
||||
|
||||
fun getIconPacks(): MutableMap<String, IconPackInfo>
|
||||
fun getIconPacks(): List<IconPackInfo>
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class PreferenceViewModel(application: Application) : AndroidViewModel(applicati
|
||||
override val notificationDotsEnabled: MutableState<Boolean> =
|
||||
mutableStateOf(enabledNotificationListeners?.contains(lawnchairNotificationListener.flattenToString()) == true)
|
||||
|
||||
override fun getIconPacks(): MutableMap<String, IconPackInfo> {
|
||||
override fun getIconPacks(): List<IconPackInfo> {
|
||||
val pm = getApplication<Application>().packageManager
|
||||
val iconPacks: MutableMap<String, IconPackInfo> = HashMap()
|
||||
val list: MutableList<ResolveInfo> = pm.queryIntentActivities(Intent("com.novalauncher.THEME"), 0)
|
||||
@@ -51,9 +51,6 @@ class PreferenceViewModel(application: Application) : AndroidViewModel(applicati
|
||||
pm.queryIntentActivities(Intent("android.intent.action.MAIN").addCategory("com.anddoes.launcher.THEME"), 0)
|
||||
)
|
||||
|
||||
iconPacks["system"] =
|
||||
IconPackInfo("System Icons", "", AppCompatResources.getDrawable(getApplication(), R.drawable.ic_launcher_home)!!)
|
||||
|
||||
for (info in list) {
|
||||
iconPacks[info.activityInfo.packageName] = IconPackInfo(
|
||||
info.loadLabel(pm).toString(),
|
||||
@@ -62,6 +59,17 @@ class PreferenceViewModel(application: Application) : AndroidViewModel(applicati
|
||||
)
|
||||
}
|
||||
|
||||
return iconPacks
|
||||
val iconPackList = iconPacks.values.toMutableList()
|
||||
iconPackList.sortBy { it.name }
|
||||
iconPackList.add(
|
||||
0,
|
||||
IconPackInfo(
|
||||
"System Icons",
|
||||
"",
|
||||
AppCompatResources.getDrawable(getApplication(), R.drawable.ic_launcher_home)!!
|
||||
)
|
||||
)
|
||||
|
||||
return iconPackList
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,22 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import app.lawnchair.ui.preferences.about.About
|
||||
import app.lawnchair.ui.preferences.about.aboutGraph
|
||||
import app.lawnchair.ui.preferences.components.PreferenceCategoryList
|
||||
import app.lawnchair.ui.preferences.components.SystemUi
|
||||
import app.lawnchair.ui.preferences.components.TopBar
|
||||
import app.lawnchair.util.Meta
|
||||
import app.lawnchair.util.pageMeta
|
||||
import app.lawnchair.util.preferences.getMajorVersion
|
||||
import com.android.launcher3.R
|
||||
|
||||
@@ -41,21 +52,8 @@ object Routes {
|
||||
const val DOCK: String = "dock"
|
||||
const val APP_DRAWER: String = "appDrawer"
|
||||
const val FOLDERS: String = "folders"
|
||||
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 +61,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
|
||||
@@ -114,6 +112,14 @@ fun getPreferenceCategories(context: Context) = listOf(
|
||||
PreferenceCategory.About(context)
|
||||
)
|
||||
|
||||
val LocalNavController = compositionLocalOf<NavController> {
|
||||
error("CompositionLocal LocalNavController not present")
|
||||
}
|
||||
|
||||
val LocalPreferenceInteractor = compositionLocalOf<PreferenceInteractor> {
|
||||
error("CompositionLocal LocalPreferenceInteractor not present")
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun Preferences(interactor: PreferenceInteractor = viewModel<PreferenceViewModel>(), window: Window) {
|
||||
@@ -125,20 +131,22 @@ fun Preferences(interactor: PreferenceInteractor = viewModel<PreferenceViewModel
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colors.background)
|
||||
) {
|
||||
TopBar(navController = navController)
|
||||
NavHost(navController = navController, startDestination = "preferences") {
|
||||
composable(route = Routes.PREFERENCES) { PreferenceCategoryList(navController) }
|
||||
composable(route = Routes.HOME_SCREEN) { HomeScreenPreferences() }
|
||||
composable(route = Routes.ICON_PACK) { IconPackPreferences(interactor = interactor) }
|
||||
composable(route = Routes.DOCK) { DockPreferences() }
|
||||
composable(route = Routes.APP_DRAWER) { AppDrawerPreferences() }
|
||||
composable(route = Routes.FOLDERS) { FolderPreferences() }
|
||||
composable(route = Routes.ABOUT) { About() }
|
||||
composable(route = Routes.GENERAL) {
|
||||
GeneralPreferences(
|
||||
navController = navController,
|
||||
interactor = interactor
|
||||
)
|
||||
CompositionLocalProvider(
|
||||
LocalNavController provides navController,
|
||||
LocalPreferenceInteractor provides interactor,
|
||||
) {
|
||||
TopBar()
|
||||
NavHost(navController = navController, startDestination = "preferences") {
|
||||
composable(route = Routes.PREFERENCES) {
|
||||
pageMeta.provide(Meta(title = stringResource(id = R.string.settings)))
|
||||
PreferenceCategoryList(navController)
|
||||
}
|
||||
generalGraph(route = Routes.GENERAL)
|
||||
homeScreenGraph(route = Routes.HOME_SCREEN)
|
||||
dockGraph(route = Routes.DOCK)
|
||||
appDrawerGraph(route = Routes.APP_DRAWER)
|
||||
folderGraph(route = Routes.FOLDERS)
|
||||
aboutGraph(route = Routes.ABOUT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.about
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.annotation.StringRes
|
||||
@@ -34,6 +34,12 @@ 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.NavGraphBuilder
|
||||
import app.lawnchair.ui.preferences.components.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.ClickListenerPreference
|
||||
import app.lawnchair.ui.preferences.preferenceGraph
|
||||
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
|
||||
@@ -109,11 +115,17 @@ val teamMembers = listOf(
|
||||
),
|
||||
)
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
fun NavGraphBuilder.aboutGraph(route: String) {
|
||||
preferenceGraph(route, { About() })
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun About() {
|
||||
val context = LocalContext.current
|
||||
|
||||
pageMeta.provide(Meta(title = stringResource(id = R.string.about_label)))
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.about
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.about
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
+2
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.about
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -30,6 +30,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.lawnchair.ui.preferences.components.PreferenceTemplate
|
||||
import com.google.accompanist.glide.GlideImage
|
||||
|
||||
@Composable
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.about
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
+17
-6
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
@@ -28,15 +28,17 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.navigate
|
||||
import app.lawnchair.ui.preferences.LocalNavController
|
||||
|
||||
@Composable
|
||||
fun NavigationActionPreference(
|
||||
label: String,
|
||||
subtitle: String? = null,
|
||||
navController: NavController,
|
||||
destination: String,
|
||||
showDivider: Boolean = true
|
||||
) =
|
||||
) {
|
||||
val navController = LocalNavController.current
|
||||
|
||||
PreferenceTemplate(height = if (subtitle != null) 72.dp else 52.dp, showDivider = showDivider) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@@ -46,11 +48,20 @@ fun NavigationActionPreference(
|
||||
.clickable { navController.navigate(route = destination) }
|
||||
.padding(start = 16.dp, end = 16.dp),
|
||||
) {
|
||||
Text(text = label, style = MaterialTheme.typography.subtitle1, color = MaterialTheme.colors.onBackground)
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.subtitle1,
|
||||
color = MaterialTheme.colors.onBackground
|
||||
)
|
||||
subtitle?.let {
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
|
||||
Text(text = it, style = MaterialTheme.typography.body2, color = MaterialTheme.colors.onBackground)
|
||||
Text(
|
||||
text = it,
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
@@ -32,15 +32,17 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.os.bundleOf
|
||||
import app.lawnchair.ui.preferences.LocalPreferenceInteractor
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.notification.NotificationListener
|
||||
import android.provider.Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS as actionNotificationListenerSettings
|
||||
|
||||
@Composable
|
||||
fun NotificationDotsPreference(interactor: PreferenceInteractor) {
|
||||
fun NotificationDotsPreference() {
|
||||
val context = LocalContext.current
|
||||
val extraFragmentArgKey = ":settings:fragment_args_key"
|
||||
val extraShowFragmentArgs = ":settings:show_fragment_args"
|
||||
val interactor = LocalPreferenceInteractor.current
|
||||
|
||||
fun onClick() {
|
||||
val intent = if (interactor.notificationDotsEnabled.value) {
|
||||
+2
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.navigate
|
||||
import app.lawnchair.ui.preferences.getPreferenceCategories
|
||||
|
||||
@Composable
|
||||
fun PreferenceCategoryList(navController: NavController) {
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Divider
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
+36
-35
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.lawnchair.ui.preferences
|
||||
package app.lawnchair.ui.preferences.components
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
@@ -31,52 +31,53 @@ 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.ui.preferences.LocalNavController
|
||||
import app.lawnchair.ui.preferences.Routes
|
||||
import app.lawnchair.util.pageMeta
|
||||
import com.android.launcher3.R
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun TopBar(navController: NavController) {
|
||||
fun TopBar() {
|
||||
val navController = LocalNavController.current
|
||||
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,38 @@
|
||||
package app.lawnchair.ui.preferences
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
|
||||
inline fun NavGraphBuilder.preferenceGraph(
|
||||
route: String,
|
||||
crossinline root: @Composable () -> Unit,
|
||||
crossinline block: NavGraphBuilder.(subRoute: (String) -> String) -> Unit = { }
|
||||
) {
|
||||
val subRoute: (String) -> String = { name -> "$route/$name" }
|
||||
val rootRoute = subRoute("root")
|
||||
navigation(startDestination = rootRoute, route) {
|
||||
composable(route = rootRoute) {
|
||||
CompositionLocalProvider(LocalRoute provides route) {
|
||||
root()
|
||||
}
|
||||
}
|
||||
block(subRoute)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun NavGraphBuilder.root(crossinline content: @Composable () -> Unit) {
|
||||
composable(route = "") {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
val LocalRoute = compositionLocalOf { "" }
|
||||
|
||||
@Composable
|
||||
fun subRoute(name: String): String {
|
||||
return "${LocalRoute.current}/$name"
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package app.lawnchair.util.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.currentComposer
|
||||
import com.android.launcher3.InvariantDeviceProfile
|
||||
import com.android.launcher3.Utilities
|
||||
import java.lang.ClassCastException
|
||||
@@ -26,16 +24,23 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
}
|
||||
|
||||
interface PreferenceChangeListener {
|
||||
fun onPreferenceChange(pref: BasePref<*>)
|
||||
fun onPreferenceChange(pref: PrefEntry<*>)
|
||||
}
|
||||
|
||||
abstract inner class BasePref<T>(val key: String, private val primaryListener: ChangeListener?) {
|
||||
interface PrefEntry<T> {
|
||||
val defaultValue: T
|
||||
|
||||
fun get(): T
|
||||
fun set(newValue: T)
|
||||
|
||||
fun addListener(listener: PreferenceChangeListener)
|
||||
fun removeListener(listener: PreferenceChangeListener)
|
||||
}
|
||||
|
||||
abstract inner class BasePref<T>(val key: String, private val primaryListener: ChangeListener?) : PrefEntry<T> {
|
||||
protected var loaded = false
|
||||
private val listeners = WeakHashMap<PreferenceChangeListener, Boolean>()
|
||||
|
||||
abstract fun get(): T
|
||||
abstract fun set(newValue: T)
|
||||
|
||||
fun onSharedPreferenceChange() {
|
||||
loaded = false
|
||||
primaryListener?.invoke()
|
||||
@@ -44,18 +49,18 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
}
|
||||
}
|
||||
|
||||
fun addListener(listener: PreferenceChangeListener) {
|
||||
override fun addListener(listener: PreferenceChangeListener) {
|
||||
listeners[listener] = true
|
||||
}
|
||||
|
||||
fun removeListener(listener: PreferenceChangeListener) {
|
||||
override fun removeListener(listener: PreferenceChangeListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
}
|
||||
|
||||
inner class StringPref(
|
||||
key: String,
|
||||
private val defaultValue: String,
|
||||
override val defaultValue: String,
|
||||
primaryListener: ChangeListener? = null
|
||||
) : BasePref<String>(key, primaryListener) {
|
||||
private var currentValue = ""
|
||||
@@ -80,7 +85,7 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
|
||||
inner class BoolPref(
|
||||
key: String,
|
||||
private val defaultValue: Boolean,
|
||||
override val defaultValue: Boolean,
|
||||
primaryListener: ChangeListener? = null
|
||||
) : BasePref<Boolean>(key, primaryListener) {
|
||||
private var currentValue = false
|
||||
@@ -105,9 +110,10 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
|
||||
open inner class IntPref(
|
||||
key: String,
|
||||
private val defaultValue: Int,
|
||||
private val defaultValueInternal: Int,
|
||||
primaryListener: ChangeListener? = null
|
||||
) : BasePref<Int>(key, primaryListener) {
|
||||
override val defaultValue = defaultValueInternal
|
||||
private var currentValue = 0
|
||||
|
||||
init {
|
||||
@@ -117,9 +123,9 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
override fun get(): Int {
|
||||
if (!loaded) {
|
||||
currentValue = try {
|
||||
sp.getInt(key, defaultValue)
|
||||
sp.getInt(key, defaultValueInternal)
|
||||
} catch (e: ClassCastException) {
|
||||
sp.getFloat(key, defaultValue.toFloat()).toInt()
|
||||
sp.getFloat(key, defaultValueInternal.toFloat()).toInt()
|
||||
}
|
||||
loaded = true
|
||||
}
|
||||
@@ -134,30 +140,45 @@ abstract class BasePreferenceManager(context: Context) : SharedPreferences.OnSha
|
||||
|
||||
inner class IdpIntPref(
|
||||
key: String,
|
||||
private val defaultValue: InvariantDeviceProfile.() -> Int,
|
||||
private val selectDefaultValue: InvariantDeviceProfile.() -> Int,
|
||||
primaryListener: ChangeListener? = null
|
||||
) : IntPref(key, -1, primaryListener) {
|
||||
override val defaultValue: Int
|
||||
get() = error("unsupported")
|
||||
|
||||
override fun get(): Int {
|
||||
error("unsupported")
|
||||
}
|
||||
|
||||
override fun set(newValue: Int) {
|
||||
error("unsupported")
|
||||
}
|
||||
|
||||
fun defaultValue(idp: InvariantDeviceProfile): Int {
|
||||
return selectDefaultValue(idp)
|
||||
}
|
||||
|
||||
fun get(idp: InvariantDeviceProfile): Int {
|
||||
val value = get()
|
||||
val value = super.get()
|
||||
return if (value == -1) {
|
||||
defaultValue(idp)
|
||||
selectDefaultValue(idp)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fun set(newValue: Int, idp: InvariantDeviceProfile) {
|
||||
if (newValue == defaultValue(idp)) {
|
||||
set(-1)
|
||||
if (newValue == selectDefaultValue(idp)) {
|
||||
super.set(-1)
|
||||
} else {
|
||||
set(newValue)
|
||||
super.set(newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class FloatPref(
|
||||
key: String,
|
||||
private val defaultValue: Float,
|
||||
override val defaultValue: Float,
|
||||
primaryListener: ChangeListener? = null
|
||||
) : BasePref<Float>(key, primaryListener) {
|
||||
private var currentValue = 0f
|
||||
|
||||
@@ -16,7 +16,7 @@ class PreferenceAdapter<T>(
|
||||
state.value = newValue
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(pref: BasePreferenceManager.BasePref<*>) {
|
||||
override fun onPreferenceChange(pref: BasePreferenceManager.PrefEntry<*>) {
|
||||
state.value = get()
|
||||
}
|
||||
}
|
||||
@@ -29,18 +29,18 @@ fun BasePreferenceManager.IdpIntPref.getAdapter(): PreferenceAdapter<Float> {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> BasePreferenceManager.BasePref<T>.getAdapter(): PreferenceAdapter<T> {
|
||||
fun <T> BasePreferenceManager.PrefEntry<T>.getAdapter(): PreferenceAdapter<T> {
|
||||
return getAdapter(this, ::get, ::set)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> BasePreferenceManager.BasePref<T>.observeAsState(): State<T> {
|
||||
fun <T> BasePreferenceManager.PrefEntry<T>.observeAsState(): State<T> {
|
||||
return getAdapter().state
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun <T> getAdapter(
|
||||
pref: BasePreferenceManager.BasePref<*>,
|
||||
pref: BasePreferenceManager.PrefEntry<*>,
|
||||
get: () -> T,
|
||||
set: (T) -> Unit
|
||||
): PreferenceAdapter<T> {
|
||||
|
||||
Reference in New Issue
Block a user