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 5de8dd4c..19cef02a 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 @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.* -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color @@ -13,7 +12,6 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.* -import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle @@ -184,12 +182,9 @@ fun AssistantScaffold( LauncherSearchBar( modifier = Modifier .fillMaxSize(), - searchBarOffset = { - (if (searchBarFocused || fixedSearchBar) 0 - else searchBarOffset.toInt() * if (bottomSearchBar) -1 else 1) - - (if (bottomSearchBar) with(density) { keyboardFilterBarPadding.toPx() }.toInt() else 0) - }, + style = searchBarStyle, level = { searchBarLevel }, + value = { value }, focused = searchBarFocused, onFocusChange = { if (it) viewModel.openSearch() @@ -198,11 +193,13 @@ fun AssistantScaffold( actions = actions, highlightedAction = searchVM.bestMatch.value as? SearchAction, isSearchOpen = true, - value = { value }, - onValueChange = { searchVM.search(it) }, darkColors = LocalPreferDarkContentOverWallpaper.current && searchBarColor == SearchBarColors.Auto || searchBarColor == SearchBarColors.Dark, - style = searchBarStyle, bottomSearchBar = bottomSearchBar, + searchBarOffset = { + (if (searchBarFocused || fixedSearchBar) 0 + else searchBarOffset.toInt() * if (bottomSearchBar) -1 else 1) + - (if (bottomSearchBar) with(density) { keyboardFilterBarPadding.toPx() }.toInt() else 0) + }, onKeyboardActionGo = if (launchOnEnter) { { searchVM.launchBestMatchOrAction(context) } } else null 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 5c55cc13..da937c03 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 @@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.requiredWidth import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.windowInsetsPadding -import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerDefaults @@ -55,7 +54,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.geometry.Offset @@ -602,16 +600,9 @@ fun PagerScaffold( LauncherSearchBar( modifier = Modifier .fillMaxSize(), + style = searchBarStyle, level = { searchBarLevel }, - searchBarOffset = { - (if (focusSearchBar || fixedSearchBar) 0 else searchBarOffset.value.toInt() * if (bottomSearchBar) 1 else -1) + - with(density) { - (widgetEditModeOffset - if (bottomSearchBar) keyboardFilterBarPadding else 0.dp) - .toPx() - .roundToInt() - } - }, - bottomSearchBar = bottomSearchBar, + value = { value }, focused = focusSearchBar, onFocusChange = { if (it) viewModel.openSearch() @@ -620,10 +611,16 @@ fun PagerScaffold( actions = actions, highlightedAction = searchVM.bestMatch.value as? SearchAction, isSearchOpen = isSearchOpen, - value = { value }, - onValueChange = { searchVM.search(it) }, darkColors = LocalPreferDarkContentOverWallpaper.current && searchBarColor == SearchBarColors.Auto || searchBarColor == SearchBarColors.Dark, - style = searchBarStyle, + bottomSearchBar = bottomSearchBar, + searchBarOffset = { + (if (focusSearchBar || fixedSearchBar) 0 else searchBarOffset.value.toInt() * if (bottomSearchBar) 1 else -1) + + with(density) { + (widgetEditModeOffset - if (bottomSearchBar) keyboardFilterBarPadding else 0.dp) + .toPx() + .roundToInt() + } + }, onKeyboardActionGo = if (launchOnEnter) { { searchVM.launchBestMatchOrAction(context) } } else null diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt index 3c34f8f6..01cb6155 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt @@ -58,9 +58,7 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.IntOffset @@ -580,12 +578,19 @@ fun PullDownScaffold( LauncherSearchBar( modifier = Modifier .fillMaxSize(), + style = searchBarStyle, level = { searchBarLevel }, + value = { value }, focused = searchBarFocused, onFocusChange = { if (it) viewModel.openSearch() viewModel.setSearchbarFocus(it) }, + actions = actions, + highlightedAction = searchVM.bestMatch.value as? SearchAction, + isSearchOpen = isSearchOpen, + darkColors = LocalPreferDarkContentOverWallpaper.current && searchBarColor == SearchBarColors.Auto || searchBarColor == SearchBarColors.Dark, + bottomSearchBar = bottomSearchBar, searchBarOffset = { (if (searchBarFocused || fixedSearchBar) 0 else searchBarOffset.value.toInt() * (if (bottomSearchBar) 1 else -1)) + with(density) { @@ -594,14 +599,6 @@ fun PullDownScaffold( .roundToInt() } }, - actions = actions, - highlightedAction = searchVM.bestMatch.value as? SearchAction, - isSearchOpen = isSearchOpen, - value = { value }, - onValueChange = { searchVM.search(it) }, - darkColors = LocalPreferDarkContentOverWallpaper.current && searchBarColor == SearchBarColors.Auto || searchBarColor == SearchBarColors.Dark, - style = searchBarStyle, - bottomSearchBar = bottomSearchBar, onKeyboardActionGo = if (launchOnEnter) { { searchVM.launchBestMatchOrAction(context) } } else null diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt index e3c10721..11d4cd33 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchVM.kt @@ -11,9 +11,9 @@ import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.preferences.SearchResultOrder import de.mm20.launcher2.preferences.search.CalendarSearchSettings import de.mm20.launcher2.preferences.search.ContactSearchSettings -import de.mm20.launcher2.preferences.search.FavoritesSettings import de.mm20.launcher2.preferences.search.FileSearchSettings import de.mm20.launcher2.preferences.search.LocationSearchSettings +import de.mm20.launcher2.preferences.search.SearchFilterSettings import de.mm20.launcher2.preferences.search.ShortcutSearchSettings import de.mm20.launcher2.preferences.ui.SearchUiSettings import de.mm20.launcher2.search.AppProfile @@ -42,7 +42,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -63,6 +62,7 @@ class SearchVM : ViewModel(), KoinComponent { private val searchUiSettings: SearchUiSettings by inject() private val locationSearchSettings: LocationSearchSettings by inject() private val devicePoseProvider: DevicePoseProvider by inject() + private val searchFilterSettings: SearchFilterSettings by inject() val launchOnEnter = searchUiSettings.launchOnEnter .stateIn(viewModelScope, SharingStarted.Eagerly, false) @@ -93,7 +93,8 @@ class SearchVM : ViewModel(), KoinComponent { val showFilters = mutableStateOf(false) - val filters = mutableStateOf(SearchFilters()) + val defaultFilters = searchFilterSettings.defaultFilter.stateIn(viewModelScope, SharingStarted.Eagerly, SearchFilters()) + val filters = mutableStateOf(defaultFilters.value) val separateWorkProfile = searchUiSettings.separateWorkProfile @@ -133,6 +134,7 @@ class SearchVM : ViewModel(), KoinComponent { fun reset() { closeFilters() + filters.value = defaultFilters.value search("") } @@ -142,6 +144,9 @@ class SearchVM : ViewModel(), KoinComponent { if (searchQuery.value != query) { showFilters.value = false } + if (query.isEmpty() && searchQuery.value.isNotEmpty()) { + filters.value = defaultFilters.value + } searchQuery.value = query isSearchEmpty.value = query.isEmpty() hiddenResults.value = emptyList() diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/filters/KeyboardFilterBar.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/filters/KeyboardFilterBar.kt index a299dcfc..0f3d7614 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/filters/KeyboardFilterBar.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/filters/KeyboardFilterBar.kt @@ -2,11 +2,8 @@ package de.mm20.launcher2.ui.launcher.search.filters import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt index 05d24f80..841169f4 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt @@ -2,19 +2,13 @@ package de.mm20.launcher2.ui.launcher.searchbar import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.tween -import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut -import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxScope -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.imeAnimationTarget -import androidx.compose.foundation.layout.isImeVisible import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing @@ -29,8 +23,6 @@ import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -46,7 +38,6 @@ import de.mm20.launcher2.ui.component.SearchBar import de.mm20.launcher2.ui.component.SearchBarLevel import de.mm20.launcher2.ui.launcher.search.SearchVM import de.mm20.launcher2.ui.launcher.search.filters.KeyboardFilterBar -import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager @Composable fun LauncherSearchBar( @@ -54,7 +45,6 @@ fun LauncherSearchBar( style: SearchBarStyle, level: () -> SearchBarLevel, value: () -> String, - onValueChange: (String) -> Unit, focused: Boolean, onFocusChange: (Boolean) -> Unit, actions: List, @@ -85,7 +75,9 @@ fun LauncherSearchBar( .windowInsetsPadding(WindowInsets.safeDrawing) .padding(8.dp) .offset { IntOffset(0, searchBarOffset()) }, - style = style, level = level(), value = _value, onValueChange = onValueChange, + style = style, level = level(), value = _value, onValueChange = { + searchVM.search(it) + }, reverse = bottomSearchBar, darkColors = darkColors, menu = { @@ -118,7 +110,9 @@ fun LauncherSearchBar( } } } - SearchBarMenu(searchBarValue = _value, onSearchBarValueChange = onValueChange) + SearchBarMenu(searchBarValue = _value, onInputClear = { + searchVM.reset() + }) }, actions = { SearchBarActions( diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt index 9b2fdaaa..007674b8 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/SearchBarMenu.kt @@ -38,7 +38,7 @@ import de.mm20.launcher2.ui.settings.SettingsActivity @Composable fun RowScope.SearchBarMenu( searchBarValue: String, - onSearchBarValueChange: (newValue: String) -> Unit, + onInputClear: () -> Unit, ) { val context = LocalContext.current var showOverflowMenu by remember { mutableStateOf(false) } @@ -47,7 +47,7 @@ fun RowScope.SearchBarMenu( val widgetsVM: WidgetsVM = viewModel() IconButton(onClick = { - if (searchBarValue.isNotBlank()) onSearchBarValueChange("") + if (searchBarValue.isNotBlank()) onInputClear() else showOverflowMenu = true }) { Icon( diff --git a/core/base/build.gradle.kts b/core/base/build.gradle.kts index 071a5883..a6f63cbe 100644 --- a/core/base/build.gradle.kts +++ b/core/base/build.gradle.kts @@ -1,6 +1,7 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.plugin.serialization) } android { diff --git a/services/search/src/main/java/de/mm20/launcher2/search/SearchFilters.kt b/core/base/src/main/java/de/mm20/launcher2/search/SearchFilters.kt similarity index 93% rename from services/search/src/main/java/de/mm20/launcher2/search/SearchFilters.kt rename to core/base/src/main/java/de/mm20/launcher2/search/SearchFilters.kt index 273e35f7..3edc61e3 100644 --- a/services/search/src/main/java/de/mm20/launcher2/search/SearchFilters.kt +++ b/core/base/src/main/java/de/mm20/launcher2/search/SearchFilters.kt @@ -1,7 +1,9 @@ package de.mm20.launcher2.search import de.mm20.launcher2.ktx.toInt +import kotlinx.serialization.Serializable +@Serializable data class SearchFilters( val allowNetwork: Boolean = false, val hiddenItems: Boolean = false, diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt index 3abc645d..46851f79 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/LauncherSettingsData.kt @@ -2,6 +2,7 @@ package de.mm20.launcher2.preferences import android.content.Context import de.mm20.launcher2.preferences.search.LocationSearchSettings +import de.mm20.launcher2.search.SearchFilters import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -144,6 +145,23 @@ data class LauncherSettingsData internal constructor( val locationSearchShowPositionOnMap: Boolean = false, val locationSearchThemeMap: Boolean = true, + val searchFilter: SearchFilters = SearchFilters(), + val searchFilterBar: Boolean = true, + val searchFilterBarItems: List = listOf( + KeyboardFilterBarItem.OnlineResults, + KeyboardFilterBarItem.Apps, + KeyboardFilterBarItem.Shortcuts, + KeyboardFilterBarItem.Events, + KeyboardFilterBarItem.Contacts, + KeyboardFilterBarItem.Files, + KeyboardFilterBarItem.Places, + KeyboardFilterBarItem.Articles, + KeyboardFilterBarItem.Websites, + KeyboardFilterBarItem.Places, + KeyboardFilterBarItem.Tools, + KeyboardFilterBarItem.HiddenResults, + ), + ) { constructor( @@ -376,4 +394,19 @@ data class LatLon( data class ProviderSettings( val locationId: String? = null, val locationName: String? = null, -) \ No newline at end of file +) + +@Serializable +enum class KeyboardFilterBarItem { + @SerialName("online") OnlineResults, + @SerialName("apps") Apps, + @SerialName("websites") Websites, + @SerialName("articles") Articles, + @SerialName("places") Places, + @SerialName("files") Files, + @SerialName("shortcuts") Shortcuts, + @SerialName("contacts") Contacts, + @SerialName("events") Events, + @SerialName("tools") Tools, + @SerialName("hidden") HiddenResults, +} \ No newline at end of file diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt index 9536daa9..e19a509f 100644 --- a/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/Module.kt @@ -9,6 +9,7 @@ import de.mm20.launcher2.preferences.search.FavoritesSettings import de.mm20.launcher2.preferences.search.FileSearchSettings import de.mm20.launcher2.preferences.search.LocationSearchSettings import de.mm20.launcher2.preferences.search.RankingSettings +import de.mm20.launcher2.preferences.search.SearchFilterSettings import de.mm20.launcher2.preferences.search.ShortcutSearchSettings import de.mm20.launcher2.preferences.search.UnitConverterSettings import de.mm20.launcher2.preferences.search.WebsiteSearchSettings @@ -49,4 +50,5 @@ val preferencesModule = module { factory { CalculatorSearchSettings(get()) } factory { ClockWidgetSettings(get()) } factory { LocationSearchSettings(get()) } + factory { SearchFilterSettings(get()) } } \ No newline at end of file diff --git a/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SearchFilterSettings.kt b/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SearchFilterSettings.kt new file mode 100644 index 00000000..fc5fc76d --- /dev/null +++ b/core/preferences/src/main/java/de/mm20/launcher2/preferences/search/SearchFilterSettings.kt @@ -0,0 +1,11 @@ +package de.mm20.launcher2.preferences.search + +import de.mm20.launcher2.preferences.LauncherDataStore +import kotlinx.coroutines.flow.map + +class SearchFilterSettings internal constructor( + private val launcherDataStore: LauncherDataStore, +) { + val defaultFilter + get() = launcherDataStore.data.map { it.searchFilter } +} \ No newline at end of file