diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
index f4121a35..de855a2a 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
@@ -37,6 +37,8 @@ fun AssistantScaffold(
modifier: Modifier = Modifier,
darkStatusBarIcons: Boolean = false,
darkNavBarIcons: Boolean = false,
+ bottomSearchBar: Boolean = false,
+ reverseSearchResults: Boolean = false,
) {
val viewModel: LauncherScaffoldVM = viewModel()
@@ -54,15 +56,6 @@ fun AssistantScaffold(
}
}
- val bottomSearchBar by remember {
- viewModel.dataStore.data.map { it.appearance.layout != Settings.AppearanceSettings.Layout.PullDown }
- }.collectAsState(null)
-
- val reverseResults by remember {
- viewModel.dataStore.data.map { it.appearance.layout != Settings.AppearanceSettings.Layout.PullDown }
- }.collectAsState(null)
-
-
val searchState = rememberLazyListState()
val isSearchAtStart by remember {
@@ -79,14 +72,11 @@ fun AssistantScaffold(
}
}
- if (reverseResults == null || bottomSearchBar == null) return
-
-
val searchBarLevel by remember {
derivedStateOf {
when {
- reverseResults == bottomSearchBar && isSearchAtStart -> SearchBarLevel.Active
- reverseResults != bottomSearchBar && isSearchAtEnd -> SearchBarLevel.Active
+ reverseSearchResults == bottomSearchBar && isSearchAtStart -> SearchBarLevel.Active
+ reverseSearchResults != bottomSearchBar && isSearchAtEnd -> SearchBarLevel.Active
else -> SearchBarLevel.Raised
}
}
@@ -95,7 +85,7 @@ fun AssistantScaffold(
val systemUiController = rememberSystemUiController()
val showStatusBarScrim by remember {
derivedStateOf {
- if (reverseResults == true) {
+ if (reverseSearchResults) {
!isSearchAtEnd
} else {
!isSearchAtStart
@@ -104,7 +94,7 @@ fun AssistantScaffold(
}
val showNavBarScrim by remember {
derivedStateOf {
- if (reverseResults == true) {
+ if (reverseSearchResults) {
!isSearchAtStart
} else {
!isSearchAtEnd
@@ -154,7 +144,7 @@ fun AssistantScaffold(
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
- val y = available.y * if (reverseResults == true) -1f else 1f
+ val y = available.y * if (reverseSearchResults) -1f else 1f
searchBarOffset = (searchBarOffset + y).coerceIn(-maxSearchBarOffset, 0f)
return super.onPreScroll(available, source)
}
@@ -175,10 +165,10 @@ fun AssistantScaffold(
SearchColumn(
modifier = Modifier.fillMaxSize(),
paddingValues = PaddingValues(
- top = (if (bottomSearchBar == true) 0.dp else 56.dp + webSearchPadding) + 4.dp + windowInsets.calculateTopPadding(),
- bottom = (if (bottomSearchBar == true) 56.dp + webSearchPadding else 0.dp) + 4.dp + windowInsets.calculateBottomPadding()
+ top = (if (bottomSearchBar) 0.dp else 56.dp + webSearchPadding) + 4.dp + windowInsets.calculateTopPadding(),
+ bottom = (if (bottomSearchBar) 56.dp + webSearchPadding else 0.dp) + 4.dp + windowInsets.calculateBottomPadding()
),
- reverse = reverseResults == true,
+ reverse = reverseSearchResults,
state = searchState
)
@@ -191,14 +181,14 @@ fun AssistantScaffold(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
- .align(if (bottomSearchBar == true) Alignment.BottomCenter else Alignment.TopCenter)
+ .align(if (bottomSearchBar) Alignment.BottomCenter else Alignment.TopCenter)
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(8.dp)
.offset {
if (searchBarFocused) IntOffset.Zero
else IntOffset(
0,
- searchBarOffset.toInt() * if (bottomSearchBar == true) -1 else 1
+ searchBarOffset.toInt() * if (bottomSearchBar) -1 else 1
)
},
level = { searchBarLevel },
@@ -213,7 +203,7 @@ fun AssistantScaffold(
onValueChange = { searchVM.search(it) },
darkColors = LocalPreferDarkContentOverWallpaper.current && searchBarColor == Settings.SearchBarSettings.SearchBarColors.Auto || searchBarColor == Settings.SearchBarSettings.SearchBarColors.Dark,
style = searchBarStyle,
- reverse = bottomSearchBar == true
+ reverse = bottomSearchBar
)
}
}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt
index 7023bbe9..9647fa7a 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt
@@ -37,5 +37,7 @@ class LauncherActivityVM : ViewModel(), KoinComponent {
isSystemInDarkMode.value = darkMode
}
- val layout = dataStore.data.map { it.appearance.layout }.asLiveData()
+ val baseLayout = dataStore.data.map { it.layout.baseLayout }.asLiveData()
+ val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }.asLiveData()
+ val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }.asLiveData()
}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
index 34e581ef..0d0e19e1 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
@@ -1,6 +1,5 @@
package de.mm20.launcher2.ui.launcher
-import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState
@@ -117,15 +116,13 @@ fun PagerScaffold(
}
val isSearchAtTop by remember {
- if (reverseSearchResults) {
- derivedStateOf {
+ derivedStateOf {
+ if (reverseSearchResults) {
val lastItem =
searchState.layoutInfo.visibleItemsInfo.lastOrNull()
?: return@derivedStateOf true
lastItem.offset + lastItem.size <= searchState.layoutInfo.viewportEndOffset - searchState.layoutInfo.afterContentPadding
- }
- } else {
- derivedStateOf {
+ } else {
searchState.firstVisibleItemIndex == 0 && searchState.firstVisibleItemScrollOffset == 0
}
}
@@ -255,8 +252,10 @@ fun PagerScaffold(
source: NestedScrollSource
): Offset {
if (source == NestedScrollSource.Drag) gestureManager.dispatchDrag(available)
- val deltaSearchBarOffset = consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
- searchBarOffset.value = (searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
+ val deltaSearchBarOffset =
+ consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
+ searchBarOffset.value =
+ (searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
return super.onPostScroll(consumed, available, source)
}
@@ -311,8 +310,9 @@ fun PagerScaffold(
state = pagerState,
userScrollEnabled = !isWidgetEditMode,
) {
- val pagerProgress = pagerState.currentPage + pagerState.currentPageOffsetFraction
- when(it) {
+ val pagerProgress =
+ pagerState.currentPage + pagerState.currentPageOffsetFraction
+ when (it) {
0 -> {
val editModePadding by animateDpAsState(if (isWidgetEditMode && bottomSearchBar) 56.dp else 0.dp)
@@ -382,6 +382,7 @@ fun PagerScaffold(
)
}
}
+
1 -> {
val webSearchPadding by animateDpAsState(
if (actions.isEmpty()) 0.dp else 48.dp
@@ -469,7 +470,12 @@ fun PagerScaffold(
.padding(8.dp)
.windowInsetsPadding(WindowInsets.safeDrawing)
.imePadding()
- .offset { IntOffset(0, if (focusSearchBar) 0 else searchBarOffset.value.toInt() * if (bottomSearchBar) 1 else -1) }
+ .offset {
+ IntOffset(
+ 0,
+ if (focusSearchBar) 0 else searchBarOffset.value.toInt() * if (bottomSearchBar) 1 else -1
+ )
+ }
.offset(y = widgetEditModeOffset),
level = { searchBarLevel },
focused = focusSearchBar,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
index 0c384a5b..ad4082be 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
@@ -18,6 +18,7 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -117,7 +118,9 @@ abstract class SharedLauncherActivity(
val hideStatus by viewModel.hideStatusBar.observeAsState(false)
val hideNav by viewModel.hideNavBar.observeAsState(false)
- val layout by viewModel.layout.observeAsState(null)
+ val layout by viewModel.baseLayout.observeAsState(null)
+ val bottomSearchBar by viewModel.bottomSearchBar.observeAsState(false)
+ val reverseSearchResults by viewModel.reverseSearchResults.observeAsState(false)
val systemUiController = rememberSystemUiController()
@@ -167,44 +170,56 @@ abstract class SharedLauncherActivity(
) {
NavBarEffects(modifier = Modifier.fillMaxSize())
if (mode == LauncherActivityMode.Assistant) {
- AssistantScaffold(
- modifier = Modifier
- .fillMaxSize(),
- darkStatusBarIcons = lightStatus,
- darkNavBarIcons = lightNav,
- )
+ key(bottomSearchBar, reverseSearchResults) {
+ AssistantScaffold(
+ modifier = Modifier
+ .fillMaxSize(),
+ darkStatusBarIcons = lightStatus,
+ darkNavBarIcons = lightNav,
+ bottomSearchBar = bottomSearchBar,
+ reverseSearchResults = reverseSearchResults,
+ )
+ }
} else {
when (layout) {
- Settings.AppearanceSettings.Layout.PullDown -> {
- PullDownScaffold(
- modifier = Modifier
- .fillMaxSize()
- .graphicsLayer {
- scaleX =
- 0.5f + enterTransitionProgress.value * 0.5f
- scaleY =
- 0.5f + enterTransitionProgress.value * 0.5f
- alpha = enterTransitionProgress.value
- },
- darkStatusBarIcons = lightStatus,
- darkNavBarIcons = lightNav,
- )
+ Settings.LayoutSettings.Layout.PullDown -> {
+ key(bottomSearchBar, reverseSearchResults) {
+ PullDownScaffold(
+ modifier = Modifier
+ .fillMaxSize()
+ .graphicsLayer {
+ scaleX =
+ 0.5f + enterTransitionProgress.value * 0.5f
+ scaleY =
+ 0.5f + enterTransitionProgress.value * 0.5f
+ alpha = enterTransitionProgress.value
+ },
+ darkStatusBarIcons = lightStatus,
+ darkNavBarIcons = lightNav,
+ bottomSearchBar = bottomSearchBar,
+ reverseSearchResults = reverseSearchResults,
+ )
+ }
}
- Settings.AppearanceSettings.Layout.Pager,
- Settings.AppearanceSettings.Layout.PagerReversed -> {
- PagerScaffold(
- modifier = Modifier
- .fillMaxSize()
- .graphicsLayer {
- scaleX = enterTransitionProgress.value
- scaleY = enterTransitionProgress.value
- alpha = enterTransitionProgress.value
- },
- darkStatusBarIcons = lightStatus,
- darkNavBarIcons = lightNav,
- reverse = layout == Settings.AppearanceSettings.Layout.PagerReversed
- )
+ Settings.LayoutSettings.Layout.Pager,
+ Settings.LayoutSettings.Layout.PagerReversed -> {
+ key(bottomSearchBar, reverseSearchResults) {
+ PagerScaffold(
+ modifier = Modifier
+ .fillMaxSize()
+ .graphicsLayer {
+ scaleX = enterTransitionProgress.value
+ scaleY = enterTransitionProgress.value
+ alpha = enterTransitionProgress.value
+ },
+ darkStatusBarIcons = lightStatus,
+ darkNavBarIcons = lightNav,
+ reverse = layout == Settings.LayoutSettings.Layout.PagerReversed,
+ bottomSearchBar = bottomSearchBar,
+ reverseSearchResults = reverseSearchResults,
+ )
+ }
}
else -> {}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt
index 60b1470d..e6cddad3 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt
@@ -40,6 +40,7 @@ import de.mm20.launcher2.ui.settings.easteregg.EasterEggSettingsScreen
import de.mm20.launcher2.ui.settings.favorites.FavoritesSettingsScreen
import de.mm20.launcher2.ui.settings.filesearch.FileSearchSettingsScreen
import de.mm20.launcher2.ui.settings.hiddenitems.HiddenItemsSettingsScreen
+import de.mm20.launcher2.ui.settings.layout.LayoutSettingsScreen
import de.mm20.launcher2.ui.settings.license.LicenseScreen
import de.mm20.launcher2.ui.settings.log.LogScreen
import de.mm20.launcher2.ui.settings.main.MainSettingsScreen
@@ -99,6 +100,9 @@ class SettingsActivity : BaseActivity() {
composable("settings/appearance") {
AppearanceSettingsScreen()
}
+ composable("settings/appearance/layout") {
+ LayoutSettingsScreen()
+ }
composable("settings/appearance/colorscheme") {
ColorSchemeSettingsScreen()
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
index 5fcc1cd2..4d915a24 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
@@ -54,13 +54,13 @@ fun AppearanceSettingsScreen() {
PreferenceScreen(title = stringResource(id = R.string.preference_screen_appearance)) {
item {
PreferenceCategory {
- val layout by viewModel.layout.observeAsState()
- LayoutPreference(
+ Preference(
title = stringResource(id = R.string.preference_layout),
summary = stringResource(id = R.string.preference_layout_summary),
- value = layout, onValueChanged = {
- viewModel.setLayout(it)
- })
+ onClick = {
+ navController?.navigate("settings/appearance/layout")
+ }
+ )
val theme by viewModel.theme.observeAsState()
ListPreference(
title = stringResource(id = R.string.preference_theme),
@@ -483,128 +483,6 @@ fun IconShapePreference(
}
}
-@Composable
-fun LayoutPreference(
- title: String,
- summary: String? = null,
- value: AppearanceSettings.Layout?,
- onValueChanged: (AppearanceSettings.Layout) -> Unit
-) {
- var showDialog by remember { mutableStateOf(false) }
- Preference(title = title, summary = summary, onClick = { showDialog = true })
-
- if (showDialog && value != null) {
- val layouts = remember {
- AppearanceSettings.Layout.values()
- .filter { it != AppearanceSettings.Layout.UNRECOGNIZED }
- }
- val pagerState = rememberPagerState(layouts.indexOf(value))
- AlertDialog(
- onDismissRequest = { showDialog = false },
- confirmButton = {
- TextButton(onClick = {
- showDialog = false
- onValueChanged(layouts[pagerState.currentPage])
- }) {
- Text(
- text = stringResource(android.R.string.ok),
- )
- }
- },
- dismissButton = {
- TextButton(onClick = { showDialog = false }) {
- Text(
- text = stringResource(android.R.string.cancel),
- )
- }
- },
-
- text = {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- HorizontalPager(
- count = layouts.size,
- state = pagerState,
- modifier = Modifier
- .fillMaxWidth()
- .padding(bottom = 16.dp)
- ) {
- Box(
- modifier = Modifier
- .height(250.dp)
- .width(141.dp)
- .background(MaterialTheme.colorScheme.secondary)
- ) {
-
- val composition by rememberLottieComposition(
- LottieCompositionSpec.RawRes(
- when (layouts[it]) {
- AppearanceSettings.Layout.PullDown -> R.raw.lottie_scaffold_pulldown
- AppearanceSettings.Layout.Pager -> R.raw.lottie_scaffold_pager
- AppearanceSettings.Layout.PagerReversed -> R.raw.lottie_scaffold_pager_reverse
- else -> 0
- }
- )
- )
-
- val dynamicProperties = rememberLottieDynamicProperties(
- rememberLottieDynamicProperty(
- property = LottieProperty.COLOR,
- value = MaterialTheme.colorScheme.primaryContainer.toArgb(),
- keyPath = arrayOf("Pointer", "**")
- ),
- rememberLottieDynamicProperty(
- property = LottieProperty.COLOR,
- value = MaterialTheme.colorScheme.surface.toArgb(),
- keyPath = arrayOf("SearchBar", "**")
- ),
- rememberLottieDynamicProperty(
- property = LottieProperty.COLOR,
- value = MaterialTheme.colorScheme.surface.toArgb(),
- keyPath = arrayOf("Favorites", "**")
- ),
- rememberLottieDynamicProperty(
- property = LottieProperty.COLOR,
- value = MaterialTheme.colorScheme.surface.toArgb(),
- keyPath = arrayOf("Apps", "**")
- ),
- rememberLottieDynamicProperty(
- property = LottieProperty.COLOR,
- value = Color.White.toArgb(),
- keyPath = arrayOf("ClockWidget", "**")
- )
- )
-
- /*LaunchedEffect(null) {
- val drw = LottieDrawable()
- drw.composition = composition
- val list = drw.resolveKeyPath(KeyPath("**"))
- list.forEach {
- Log.d("MM20", it.keysToString())
- }
- }*/
-
-
- val progress by animateLottieCompositionAsState(
- composition,
- iterations = LottieConstants.IterateForever
- )
-
- LottieAnimation(
- composition = composition,
- progress = progress,
- dynamicProperties = dynamicProperties
- )
- }
- }
- HorizontalPagerIndicator(pagerState = pagerState)
- }
- }
- )
- }
-}
-
@Composable
private fun getShapeName(shape: IconSettings.IconShape?): String? {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
index 7ca67299..deed068d 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
@@ -288,18 +288,4 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
}
}
}
-
- val layout = dataStore.data.map { it.appearance.layout }.asLiveData()
- fun setLayout(layout: Settings.AppearanceSettings.Layout) {
- viewModelScope.launch {
- dataStore.updateData {
- it.toBuilder()
- .setAppearance(
- it.appearance.toBuilder()
- .setLayout(layout)
- )
- .build()
- }
- }
- }
}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreen.kt
new file mode 100644
index 00000000..a6ce00b1
--- /dev/null
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreen.kt
@@ -0,0 +1,60 @@
+package de.mm20.launcher2.ui.settings.layout
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.res.stringResource
+import androidx.lifecycle.viewmodel.compose.viewModel
+import de.mm20.launcher2.preferences.Settings.LayoutSettings.Layout
+import de.mm20.launcher2.ui.R
+import de.mm20.launcher2.ui.component.preferences.ListPreference
+import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
+import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
+
+@Composable
+fun LayoutSettingsScreen() {
+ val viewModel: LayoutSettingsScreenVM = viewModel()
+ PreferenceScreen(
+ title = stringResource(id = R.string.preference_layout)
+ ) {
+ item {
+ PreferenceCategory {
+ val baseLayout by viewModel.baseLayout.observeAsState()
+ ListPreference(title = stringResource(R.string.preference_layout_open_search),
+ items = listOf(
+ stringResource(R.string.open_search_pull_down) to Layout.PullDown,
+ stringResource(R.string.open_search_swipe_left) to Layout.Pager,
+ stringResource(R.string.open_search_swipe_right) to Layout.PagerReversed,
+ ),
+ value = baseLayout,
+ onValueChanged = {
+ if (it != null) viewModel.setBaseLayout(it)
+ },
+ )
+ val bottomSearchBar by viewModel.bottomSearchBar.observeAsState()
+ ListPreference(
+ title = stringResource(R.string.preference_layout_search_bar_position),
+ items = listOf(
+ stringResource(R.string.search_bar_position_top) to false,
+ stringResource(R.string.search_bar_position_bottom) to true,
+ ),
+ value = bottomSearchBar,
+ onValueChanged = {
+ if (it != null) viewModel.setBottomSearchBar(it)
+ },
+ )
+ val reverseSearchResults by viewModel.reverseSearchResults.observeAsState()
+ ListPreference(title = stringResource(R.string.preference_layout_search_results),
+ items = listOf(
+ stringResource(R.string.search_results_order_top_down) to false,
+ stringResource(R.string.search_results_order_bottom_up) to true,
+ ),
+ value = reverseSearchResults,
+ onValueChanged = {
+ if (it != null) viewModel.setReverseSearchResults(it)
+ },
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreenVM.kt
new file mode 100644
index 00000000..2957f301
--- /dev/null
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/layout/LayoutSettingsScreenVM.kt
@@ -0,0 +1,49 @@
+package de.mm20.launcher2.ui.settings.layout
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.asLiveData
+import androidx.lifecycle.viewModelScope
+import de.mm20.launcher2.preferences.LauncherDataStore
+import de.mm20.launcher2.preferences.Settings.LayoutSettings.Layout
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import org.koin.core.component.KoinComponent
+import org.koin.core.component.inject
+
+class LayoutSettingsScreenVM: ViewModel(), KoinComponent {
+
+ private val dataStore : LauncherDataStore by inject()
+
+ val baseLayout = dataStore.data.map { it.layout.baseLayout }.asLiveData()
+ fun setBaseLayout(baseLayout: Layout) {
+ viewModelScope.launch {
+ dataStore.updateData {
+ it.toBuilder()
+ .setLayout(it.layout.toBuilder().setBaseLayout(baseLayout))
+ .build()
+ }
+ }
+ }
+
+ val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }.asLiveData()
+ fun setBottomSearchBar(bottomSearchBar: Boolean) {
+ viewModelScope.launch {
+ dataStore.updateData {
+ it.toBuilder()
+ .setLayout(it.layout.toBuilder().setBottomSearchBar(bottomSearchBar))
+ .build()
+ }
+ }
+ }
+
+ val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }.asLiveData()
+ fun setReverseSearchResults(reverseSearchResults: Boolean) {
+ viewModelScope.launch {
+ dataStore.updateData {
+ it.toBuilder()
+ .setLayout(it.layout.toBuilder().setReverseSearchResults(reverseSearchResults))
+ .build()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml
index 0ad3026a..2cd49ecf 100644
--- a/core/i18n/src/main/res/values/strings.xml
+++ b/core/i18n/src/main/res/values/strings.xml
@@ -722,4 +722,14 @@
- %1$d item selected
- %1$d items selected
+ Search activation
+ Swipe down
+ Swipe left
+ Swipe right
+ Search bar position
+ Top
+ Bottom
+ Arrangement of search results
+ Top-down
+ Bottom-up
\ No newline at end of file
diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt
index b156f5d9..8d80b9f3 100644
--- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt
+++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt
@@ -22,7 +22,7 @@ internal val Context.dataStore: LauncherDataStore by dataStore(
}
)
-internal const val SchemaVersion = 11
+internal const val SchemaVersion = 12
internal fun getMigrations(context: Context): List> {
return listOf(
@@ -37,5 +37,6 @@ internal fun getMigrations(context: Context): List> {
Migration_8_9(),
Migration_9_10(),
Migration_10_11(),
+ Migration_11_12(),
)
}
\ No newline at end of file
diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
index 1737a70e..9d5d473e 100644
--- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
+++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
@@ -162,6 +162,12 @@ fun createFactorySettings(context: Context): Settings {
Settings.WidgetSettings.newBuilder()
.setEditButton(true)
)
+ .setLayout(
+ Settings.LayoutSettings.newBuilder()
+ .setBaseLayout(Settings.LayoutSettings.Layout.PullDown)
+ .setBottomSearchBar(false)
+ .setReverseSearchResults(false)
+ )
.build()
}
diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_11_12.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_11_12.kt
new file mode 100644
index 00000000..606441a1
--- /dev/null
+++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_11_12.kt
@@ -0,0 +1,37 @@
+package de.mm20.launcher2.preferences.migrations
+
+import de.mm20.launcher2.preferences.Settings
+import de.mm20.launcher2.preferences.Settings.LayoutSettings
+
+class Migration_11_12: VersionedMigration(11, 12) {
+ override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
+ val oldLayout = builder.appearance.layout
+ when(oldLayout) {
+ LayoutSettings.Layout.Pager -> {
+ builder.setLayout(
+ LayoutSettings.newBuilder()
+ .setBaseLayout(LayoutSettings.Layout.Pager)
+ .setBottomSearchBar(true)
+ .setReverseSearchResults(true)
+ )
+ }
+ LayoutSettings.Layout.PagerReversed -> {
+ builder.setLayout(
+ LayoutSettings.newBuilder()
+ .setBaseLayout(LayoutSettings.Layout.PagerReversed)
+ .setBottomSearchBar(true)
+ .setReverseSearchResults(true)
+ )
+ }
+ else -> {
+ builder.setLayout(
+ LayoutSettings.newBuilder()
+ .setBaseLayout(LayoutSettings.Layout.PullDown)
+ .setBottomSearchBar(false)
+ .setReverseSearchResults(false)
+ )
+ }
+ }
+ return builder
+ }
+}
\ No newline at end of file
diff --git a/core/preferences/src/main/proto/settings.proto b/core/preferences/src/main/proto/settings.proto
index 12100f01..599024f2 100644
--- a/core/preferences/src/main/proto/settings.proto
+++ b/core/preferences/src/main/proto/settings.proto
@@ -68,12 +68,10 @@ message Settings {
CustomColors custom_colors = 8;
bool dim_wallpaper = 7;
- enum Layout {
- PullDown = 0;
- Pager = 1;
- PagerReversed = 2;
- }
- Layout layout = 9;
+ /**
+ * Deprecated, use layout instead
+ */
+ LayoutSettings.Layout layout = 9 [deprecated = true];
enum Font {
Outfit = 0;
@@ -288,4 +286,17 @@ message Settings {
bool edit_button = 1;
}
WidgetSettings widgets = 26;
+
+ message LayoutSettings {
+ enum Layout {
+ PullDown = 0;
+ Pager = 1;
+ PagerReversed = 2;
+ }
+
+ Layout base_layout = 1;
+ bool bottom_search_bar = 2;
+ bool reverse_search_results = 3;
+ }
+ LayoutSettings layout = 27;
}
\ No newline at end of file