Use mrmans0n Compose rules to check styles (#3788)

* Use customRuleSets

* Disable ktlint_compose_modifier-missing-check

* Fix compose:vm-forwarding-check

https://mrmans0n.github.io/compose-rules/rules/#hoist-all-the-things

* Fix compose:param-order-check

https://mrmans0n.github.io/compose-rules/rules/#ordering-composable-parameters-properly

* Intro kotlinx-collections-immutable

* Fix compose:unstable-collections

https://mrmans0n.github.io/compose-rules/rules/#avoid-using-unstable-collections

* Fix compose:modifier-not-used-at-root

https://mrmans0n.github.io/compose-rules/rules/#modifiers-should-be-used-at-the-top-most-layout-of-the-component

* Fix compose:multiple-emitters-check

https://mrmans0n.github.io/compose-rules/rules/#do-not-emit-multiple-pieces-of-content

* Fix compose:compositionlocal-allowlist

https://mrmans0n.github.io/compose-rules/rules/#compositionlocals

* Enable modifier-missing-check

https://mrmans0n.github.io/compose-rules/rules/#when-should-i-expose-modifier-parameters

* Cleanups

* io.nlopez.compose.rules:ktlint:0.3.5

* Rearrange params

* Revert "Fix compose:modifier-not-used-at-root"

This reverts commit 7dee424730d58e1a75e6953dd780806750823887.

* Disable modifier-not-used-at-root for PreferenceTemplate

* Cleanups

* Remove unused modifiers

* Disable ktlint_compose_modifier-missing-check

* Disable ktlint_compose_compositionlocal-allowlist
This commit is contained in:
Goooler
2023-12-09 15:45:04 +08:00
committed by GitHub
parent 5931c9afec
commit d9af42b50e
49 changed files with 242 additions and 169 deletions
+8 -2
View File
@@ -375,6 +375,7 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2'
implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.6"
implementation 'com.github.ChickenHook:RestrictionBypass:2.2'
implementation 'dev.rikka.tools.refine:runtime:4.4.0'
@@ -438,8 +439,13 @@ ksp {
spotless {
kotlin {
ktlint()
target("lawnchair/src/**/*.kt", "baseline-profile/src/**/*.kt")
target("lawnchair/src/**/*.kt")
ktlint().customRuleSets([
"io.nlopez.compose.rules:ktlint:0.3.5",
]).editorConfigOverride([
"ktlint_compose_modifier-missing-check": "disabled",
"ktlint_compose_compositionlocal-allowlist": "disabled",
])
}
}
@@ -61,7 +61,9 @@ fun NavGraphBuilder.createBackupGraph(route: String) {
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun CreateBackupScreen(viewModel: CreateBackupViewModel) {
fun CreateBackupScreen(
viewModel: CreateBackupViewModel,
) {
val contents by viewModel.backupContents.collectAsState()
val screenshot by viewModel.screenshot.collectAsState()
val screenshotDone by viewModel.screenshotDone.collectAsState()
@@ -76,13 +76,15 @@ fun NavGraphBuilder.restoreBackupGraph(route: String) {
viewModel.init(backupUri)
onDispose { }
}
RestoreBackupScreen(viewModel)
RestoreBackupScreen()
}
}
}
@Composable
fun RestoreBackupScreen(viewModel: RestoreBackupViewModel) {
fun RestoreBackupScreen(
viewModel: RestoreBackupViewModel = viewModel(),
) {
val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT
val scrollState = rememberScrollState()
val uiState = viewModel.uiState.collectAsState().value
@@ -92,7 +94,7 @@ fun RestoreBackupScreen(viewModel: RestoreBackupViewModel) {
scrollState = if (isPortrait) null else scrollState,
) {
when (uiState) {
is RestoreBackupUiState.Success -> RestoreBackupOptions(isPortrait, uiState.backup, viewModel = viewModel)
is RestoreBackupUiState.Success -> RestoreBackupOptions(isPortrait, uiState.backup)
is RestoreBackupUiState.Loading -> {
Box(modifier = Modifier.fillMaxSize()) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
@@ -115,7 +117,7 @@ fun RestoreBackupScreen(viewModel: RestoreBackupViewModel) {
fun ColumnScope.RestoreBackupOptions(
isPortrait: Boolean,
backup: LawnchairBackup,
viewModel: RestoreBackupViewModel,
viewModel: RestoreBackupViewModel = viewModel(),
) {
val backupContents = backup.info.contents
val contents by viewModel.backupContents.collectAsState()
@@ -85,8 +85,7 @@ class SleepMethodPieAccessibility(context: Context) : SleepGestureHandler.SleepM
title = R.string.dt2s_a11y_hint_title,
description = R.string.dt2s_a11y_hint,
settingsIntent = intent,
handleClose = { close(true) },
)
) { close(true) }
}
return
}
@@ -114,8 +113,7 @@ class SleepMethodDeviceAdmin(context: Context) : SleepGestureHandler.SleepMethod
title = R.string.dt2s_admin_hint_title,
description = R.string.dt2s_admin_hint,
settingsIntent = intent,
handleClose = { close(true) },
)
) { close(true) }
}
return
}
@@ -13,7 +13,9 @@ import androidx.compose.ui.unit.dp
import app.lawnchair.ui.preferences.components.ClickableIcon
@Composable
fun OverflowMenu(block: @Composable OverflowMenuScope.() -> Unit) {
fun OverflowMenu(
block: @Composable OverflowMenuScope.() -> Unit,
) {
val showMenu = remember { mutableStateOf(false) }
val overflowMenuScope = remember { OverflowMenuScopeImpl(showMenu) }
@@ -219,16 +219,15 @@ private fun IconShapeClipboardPreferenceGroup(
@Composable
private fun ClipboardButton(
modifier: Modifier = Modifier,
label: String,
imageVector: ImageVector,
modifier: Modifier = Modifier,
description: String? = null,
enabled: Boolean = true,
imageVector: ImageVector,
onClick: () -> Unit,
) {
PreferenceTemplate(
modifier = modifier.clickable(enabled = enabled, onClick = onClick),
contentModifier = Modifier,
title = { Text(text = label) },
description = { description?.let { Text(text = it) } },
startWidget = {
@@ -247,12 +246,12 @@ private fun ClipboardButton(
@Composable
private fun IconShapeCornerPreference(
modifier: Modifier = Modifier,
title: String,
scale: Float,
onScaleChange: (Float) -> Unit,
cornerShape: IconCornerShape,
onScaleChange: (Float) -> Unit,
onCornerShapeChange: (IconCornerShape) -> Unit,
modifier: Modifier = Modifier,
) {
CornerSlider(
modifier = modifier,
@@ -268,12 +267,12 @@ private fun IconShapeCornerPreference(
@Composable
private fun CornerSlider(
modifier: Modifier = Modifier,
label: String,
value: Float,
onValueChange: (Float) -> Unit,
cornerShape: IconCornerShape,
onCornerShapeChange: (IconCornerShape) -> Unit,
modifier: Modifier = Modifier,
) {
val bottomSheetHandler = LocalBottomSheetHandler.current
val options = listOf<IconCornerShape>(
@@ -38,6 +38,7 @@ import app.lawnchair.ui.preferences.components.PreferenceLayout
import app.lawnchair.ui.preferences.components.SliderPreference
import app.lawnchair.ui.preferences.components.SwitchPreference
import com.android.launcher3.R
import kotlinx.collections.immutable.toPersistentList
object DockRoutes {
const val SEARCH_PROVIDER = "searchProvider"
@@ -116,7 +117,7 @@ private fun HotseatModePreference(
ListPreference(
adapter = adapter,
entries = entries,
entries = entries.toPersistentList(),
label = stringResource(id = R.string.hotseat_mode_label),
)
}
@@ -89,7 +89,9 @@ private enum class ContentType {
}
@Composable
fun FontSelection(fontPref: BasePreferenceManager.FontPref) {
fun FontSelection(
fontPref: BasePreferenceManager.FontPref,
) {
val context = LocalContext.current
val customFonts by remember { FontCache.INSTANCE.get(context).customFonts }.collectAsState(initial = emptyList())
val items by produceState(initialValue = emptyList<FontCache.Family>()) {
@@ -254,15 +256,7 @@ private fun FontSelectionItem(
endWidget = when {
selected && family.variants.size > 1 -> {
{
Row(
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.wrapContentWidth()
.padding(end = 16.dp),
) {
VariantDropdown(adapter = adapter, family = family)
}
VariantDropdown(adapter = adapter, family = family)
}
}
onDelete != null -> {
@@ -298,46 +292,54 @@ private fun VariantDropdown(
adapter: PreferenceAdapter<FontCache.Font>,
family: FontCache.Family,
) {
val selectedFont = adapter.state.value
var showVariants by remember { mutableStateOf(false) }
val context = LocalContext.current
DisposableEffect(family) {
val fontCache = FontCache.INSTANCE.get(context)
family.variants.forEach { fontCache.preloadFont(it.value) }
onDispose { }
}
TextButton(
onClick = { showVariants = true },
colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.onBackground),
contentPadding = VariantButtonContentPadding,
Row(
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.wrapContentWidth()
.padding(end = 16.dp),
) {
AndroidText(
modifier = Modifier.wrapContentWidth(),
update = {
it.text = selectedFont.displayName
it.setFont(selectedFont)
},
)
Icon(
imageVector = Icons.Rounded.ArrowDropDown,
contentDescription = null,
)
}
DropdownMenu(
expanded = showVariants,
onDismissRequest = { showVariants = false },
) {
family.sortedVariants.forEach { font ->
DropdownMenuItem(onClick = {
adapter.onChange(font)
showVariants = false
}) {
Text(
text = font.displayName,
fontFamily = font.composeFontFamily,
)
val selectedFont = adapter.state.value
var showVariants by remember { mutableStateOf(false) }
val context = LocalContext.current
DisposableEffect(family) {
val fontCache = FontCache.INSTANCE.get(context)
family.variants.forEach { fontCache.preloadFont(it.value) }
onDispose { }
}
TextButton(
onClick = { showVariants = true },
colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.onBackground),
contentPadding = VariantButtonContentPadding,
) {
AndroidText(
modifier = Modifier.wrapContentWidth(),
update = {
it.text = selectedFont.displayName
it.setFont(selectedFont)
},
)
Icon(
imageVector = Icons.Rounded.ArrowDropDown,
contentDescription = null,
)
}
DropdownMenu(
expanded = showVariants,
onDismissRequest = { showVariants = false },
) {
family.sortedVariants.forEach { font ->
DropdownMenuItem(onClick = {
adapter.onChange(font)
showVariants = false
}) {
Text(
text = font.displayName,
fontFamily = font.composeFontFamily,
)
}
}
}
}
@@ -40,6 +40,8 @@ import app.lawnchair.util.appComparator
import app.lawnchair.util.appsState
import com.android.launcher3.R
import java.util.Comparator.comparing
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.toPersistentSet
fun NavGraphBuilder.hiddenAppsGraph(route: String) {
preferenceGraph(route, { HiddenAppsPreferences() })
@@ -55,7 +57,7 @@ fun HiddenAppsPreferences() {
} else {
stringResource(id = R.string.hidden_apps_label_with_count, hiddenApps.size)
}
val apps by appsState(comparator = hiddenAppsComparator(hiddenApps))
val apps by appsState(comparator = hiddenAppsComparator(hiddenApps.toPersistentSet()))
val state = rememberLazyListState()
PreferenceScaffold(
label = pageTitle,
@@ -107,7 +109,7 @@ fun HiddenAppsPreferences() {
}
@Composable
fun hiddenAppsComparator(hiddenApps: Set<String>): Comparator<App> = remember {
fun hiddenAppsComparator(hiddenApps: ImmutableSet<String>): Comparator<App> = remember {
comparing<App, Int> {
if (hiddenApps.contains(it.key.toString())) 0 else 1
}.then(appComparator)
@@ -41,6 +41,7 @@ import app.lawnchair.ui.preferences.components.SwitchPreference
import app.lawnchair.util.collectAsStateBlocking
import com.android.launcher3.R
import com.android.launcher3.Utilities
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.launch
object HomeScreenRoutes {
@@ -187,7 +188,7 @@ fun HomeScreenPreferences() {
fun HomeScreenTextColorPreference() {
ListPreference(
adapter = preferenceManager2().workspaceTextColor.getAdapter(),
entries = ColorMode.entries(),
entries = ColorMode.entries().toPersistentList(),
label = stringResource(id = R.string.home_screen_text_color),
)
}
@@ -70,6 +70,7 @@ import app.lawnchair.util.getThemedIconPacksInstalled
import app.lawnchair.util.isPackageInstalled
import com.android.launcher3.R
import com.google.accompanist.drawablepainter.rememberDrawablePainter
import kotlinx.collections.immutable.toPersistentList
data class IconPackInfo(
val name: String,
@@ -190,7 +191,7 @@ fun IconPackPreferences() {
value = it,
label = { stringResource(id = it.labelResourceId) },
)
},
}.toPersistentList(),
value = ThemedIconsState.getForSettings(
themedIcons = themedIconsAdapter.state.value,
drawerThemedIcons = drawerThemedIconsEnabled,
@@ -228,7 +229,6 @@ fun IconPackGrid(
val padding = 12.dp
var iconPacksLocal = iconPacks
val themedIconPacksName = themedIconPacks.map { it.name }
val modifier = Modifier.padding(bottom = 6.dp, top = 6.dp)
if (isThemedIconPack) {
iconPacksLocal = if (drawerThemedIcons) {
@@ -259,7 +259,7 @@ fun IconPackGrid(
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(space = padding),
contentPadding = PaddingValues(horizontal = padding),
modifier = modifier.fillMaxWidth(),
modifier = Modifier.padding(bottom = 6.dp, top = 6.dp).fillMaxWidth(),
) {
itemsIndexed(iconPacksLocal, { _, item -> item.packageName }) { index, item ->
IconPackItem(
@@ -300,7 +300,7 @@ private fun getIconPackItemWidth(
fun IconPackItem(
item: IconPackInfo,
selected: Boolean,
modifier: Modifier,
modifier: Modifier = Modifier,
onClick: () -> Unit,
) {
Surface(
@@ -84,7 +84,9 @@ fun NavGraphBuilder.iconPickerGraph(route: String) {
}
@Composable
fun IconPickerPreference(packageName: String) {
fun IconPickerPreference(
packageName: String,
) {
val context = LocalContext.current
val iconPack = remember {
IconPackProvider.INSTANCE.get(context).getIconPackOrSystem(packageName)
@@ -68,7 +68,9 @@ val LocalPreferenceInteractor = staticCompositionLocalOf<PreferenceInteractor> {
}
@Composable
fun Preferences(interactor: PreferenceInteractor = viewModel<PreferenceViewModel>()) {
fun Preferences(
interactor: PreferenceInteractor = viewModel<PreferenceViewModel>(),
) {
val navController = rememberNavController()
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
val slideDistance = rememberSlideDistance()
@@ -46,6 +46,7 @@ import app.lawnchair.ui.preferences.components.SwitchPreference
import app.lawnchair.ui.theme.isSelectedThemeDark
import com.android.launcher3.R
import com.kieronquinn.app.smartspacer.sdk.SmartspacerConstants
import kotlinx.collections.immutable.toPersistentList
fun NavGraphBuilder.smartspaceGraph(route: String) {
preferenceGraph(route, { SmartspacePreferences(fromWidget = false) })
@@ -56,7 +57,9 @@ fun NavGraphBuilder.smartspaceWidgetGraph(route: String) {
}
@Composable
fun SmartspacePreferences(fromWidget: Boolean) {
fun SmartspacePreferences(
fromWidget: Boolean,
) {
val preferenceManager2 = preferenceManager2()
val smartspaceProvider = SmartspaceProvider.INSTANCE.get(LocalContext.current)
val smartspaceAdapter = preferenceManager2.enableSmartspace.getAdapter()
@@ -134,7 +137,7 @@ fun SmartspaceProviderPreference(
ListPreference(
adapter = adapter,
entries = entries,
entries = entries.toPersistentList(),
label = stringResource(id = R.string.smartspace_mode_label),
endWidget = endWidget,
)
@@ -227,7 +230,7 @@ fun SmartspaceTimeFormatPreference() {
ListPreference(
adapter = adapter,
entries = entries,
entries = entries.toPersistentList(),
label = stringResource(id = R.string.smartspace_time_format),
)
}
@@ -244,7 +247,7 @@ fun SmartspaceCalendarPreference() {
ListPreference(
adapter = adapter,
entries = entries,
entries = entries.toPersistentList(),
label = stringResource(id = R.string.smartspace_calendar),
)
}
@@ -39,7 +39,12 @@ import app.lawnchair.ui.preferences.components.PreferenceTemplate
import coil.compose.SubcomposeAsyncImage
@Composable
fun ContributorRow(name: String, description: String, photoUrl: String, url: String) {
fun ContributorRow(
name: String,
description: String,
photoUrl: String,
url: String,
) {
val context = LocalContext.current
PreferenceTemplate(
@@ -45,8 +45,8 @@ import androidx.compose.ui.unit.dp
fun LawnchairLink(
@DrawableRes iconResId: Int,
label: String,
modifier: Modifier = Modifier,
url: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
@@ -78,7 +78,10 @@ fun Acknowledgements() {
}
@Composable
fun OssLibraryItem(ossLibrary: OssLibrary, index: Int) {
fun OssLibraryItem(
ossLibrary: OssLibrary,
index: Int,
) {
val navController = LocalNavController.current
val destination = subRoute(name = "$index")
@@ -96,7 +99,9 @@ fun OssLibraryItem(ossLibrary: OssLibrary, index: Int) {
}
@Composable
fun NoticePage(index: Int) {
fun NoticePage(
index: Int,
) {
val ossLibraries by LocalPreferenceInteractor.current.ossLibraries.collectAsState()
val ossLibrary = ossLibraries.getOrNull(index)
val dataState = ossLibrary?.let { loadNotice(ossLibrary = it) }
@@ -75,7 +75,6 @@ fun AppItemPlaceholder(
widget: (@Composable () -> Unit)? = null,
) {
AppItemLayout(
widget = widget,
icon = {
Spacer(
modifier = Modifier
@@ -86,25 +85,27 @@ fun AppItemPlaceholder(
),
)
},
) {
Spacer(
modifier = Modifier
.width(120.dp)
.height(24.dp)
.placeholder(
visible = true,
highlight = PlaceholderHighlight.fade(),
),
)
}
title = {
Spacer(
modifier = Modifier
.width(120.dp)
.height(24.dp)
.placeholder(
visible = true,
highlight = PlaceholderHighlight.fade(),
),
)
},
widget = widget,
)
}
@Composable
private fun AppItemLayout(
modifier: Modifier = Modifier,
widget: (@Composable () -> Unit)? = null,
icon: @Composable () -> Unit,
title: @Composable () -> Unit,
modifier: Modifier = Modifier,
widget: (@Composable () -> Unit)? = null,
) {
PreferenceTemplate(
title = title,
@@ -11,8 +11,8 @@ fun FlagSwitchPreference(
mask: Int,
label: String,
description: String? = null,
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
onClick: (() -> Unit)? = null,
) {
SwitchPreference(
checked = flags.hasFlag(mask),
@@ -140,8 +140,8 @@ fun IconShapePreference() {
@Composable
private fun CustomIconShapePreference(
modifier: Modifier = Modifier,
iconShapeAdapter: PreferenceAdapter<IconShape>,
modifier: Modifier = Modifier,
) {
val preferenceManager2 = preferenceManager2()
@@ -169,8 +169,8 @@ private fun CustomIconShapePreference(
@Composable
private fun ModifyCustomIconShapePreference(
modifier: Modifier = Modifier,
customIconShape: IconShape?,
modifier: Modifier = Modifier,
) {
val navController = LocalNavController.current
val route = subRoute(IconShapeRoutes.CUSTOM_ICON_SHAPE_CREATOR)
@@ -220,8 +220,8 @@ private fun ModifyCustomIconShapePreference(
*/
@Composable
fun IconShapePreview(
modifier: Modifier = Modifier,
iconShape: IconShape,
modifier: Modifier = Modifier,
strokeColor: Color = MaterialTheme.colorScheme.primary,
fillColor: Color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.1f),
) {
@@ -31,13 +31,13 @@ import androidx.compose.ui.unit.dp
fun LazyListScope.preferenceGroupItems(
count: Int,
heading: (@Composable () -> String)? = null,
isFirstChild: Boolean,
key: ((index: Int) -> Any)? = null,
contentType: (index: Int) -> Any? = { null },
showDividers: Boolean = true,
dividerStartIndent: Dp = 0.dp,
dividerEndIndent: Dp = 0.dp,
heading: (@Composable () -> String)? = null,
key: ((index: Int) -> Any)? = null,
contentType: (index: Int) -> Any? = { null },
itemContent: @Composable LazyItemScope.(index: Int) -> Unit,
) {
item {
@@ -58,24 +58,24 @@ fun LazyListScope.preferenceGroupItems(
inline fun <T> LazyListScope.preferenceGroupItems(
items: List<T>,
noinline heading: (@Composable () -> String)? = null,
isFirstChild: Boolean,
noinline key: ((index: Int, item: T) -> Any)? = null,
noinline contentType: (index: Int) -> Any? = { null },
showDividers: Boolean = true,
dividerStartIndent: Dp = 0.dp,
dividerEndIndent: Dp = 0.dp,
noinline heading: (@Composable () -> String)? = null,
noinline key: ((index: Int, item: T) -> Any)? = null,
noinline contentType: (index: Int) -> Any? = { null },
crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit,
) {
preferenceGroupItems(
items.size,
heading,
isFirstChild,
if (key != null) { index: Int -> key(index, items[index]) } else null,
contentType = contentType,
showDividers = showDividers,
dividerStartIndent = dividerStartIndent,
dividerEndIndent = dividerEndIndent,
heading,
key = if (key != null) { index: Int -> key(index, items[index]) } else null,
contentType = contentType,
) {
itemContent(it, items[it])
}
@@ -31,11 +31,12 @@ import androidx.compose.ui.unit.dp
import app.lawnchair.preferences.PreferenceAdapter
import app.lawnchair.ui.AlertBottomSheetContent
import app.lawnchair.ui.util.bottomSheetHandler
import kotlinx.collections.immutable.ImmutableList
@Composable
fun <T> ListPreference(
adapter: PreferenceAdapter<T>,
entries: List<ListPreferenceEntry<T>>,
entries: ImmutableList<ListPreferenceEntry<T>>,
label: String,
enabled: Boolean = true,
description: String? = null,
@@ -54,7 +55,7 @@ fun <T> ListPreference(
@Composable
fun <T> ListPreference(
entries: List<ListPreferenceEntry<T>>,
entries: ImmutableList<ListPreferenceEntry<T>>,
value: T,
onValueChange: (T) -> Unit,
label: String,
@@ -26,7 +26,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
fun LoadingScreen(isLoading: Boolean, content: @Composable () -> Unit) {
fun LoadingScreen(
isLoading: Boolean,
content: @Composable () -> Unit,
) {
Crossfade(targetState = isLoading, label = "") {
if (it) {
Column(
@@ -43,7 +46,10 @@ fun LoadingScreen(isLoading: Boolean, content: @Composable () -> Unit) {
}
@Composable
fun <T> LoadingScreen(obj: T?, content: @Composable (T) -> Unit) {
fun <T> LoadingScreen(
obj: T?,
content: @Composable (T) -> Unit,
) {
LoadingScreen(isLoading = obj == null) {
content(obj!!)
}
@@ -25,8 +25,8 @@ import app.lawnchair.ui.preferences.LocalNavController
@Composable
fun NavigationActionPreference(
label: String,
subtitle: String? = null,
destination: String,
subtitle: String? = null,
endWidget: (@Composable () -> Unit)? = null,
) {
val navController = LocalNavController.current
@@ -19,7 +19,9 @@ import androidx.compose.ui.unit.Velocity
import app.lawnchair.ui.StretchEdgeEffect
@Composable
fun NestedScrollStretch(content: @Composable () -> Unit) {
fun NestedScrollStretch(
content: @Composable () -> Unit,
) {
val invalidateTick = remember { mutableIntStateOf(0) }
val invalidate = Runnable { invalidateTick.intValue++ }
@@ -56,7 +56,10 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
@Composable
fun NotificationDotsPreference(enabled: Boolean, serviceEnabled: Boolean) {
fun NotificationDotsPreference(
enabled: Boolean,
serviceEnabled: Boolean,
) {
val bottomSheetHandler = bottomSheetHandler
val context = LocalContext.current
val showWarning = enabled && !serviceEnabled
@@ -102,7 +105,9 @@ fun NotificationDotsPreference(enabled: Boolean, serviceEnabled: Boolean) {
}
@Composable
fun NotificationAccessConfirmation(onDismissRequest: () -> Unit) {
fun NotificationAccessConfirmation(
onDismissRequest: () -> Unit,
) {
val context = LocalContext.current
AlertBottomSheetContent(
@@ -34,9 +34,9 @@ import app.lawnchair.ui.preferences.subRoute
@Composable
fun PreferenceCategory(
label: String,
description: String? = null,
@DrawableRes iconResource: Int,
route: String,
description: String? = null,
) {
val navController = LocalNavController.current
val resolvedRoute = subRoute(name = route)
@@ -67,12 +67,14 @@ fun PreferenceGroup(
}
}
}
PreferenceGroupDescription(description, showDescription)
PreferenceGroupDescription(description = description, showDescription = showDescription)
}
}
@Composable
fun PreferenceGroupHeading(heading: String?) {
fun PreferenceGroupHeading(
heading: String?,
) {
if (heading != null) {
Column(
verticalArrangement = Arrangement.Center,
@@ -93,7 +95,10 @@ fun PreferenceGroupHeading(heading: String?) {
}
@Composable
fun PreferenceGroupDescription(description: String? = null, showDescription: Boolean = true) {
fun PreferenceGroupDescription(
description: String? = null,
showDescription: Boolean = true,
) {
description?.let {
ExpandAndShrink(visible = showDescription) {
Row(modifier = Modifier.padding(start = 32.dp, end = 32.dp, top = 16.dp)) {
@@ -31,13 +31,13 @@ import androidx.compose.ui.unit.dp
@Composable
fun PreferenceLayout(
label: String,
backArrowVisible: Boolean = true,
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(8.dp),
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
scrollState: ScrollState? = rememberScrollState(),
label: String,
actions: @Composable RowScope.() -> Unit = {},
bottomBar: @Composable () -> Unit = { BottomSpacer() },
backArrowVisible: Boolean = true,
content: @Composable ColumnScope.() -> Unit,
) {
PreferenceScaffold(
@@ -57,12 +57,12 @@ fun PreferenceLayout(
@Composable
fun PreferenceLayoutLazyColumn(
label: String,
modifier: Modifier = Modifier,
enabled: Boolean = true,
state: LazyListState = rememberLazyListState(),
label: String,
actions: @Composable RowScope.() -> Unit = {},
backArrowVisible: Boolean = true,
state: LazyListState = rememberLazyListState(),
actions: @Composable RowScope.() -> Unit = {},
content: LazyListScope.() -> Unit,
) {
PreferenceScaffold(
@@ -34,8 +34,8 @@ import com.google.accompanist.insets.ui.Scaffold
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PreferenceScaffold(
backArrowVisible: Boolean = true,
label: String,
backArrowVisible: Boolean = true,
actions: @Composable RowScope.() -> Unit = {},
bottomBar: @Composable () -> Unit = { BottomSpacer() },
content: @Composable (PaddingValues) -> Unit,
@@ -37,19 +37,20 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import app.lawnchair.ui.util.addIf
@Suppress("ktlint:compose:modifier-not-used-at-root")
@Composable
fun PreferenceTemplate(
title: @Composable () -> Unit,
modifier: Modifier = Modifier,
contentModifier: Modifier = Modifier,
title: @Composable () -> Unit,
description: @Composable () -> Unit = {},
startWidget: (@Composable () -> Unit)? = null,
endWidget: (@Composable () -> Unit)? = null,
enabled: Boolean = true,
applyPaddings: Boolean = true,
horizontalPadding: Dp = 16.dp,
verticalPadding: Dp = 16.dp,
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
description: @Composable () -> Unit = {},
startWidget: (@Composable () -> Unit)? = null,
endWidget: (@Composable () -> Unit)? = null,
) {
val contentAlphaDisabled = ContentAlpha.disabled
Column {
@@ -54,8 +54,8 @@ fun PreferenceColumn(
fun PreferenceLazyColumn(
modifier: Modifier = Modifier,
enabled: Boolean = true,
state: LazyListState = rememberLazyListState(),
isChild: Boolean = false,
state: LazyListState = rememberLazyListState(),
content: LazyListScope.() -> Unit,
) {
if (!enabled) {
@@ -23,14 +23,12 @@ fun SearchTextField(
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
isError: Boolean = false,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = MaterialTheme.shapes.small,
colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors(
@@ -38,6 +36,8 @@ fun SearchTextField(
unfocusedBorderColor = Color.Transparent,
disabledBorderColor = Color.Transparent,
),
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
) {
OutlinedTextField(
value = value,
@@ -36,8 +36,8 @@ fun SwitchPreference(
adapter: PreferenceAdapter<Boolean>,
label: String,
description: String? = null,
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
onClick: (() -> Unit)? = null,
) {
val checked = adapter.state.value
SwitchPreference(
@@ -56,8 +56,8 @@ fun SwitchPreference(
onCheckedChange: (Boolean) -> Unit,
label: String,
description: String? = null,
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
onClick: (() -> Unit)? = null,
) {
PreferenceTemplate(
modifier = Modifier.clickable(enabled = enabled) {
@@ -24,8 +24,8 @@ import app.lawnchair.ui.util.bottomSheetHandler
fun TextPreference(
adapter: PreferenceAdapter<String>,
label: String,
description: (String) -> String? = { it },
enabled: Boolean = true,
description: (String) -> String? = { it },
) {
val value = adapter.state.value
TextPreference(
@@ -42,8 +42,8 @@ fun TextPreference(
value: String,
onChange: (String) -> Unit,
label: String,
description: (String) -> String? = { it },
enabled: Boolean = true,
description: (String) -> String? = { it },
) {
val bottomSheetHandler = bottomSheetHandler
PreferenceTemplate(
@@ -6,6 +6,7 @@ import app.lawnchair.preferences.getAdapter
import app.lawnchair.preferences.preferenceManager
import com.android.launcher3.R
import com.android.launcher3.Utilities
import kotlinx.collections.immutable.toPersistentList
object ThemeChoice {
const val LIGHT = "light"
@@ -31,7 +32,7 @@ val themeEntries = listOf(
fun ThemePreference() {
ListPreference(
adapter = preferenceManager().launcherTheme.getAdapter(),
entries = themeEntries,
entries = themeEntries.toPersistentList(),
label = stringResource(id = R.string.theme_label),
)
}
@@ -47,8 +47,8 @@ import androidx.compose.ui.unit.dp
@Composable
fun TopBar(
backArrowVisible: Boolean,
scrollBehavior: TopAppBarScrollBehavior? = null,
label: String,
scrollBehavior: TopAppBarScrollBehavior? = null,
actions: @Composable RowScope.() -> Unit = {},
) {
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
@@ -24,7 +24,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun WallpaperPreview(modifier: Modifier = Modifier) {
fun WallpaperPreview(
modifier: Modifier = Modifier,
) {
val painter = rememberDrawablePainter(wallpaperDrawable())
Image(
painter = painter,
@@ -10,8 +10,8 @@ import androidx.compose.ui.Modifier
@Composable
fun WarningPreference(
modifier: Modifier = Modifier,
text: String,
modifier: Modifier = Modifier,
) {
PreferenceTemplate(
modifier = modifier,
@@ -17,10 +17,10 @@ private const val CONTRAST_THRESHOLD = 1.5
*/
@Composable
fun ColorContrastWarning(
modifier: Modifier = Modifier,
foregroundColor: ColorOption,
backgroundColor: ColorOption,
text: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val foregroundColorInt = foregroundColor.colorPreferenceEntry.lightColor(context)
@@ -40,10 +40,10 @@ fun ColorContrastWarning(
*/
@Composable
fun ColorContrastWarning(
modifier: Modifier = Modifier,
@ColorInt foregroundColor: Int,
@ColorInt backgroundColor: Int,
text: String,
modifier: Modifier = Modifier,
) {
val enoughContrast = if (foregroundColor != 0 && backgroundColor != 0) {
ColorUtils.calculateContrast(
@@ -1,8 +1,10 @@
package app.lawnchair.ui.preferences.components.colorpreference
import app.lawnchair.theme.color.ColorOption
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
val staticColors = listOf(
val staticColors: ImmutableList<ColorPreferenceEntry<ColorOption>> = listOf(
ColorOption.CustomColor(0xFFF32020),
ColorOption.CustomColor(0xFFF20D69),
ColorOption.CustomColor(0xFF7452FF),
@@ -15,10 +17,13 @@ val staticColors = listOf(
ColorOption.CustomColor(0xFFFF9800),
ColorOption.CustomColor(0xFF7C5445),
ColorOption.CustomColor(0xFF67818E),
).map(ColorOption::colorPreferenceEntry)
).asSequence().map(ColorOption::colorPreferenceEntry).toPersistentList()
val dynamicColors = listOf(ColorOption.SystemAccent, ColorOption.WallpaperPrimary)
val dynamicColors: ImmutableList<ColorPreferenceEntry<ColorOption>> = listOf(ColorOption.SystemAccent, ColorOption.WallpaperPrimary)
.asSequence()
.filter(ColorOption::isSupported)
.map(ColorOption::colorPreferenceEntry)
.toPersistentList()
val dynamicColorsWithDefault = dynamicColors + listOf(ColorOption.Default.colorPreferenceEntry)
val dynamicColorsWithDefault: ImmutableList<ColorPreferenceEntry<ColorOption>> =
(dynamicColors.asSequence() + ColorOption.Default.colorPreferenceEntry).toPersistentList()
@@ -37,7 +37,9 @@ import com.patrykmichalik.opto.domain.Preference
* @see ColorSelection
*/
@Composable
fun ColorPreference(preference: Preference<ColorOption, String, Preferences.Key<String>>) {
fun ColorPreference(
preference: Preference<ColorOption, String, Preferences.Key<String>>,
) {
val modelList = ColorPreferenceModelList.INSTANCE.get(LocalContext.current)
val model = modelList[preference.key.name]
val adapter: PreferenceAdapter<ColorOption> = model.prefObject.getAdapter()
@@ -38,6 +38,8 @@ import app.lawnchair.ui.preferences.components.colorpreference.pickers.SwatchGri
import app.lawnchair.ui.preferences.preferenceGraph
import com.android.launcher3.R
import com.patrykmichalik.opto.domain.Preference
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.launch
fun NavGraphBuilder.colorSelectionGraph(route: String) {
@@ -56,7 +58,7 @@ fun NavGraphBuilder.colorSelectionGraph(route: String) {
ColorSelection(
label = stringResource(id = model.labelRes),
preference = model.prefObject,
dynamicEntries = model.dynamicEntries,
dynamicEntries = model.dynamicEntries.toPersistentList(),
)
}
}
@@ -67,8 +69,8 @@ fun NavGraphBuilder.colorSelectionGraph(route: String) {
fun ColorSelection(
label: String,
preference: Preference<ColorOption, String, *>,
dynamicEntries: List<ColorPreferenceEntry<ColorOption>> = dynamicColors,
staticEntries: List<ColorPreferenceEntry<ColorOption>> = staticColors,
dynamicEntries: ImmutableList<ColorPreferenceEntry<ColorOption>> = dynamicColors,
staticEntries: ImmutableList<ColorPreferenceEntry<ColorOption>> = staticColors,
) {
val adapter = preference.getAdapter()
val appliedColor = adapter.state.value
@@ -79,8 +79,8 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun CustomColorPicker(
modifier: Modifier = Modifier,
selectedColor: Int,
modifier: Modifier = Modifier,
onSelect: (Int) -> Unit,
) {
val focusManager = LocalFocusManager.current
@@ -208,8 +208,8 @@ fun CustomColorPicker(
@Composable
private fun HexColorPicker(
modifier: Modifier = Modifier,
textFieldValue: TextFieldValue,
modifier: Modifier = Modifier,
onTextFieldValueChange: (TextFieldValue) -> Unit,
) {
val context = LocalContext.current
@@ -353,9 +353,9 @@ private fun HsvColorPicker(
@Composable
private fun RgbColorPicker(
selectedColor: Int,
selectedColorCompose: Color = Color(selectedColor),
onSelectedColorChange: () -> Unit,
onSliderValuesChange: (Int) -> Unit,
selectedColorCompose: Color = Color(selectedColor),
) {
var red by remember { mutableIntStateOf(selectedColor.red) }
var green by remember { mutableIntStateOf(selectedColor.green) }
@@ -16,10 +16,11 @@ import app.lawnchair.ui.preferences.components.PreferenceTemplate
import app.lawnchair.ui.preferences.components.colorpreference.ColorDot
import app.lawnchair.ui.preferences.components.colorpreference.ColorPreferenceEntry
import com.android.launcher3.R
import kotlinx.collections.immutable.ImmutableList
@Composable
fun PresetsList(
dynamicEntries: List<ColorPreferenceEntry<ColorOption>>,
dynamicEntries: ImmutableList<ColorPreferenceEntry<ColorOption>>,
onPresetClick: (ColorOption) -> Unit,
isPresetSelected: (ColorOption) -> Boolean,
) {
@@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
import app.lawnchair.ui.preferences.components.PreferenceGroup
import app.lawnchair.ui.preferences.components.colorpreference.ColorPreferenceEntry
import com.android.launcher3.R
import kotlinx.collections.immutable.ImmutableList
object SwatchGridDefaults {
val GutterSize = 12.dp
@@ -37,11 +38,11 @@ object SwatchGridDefaults {
@Composable
fun <T> SwatchGrid(
modifier: Modifier = Modifier,
contentModifier: Modifier = Modifier,
entries: List<ColorPreferenceEntry<T>>,
entries: ImmutableList<ColorPreferenceEntry<T>>,
onSwatchClick: (T) -> Unit,
isSwatchSelected: (T) -> Boolean,
modifier: Modifier = Modifier,
contentModifier: Modifier = Modifier,
) {
val columnCount = SwatchGridDefaults.COLUMN_COUNT
val rowCount = (entries.size - 1) / columnCount + 1
@@ -87,9 +88,9 @@ fun <T> SwatchGrid(
@Composable
fun <T> ColorSwatch(
entry: ColorPreferenceEntry<T>,
modifier: Modifier = Modifier,
onClick: () -> Unit,
selected: Boolean,
modifier: Modifier = Modifier,
) {
val color = if (MaterialTheme.colors.isLight) {
entry.lightColor(LocalContext.current)
@@ -120,7 +120,9 @@ class BottomSheetHandler(
)
@Composable
fun StatusBarOffset(content: @Composable () -> Unit) {
fun StatusBarOffset(
content: @Composable () -> Unit,
) {
val statusBar = WindowInsets.statusBars.getTop(LocalDensity.current)
val displayCutout = WindowInsets.displayCutout.getTop(LocalDensity.current)
val statusBarHeight = max(statusBar, displayCutout)
@@ -9,7 +9,9 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.lifecycle.Lifecycle
@Composable
fun BackHandler(onBack: () -> Unit) {
fun BackHandler(
onBack: () -> Unit,
) {
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
val currentOnBack by rememberUpdatedState(onBack)
val resumed = lifecycleState().isAtLeast(Lifecycle.State.RESUMED)
@@ -78,7 +78,7 @@ class ComposeBottomSheet<T>(context: Context) :
) {
container.setContent {
Providers {
ContentWrapper(contentPaddings) {
ContentWrapper(contentPaddings = contentPaddings) {
content(this)
}
}
@@ -188,7 +188,9 @@ class ComposeBottomSheet<T>(context: Context) :
}
@Composable
private fun Providers(content: @Composable () -> Unit) {
private fun Providers(
content: @Composable () -> Unit,
) {
LawnchairTheme {
ProvideLifecycleState {
CompositionLocalProvider(