ui: close the list search on back

This commit is contained in:
austinried
2026-10-19 14:30:38 +00:00
parent fb1c2a02ff
commit d038a33b36
2 changed files with 46 additions and 4 deletions
@@ -1,5 +1,6 @@
package com.subtracks.ui.library
import androidx.activity.compose.BackHandler
import androidx.annotation.StringRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
@@ -429,9 +430,14 @@ fun LibraryScreen(
var searchActive by rememberSaveable { mutableStateOf(false) }
var topRequest by remember { mutableIntStateOf(0) }
val searchFocus = remember { FocusRequester() }
val closeSearch = {
searchActive = false
onSearchChange("")
}
// Search mode is left open so the typed query survives; MainNavigation dismisses the keyboard.
DismissOnRequest(dismissals) { showOptions = false }
BackHandler(enabled = searchActive, onBack = closeSearch)
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.settledPage }.collect { page ->
@@ -594,10 +600,7 @@ fun LibraryScreen(
SearchField(
value = search,
onValueChange = onSearchChange,
onClose = {
searchActive = false
onSearchChange("")
},
onClose = closeSearch,
focusRequester = searchFocus,
modifier =
Modifier
@@ -5,6 +5,7 @@ import androidx.compose.foundation.pager.PagerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription
@@ -20,6 +21,7 @@ import androidx.paging.LoadStates
import androidx.paging.PagingData
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
import com.subtracks.R
import com.subtracks.data.model.Album
import com.subtracks.data.model.Artist
import com.subtracks.data.model.Playlist
@@ -32,6 +34,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
@@ -272,6 +275,42 @@ class LibraryScreenTest {
composeRule.waitForIdle()
}
@Test
fun backClosesTheListSearchInsteadOfLeavingTheApp() {
val search = mutableStateOf("xyz")
composeRule.setContent {
SubtracksTheme {
LibraryScreen(
selectedTab = LibraryTab.Albums,
onTabSelected = {},
albums = remember { flowOf(PagingData.from(albums())) },
artists = remember { flowOf(PagingData.empty<Artist>()) },
playlists = remember { flowOf(PagingData.empty<Playlist>()) },
coverArt = { _, _ -> null },
onAlbumClick = {},
onArtistClick = {},
onPlaylistClick = {},
onSync = {},
onOpenSettings = {},
search = search.value,
onSearchChange = { search.value = it },
)
}
}
val closeLabel = composeRule.activity.getString(R.string.close_search)
composeRule.waitUntil(timeoutMillis = 5_000) {
composeRule.onAllNodesWithContentDescription(closeLabel).fetchSemanticsNodes().isNotEmpty()
}
composeRule.runOnIdle { composeRule.activity.onBackPressedDispatcher.onBackPressed() }
composeRule.waitForIdle()
assertEquals("back should clear the list search", "", search.value)
composeRule.onNodeWithContentDescription(closeLabel).assertDoesNotExist()
assertFalse("back should not leave the app", composeRule.activity.isFinishing)
}
@Test
fun theTabRowReflowsInOneDirectionDuringASwitch() {
val pagerState = PagerState(currentPage = 1, pageCount = { LibraryTab.entries.size })