Skip to content

Commit

Permalink
SearchVM, SearchService: improve search UX by reducing flickering (
Browse files Browse the repository at this point in the history
…#1117)

* Fix: don't treat PH OpeningHours with specified time as `everyDay`

* Use SnapshotStateList in SearchVM and don't clear search-results if
there are no new search results from SearchableRepositories

* Rename parameter

* mergeStateLists: refactor as extension method, add apps to SearchResults by default

---------

Co-authored-by: MM20 <[email protected]>
  • Loading branch information
shtrophic and MM2-0 authored Dec 5, 2024
1 parent 2b08cb7 commit 8c4bfb7
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fun AssistantScaffold(
val density = LocalDensity.current
val maxSearchBarOffset = with(density) { 128.dp.toPx() }
var searchBarOffset by remember {
mutableStateOf(0f)
mutableFloatStateOf(0f)
}

val nestedScrollConnection = remember {
Expand All @@ -159,7 +159,7 @@ fun AssistantScaffold(
}
}
}
val actions by searchVM.searchActionResults
val actions = searchVM.searchActionResults
val webSearchPadding by animateDpAsState(
if (actions.isEmpty()) 0.dp else 48.dp
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -124,7 +124,7 @@ fun PagerScaffold(
val isSearchOpen by viewModel.isSearchOpen
val isWidgetEditMode by viewModel.isWidgetEditMode

val actions by searchVM.searchActionResults
val actions = searchVM.searchActionResults

val widgetsScrollState = rememberScrollState()
val searchState = rememberLazyListState()
Expand Down Expand Up @@ -272,7 +272,7 @@ fun PagerScaffold(
}
}

val searchBarOffset = remember { mutableStateOf(0f) }
val searchBarOffset = remember { mutableFloatStateOf(0f) }

val scope = rememberCoroutineScope()

Expand Down Expand Up @@ -341,8 +341,8 @@ fun PagerScaffold(
}
val deltaSearchBarOffset =
consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
searchBarOffset.value =
(searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
searchBarOffset.floatValue =
(searchBarOffset.floatValue + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
return super.onPostScroll(consumed, available, source)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
Expand Down Expand Up @@ -106,7 +107,7 @@ fun PullDownScaffold(
val density = LocalDensity.current
val context = LocalContext.current

val actions by searchVM.searchActionResults
val actions = searchVM.searchActionResults

val isSearchOpen by viewModel.isSearchOpen
val isWidgetEditMode by viewModel.isWidgetEditMode
Expand All @@ -116,7 +117,7 @@ fun PullDownScaffold(

val pagerState = rememberPagerState { 2 }

val offsetY = remember { mutableStateOf(0f) }
val offsetY = remember { mutableFloatStateOf(0f) }
val maxOffset = with(density) { 64.dp.toPx() }
val toggleSearchThreshold = with(density) { 48.dp.toPx() }

Expand Down Expand Up @@ -153,13 +154,13 @@ fun PullDownScaffold(

val isOverThreshold by remember {
derivedStateOf {
offsetY.value.absoluteValue > toggleSearchThreshold
offsetY.floatValue.absoluteValue > toggleSearchThreshold
}
}

val dragProgress by remember {
derivedStateOf {
(offsetY.value.absoluteValue / toggleSearchThreshold).coerceAtMost(1f)
(offsetY.floatValue.absoluteValue / toggleSearchThreshold).coerceAtMost(1f)
}
}

Expand Down Expand Up @@ -236,7 +237,7 @@ fun PullDownScaffold(
}
}

val searchBarOffset = remember { mutableStateOf(0f) }
val searchBarOffset = remember { mutableFloatStateOf(0f) }

val maxSearchBarOffset = with(density) { 128.dp.toPx() }

Expand Down Expand Up @@ -281,7 +282,7 @@ fun PullDownScaffold(
}

LaunchedEffect(isWidgetEditMode) {
if (!isWidgetEditMode) searchBarOffset.value = 0f
if (!isWidgetEditMode) searchBarOffset.floatValue = 0f
}

val handleBackOrHomeEvent = {
Expand Down Expand Up @@ -321,7 +322,7 @@ fun PullDownScaffold(
LaunchedEffect(isOverThreshold) {
if (isOverThreshold) {
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
} else if (offsetY.value != 0f) {
} else if (offsetY.floatValue != 0f) {
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE)
}
}
Expand All @@ -342,15 +343,15 @@ fun PullDownScaffold(
val canPullUp = isSearchOpen && isSearchAtBottom

val consumed = when {
canPullUp && available.y < 0 || offsetY.value < 0 -> {
canPullUp && available.y < 0 || offsetY.floatValue < 0 -> {
val consumed = available.y
offsetY.value = (offsetY.value + (consumed * 0.5f)).coerceIn(-maxOffset, 0f)
offsetY.floatValue = (offsetY.floatValue + (consumed * 0.5f)).coerceIn(-maxOffset, 0f)
consumed
}

canPullDown && available.y > 0 || offsetY.value > 0 -> {
canPullDown && available.y > 0 || offsetY.floatValue > 0 -> {
val consumed = available.y
offsetY.value = (offsetY.value + (consumed * 0.5f)).coerceIn(0f, maxOffset)
offsetY.floatValue = (offsetY.floatValue + (consumed * 0.5f)).coerceIn(0f, maxOffset)
consumed
}

Expand All @@ -367,17 +368,17 @@ fun PullDownScaffold(
): Offset {
val deltaSearchBarOffset =
consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
searchBarOffset.value =
(searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
searchBarOffset.floatValue =
(searchBarOffset.floatValue + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
return super.onPostScroll(consumed, available, source)
}

override suspend fun onPreFling(available: Velocity): Velocity {
if (offsetY.value > toggleSearchThreshold || offsetY.value < -toggleSearchThreshold) {
if (offsetY.floatValue > toggleSearchThreshold || offsetY.floatValue < -toggleSearchThreshold) {
viewModel.toggleSearch()
}
if (!isWidgetEditMode) gestureManager.dispatchDragEnd()
if (offsetY.value != 0f) {
if (offsetY.floatValue != 0f) {
offsetY.animateTo(0f)
return available
}
Expand Down Expand Up @@ -406,7 +407,7 @@ fun PullDownScaffold(
}
)
}
.offset { IntOffset(0, offsetY.value.toInt()) },
.offset { IntOffset(0, offsetY.floatValue.toInt()) },
contentAlignment = Alignment.TopCenter
) {
BoxWithConstraints(
Expand Down Expand Up @@ -576,7 +577,7 @@ fun PullDownScaffold(
val searchBarLevel by remember {
derivedStateOf {
when {
offsetY.value != 0f -> SearchBarLevel.Raised
offsetY.floatValue != 0f -> SearchBarLevel.Raised
!isSearchOpen && isWidgetsAtStart && (fillClockHeight || !bottomSearchBar) -> SearchBarLevel.Resting
isSearchOpen && isSearchAtTop && !bottomSearchBar -> SearchBarLevel.Active
isSearchOpen && isSearchAtBottom && bottomSearchBar -> SearchBarLevel.Active
Expand Down Expand Up @@ -613,7 +614,7 @@ fun PullDownScaffold(
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)) +
(if (searchBarFocused || fixedSearchBar) 0 else searchBarOffset.floatValue.toInt() * (if (bottomSearchBar) 1 else -1)) +
with(density) {
(editModeSearchBarOffset - if (bottomSearchBar) keyboardFilterBarPadding else 0.dp)
.toPx()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.mm20.launcher2.ui.launcher.search

import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedContent
Expand Down Expand Up @@ -75,22 +74,22 @@ fun SearchColumn(
val hideFavs by viewModel.hideFavorites
val favoritesEnabled by viewModel.favoritesEnabled.collectAsState(false)

val apps by viewModel.appResults
val workApps by viewModel.workAppResults
val privateApps by viewModel.privateSpaceAppResults
val apps = viewModel.appResults
val workApps = viewModel.workAppResults
val privateApps = viewModel.privateSpaceAppResults
val profiles by viewModel.profiles.collectAsState(emptyList())
val profileStates by viewModel.profileStates.collectAsState(emptyList())

val appShortcuts by viewModel.appShortcutResults
val contacts by viewModel.contactResults
val files by viewModel.fileResults
val events by viewModel.calendarResults
val unitConverter by viewModel.unitConverterResults
val calculator by viewModel.calculatorResults
val wikipedia by viewModel.articleResults
val locations by viewModel.locationResults
val website by viewModel.websiteResults
val hiddenResults by viewModel.hiddenResults
val appShortcuts = viewModel.appShortcutResults
val contacts = viewModel.contactResults
val files = viewModel.fileResults
val events = viewModel.calendarResults
val unitConverter = viewModel.unitConverterResults
val calculator = viewModel.calculatorResults
val wikipedia = viewModel.articleResults
val locations = viewModel.locationResults
val website = viewModel.websiteResults
val hiddenResults = viewModel.hiddenResults

val bestMatch by viewModel.bestMatch

Expand Down
Loading

0 comments on commit 8c4bfb7

Please sign in to comment.