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