mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 02:11:50 +01:00
Improve search toolbar UX a little bit (#8102)
* Improve search toolbar UX a little. * Fix wrong stringResource import. * Revert `FocusRequester` change in favour of #8093.
This commit is contained in:
parent
98a4f6cccb
commit
5a37f2398a
@ -6,10 +6,12 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.presentation.browse.components.BrowseSourceSearchToolbar
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
|
||||
import eu.kanade.tachiyomi.ui.more.MoreController
|
||||
@ -39,6 +41,7 @@ fun SourceSearchScreen(
|
||||
BrowseSourceSearchToolbar(
|
||||
searchQuery = presenter.searchQuery ?: "",
|
||||
onSearchQueryChanged = { presenter.searchQuery = it },
|
||||
placeholderText = stringResource(R.string.action_search_hint),
|
||||
navigateUp = navigateUp,
|
||||
onResetClick = { presenter.searchQuery = "" },
|
||||
onSearchClick = { presenter.search() },
|
||||
|
@ -17,6 +17,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
||||
@ -57,6 +59,7 @@ fun BrowseSourceToolbar(
|
||||
BrowseSourceSearchToolbar(
|
||||
searchQuery = state.searchQuery!!,
|
||||
onSearchQueryChanged = { state.searchQuery = it },
|
||||
placeholderText = stringResource(R.string.action_search_hint),
|
||||
navigateUp = { state.searchQuery = null },
|
||||
onResetClick = { state.searchQuery = "" },
|
||||
onSearchClick = onSearch,
|
||||
@ -159,18 +162,25 @@ fun BrowseSourceRegularToolbar(
|
||||
fun BrowseSourceSearchToolbar(
|
||||
searchQuery: String,
|
||||
onSearchQueryChanged: (String) -> Unit,
|
||||
placeholderText: String?,
|
||||
navigateUp: () -> Unit,
|
||||
onResetClick: () -> Unit,
|
||||
onSearchClick: () -> Unit,
|
||||
scrollBehavior: TopAppBarScrollBehavior?,
|
||||
) {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
SearchToolbar(
|
||||
searchQuery = searchQuery,
|
||||
onChangeSearchQuery = onSearchQueryChanged,
|
||||
placeholderText = placeholderText,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
onSearchClick()
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
},
|
||||
),
|
||||
onClickCloseSearch = navigateUp,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package eu.kanade.presentation.components
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
@ -20,6 +21,7 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
@ -38,8 +40,10 @@ import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
@Composable
|
||||
@ -63,7 +67,10 @@ fun AppBar(
|
||||
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
) {
|
||||
val isActionMode by derivedStateOf { actionModeCounter > 0 }
|
||||
val isActionMode by remember(actionModeCounter) {
|
||||
derivedStateOf { actionModeCounter > 0 }
|
||||
}
|
||||
|
||||
AppBar(
|
||||
modifier = modifier,
|
||||
titleContent = {
|
||||
@ -216,6 +223,7 @@ fun AppBarActions(
|
||||
fun SearchToolbar(
|
||||
searchQuery: String,
|
||||
onChangeSearchQuery: (String) -> Unit,
|
||||
placeholderText: String? = null,
|
||||
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
||||
keyboardActions: KeyboardActions = KeyboardActions.Default,
|
||||
onClickCloseSearch: () -> Unit,
|
||||
@ -223,8 +231,11 @@ fun SearchToolbar(
|
||||
incognitoMode: Boolean = false,
|
||||
downloadedOnlyMode: Boolean = false,
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
AppBar(
|
||||
titleContent = {
|
||||
BasicTextField(
|
||||
@ -233,11 +244,40 @@ fun SearchToolbar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
textStyle = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground),
|
||||
textStyle = MaterialTheme.typography.titleMedium.copy(
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 18.sp,
|
||||
),
|
||||
keyboardOptions = keyboardOptions,
|
||||
keyboardActions = keyboardActions,
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground),
|
||||
visualTransformation = visualTransformation,
|
||||
interactionSource = interactionSource,
|
||||
decorationBox = { innerTextField ->
|
||||
TextFieldDefaults.TextFieldDecorationBox(
|
||||
value = searchQuery,
|
||||
innerTextField = innerTextField,
|
||||
enabled = true,
|
||||
singleLine = true,
|
||||
visualTransformation = visualTransformation,
|
||||
interactionSource = interactionSource,
|
||||
placeholder = {
|
||||
if (!placeholderText.isNullOrEmpty()) {
|
||||
Text(
|
||||
text = placeholderText,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleMedium.copy(
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
navigationIcon = Icons.Outlined.ArrowBack,
|
||||
|
@ -22,6 +22,7 @@ fun TabbedScreen(
|
||||
tabs: List<TabContent>,
|
||||
startIndex: Int? = null,
|
||||
searchQuery: String? = null,
|
||||
@StringRes placeholderRes: Int? = null,
|
||||
onChangeSearchQuery: (String?) -> Unit = {},
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
@ -47,6 +48,7 @@ fun TabbedScreen(
|
||||
} else {
|
||||
SearchToolbar(
|
||||
searchQuery = searchQuery,
|
||||
placeholderText = placeholderRes?.let { stringResource(it) },
|
||||
onChangeSearchQuery = {
|
||||
onChangeSearchQuery(it)
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
package eu.kanade.presentation.history.components
|
||||
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.DeleteSweep
|
||||
import androidx.compose.material.icons.outlined.Search
|
||||
@ -7,7 +9,10 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.presentation.components.SearchToolbar
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -21,6 +26,9 @@ fun HistoryToolbar(
|
||||
incognitoMode: Boolean,
|
||||
downloadedOnlyMode: Boolean,
|
||||
) {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
if (state.searchQuery == null) {
|
||||
HistoryRegularToolbar(
|
||||
onClickSearch = { state.searchQuery = "" },
|
||||
@ -33,10 +41,20 @@ fun HistoryToolbar(
|
||||
SearchToolbar(
|
||||
searchQuery = state.searchQuery!!,
|
||||
onChangeSearchQuery = { state.searchQuery = it },
|
||||
placeholderText = stringResource(R.string.action_search_hint),
|
||||
onClickCloseSearch = { state.searchQuery = null },
|
||||
onClickResetSearch = { state.searchQuery = "" },
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
imeAction = ImeAction.Search,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package eu.kanade.presentation.library.components
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.FilterList
|
||||
import androidx.compose.material.icons.outlined.FlipToBack
|
||||
@ -17,7 +19,10 @@ import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
@ -48,15 +53,30 @@ fun LibraryToolbar(
|
||||
onClickSelectAll = onClickSelectAll,
|
||||
onClickInvertSelection = onClickInvertSelection,
|
||||
)
|
||||
state.searchQuery != null -> SearchToolbar(
|
||||
searchQuery = state.searchQuery!!,
|
||||
onChangeSearchQuery = { state.searchQuery = it },
|
||||
onClickCloseSearch = { state.searchQuery = null },
|
||||
onClickResetSearch = { state.searchQuery = "" },
|
||||
scrollBehavior = scrollBehavior,
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
)
|
||||
state.searchQuery != null -> {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
SearchToolbar(
|
||||
searchQuery = state.searchQuery!!,
|
||||
onChangeSearchQuery = { state.searchQuery = it },
|
||||
onClickCloseSearch = { state.searchQuery = null },
|
||||
onClickResetSearch = { state.searchQuery = "" },
|
||||
scrollBehavior = scrollBehavior,
|
||||
incognitoMode = incognitoMode,
|
||||
downloadedOnlyMode = downloadedOnlyMode,
|
||||
placeholderText = stringResource(R.string.action_search_hint),
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
imeAction = ImeAction.Search,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> LibraryRegularToolbar(
|
||||
title = title,
|
||||
hasFilters = state.hasActiveFilters,
|
||||
|
@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -14,11 +16,16 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.components.ScrollbarLazyColumn
|
||||
import eu.kanade.presentation.components.SearchToolbar
|
||||
import eu.kanade.presentation.util.horizontalPadding
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.setting.SettingsController
|
||||
import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchHelper
|
||||
import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchPresenter
|
||||
@ -33,6 +40,9 @@ fun SettingsSearchScreen(
|
||||
val results by presenter.state.collectAsState()
|
||||
var query by remember { mutableStateOf("") }
|
||||
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
Scaffold(
|
||||
topBar = { scrollBehavior ->
|
||||
SearchToolbar(
|
||||
@ -41,13 +51,20 @@ fun SettingsSearchScreen(
|
||||
query = it
|
||||
presenter.searchSettings(it)
|
||||
},
|
||||
placeholderText = stringResource(R.string.action_search_settings),
|
||||
onClickCloseSearch = navigateUp,
|
||||
onClickResetSearch = { query = "" },
|
||||
scrollBehavior = scrollBehavior,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
imeAction = ImeAction.Search,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// TODO: search placeholder
|
||||
// Text(stringResource(R.string.action_search_settings))
|
||||
},
|
||||
) { contentPadding ->
|
||||
ScrollbarLazyColumn(
|
||||
|
@ -45,6 +45,7 @@ class BrowseController : FullComposeController<BrowsePresenter>, RootController
|
||||
startIndex = 1.takeIf { toExtensions },
|
||||
searchQuery = query,
|
||||
onChangeSearchQuery = { presenter.extensionsPresenter.search(it) },
|
||||
placeholderRes = R.string.action_search_hint,
|
||||
incognitoMode = presenter.isIncognitoMode,
|
||||
downloadedOnlyMode = presenter.isDownloadOnly,
|
||||
)
|
||||
|
@ -50,6 +50,7 @@
|
||||
<string name="action_sort_chapter_fetch_date">Chapter fetch date</string>
|
||||
<string name="action_sort_date_added">Date added</string>
|
||||
<string name="action_search">Search</string>
|
||||
<string name="action_search_hint">Search…</string>
|
||||
<string name="action_search_settings">Search settings</string>
|
||||
<string name="action_global_search">Global search</string>
|
||||
<string name="action_select_all">Select all</string>
|
||||
|
Loading…
Reference in New Issue
Block a user