mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Refactor search toolbar and fix browse source (#8360)
This commit is contained in:
		| @@ -6,12 +6,10 @@ 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.presentation.components.SearchToolbar | ||||
| import eu.kanade.tachiyomi.source.LocalSource | ||||
| import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter | ||||
| import eu.kanade.tachiyomi.ui.more.MoreController | ||||
| @@ -38,13 +36,11 @@ fun SourceSearchScreen( | ||||
|  | ||||
|     Scaffold( | ||||
|         topBar = { scrollBehavior -> | ||||
|             BrowseSourceSearchToolbar( | ||||
|             SearchToolbar( | ||||
|                 searchQuery = presenter.searchQuery ?: "", | ||||
|                 onSearchQueryChanged = { presenter.searchQuery = it }, | ||||
|                 placeholderText = stringResource(R.string.action_search_hint), | ||||
|                 navigateUp = navigateUp, | ||||
|                 onResetClick = { presenter.searchQuery = "" }, | ||||
|                 onSearchClick = { presenter.search(it) }, | ||||
|                 onChangeSearchQuery = { presenter.searchQuery = it }, | ||||
|                 onClickCloseSearch = navigateUp, | ||||
|                 onSearch = { presenter.search(it) }, | ||||
|                 scrollBehavior = scrollBehavior, | ||||
|             ) | ||||
|         }, | ||||
|   | ||||
| @@ -1,13 +1,10 @@ | ||||
| package eu.kanade.presentation.browse.components | ||||
|  | ||||
| import androidx.compose.foundation.text.KeyboardActions | ||||
| import androidx.compose.foundation.text.KeyboardOptions | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.filled.ViewList | ||||
| import androidx.compose.material.icons.filled.ViewModule | ||||
| import androidx.compose.material.icons.outlined.Help | ||||
| import androidx.compose.material.icons.outlined.Public | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material3.Text | ||||
| import androidx.compose.material3.TopAppBarScrollBehavior | ||||
| import androidx.compose.runtime.Composable | ||||
| @@ -15,14 +12,12 @@ 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 | ||||
| import eu.kanade.presentation.browse.BrowseSourceState | ||||
| import eu.kanade.presentation.components.AppBar | ||||
| import eu.kanade.presentation.components.AppBarActions | ||||
| import eu.kanade.presentation.components.AppBarTitle | ||||
| import eu.kanade.presentation.components.DropdownMenu | ||||
| import eu.kanade.presentation.components.RadioMenuItem | ||||
| import eu.kanade.presentation.components.SearchToolbar | ||||
| @@ -42,59 +37,21 @@ fun BrowseSourceToolbar( | ||||
|     onSearch: (String) -> Unit, | ||||
|     scrollBehavior: TopAppBarScrollBehavior? = null, | ||||
| ) { | ||||
|     if (state.searchQuery == null) { | ||||
|         BrowseSourceRegularToolbar( | ||||
|             title = if (state.isUserQuery) state.currentFilter.query else source?.name.orEmpty(), | ||||
|             isLocalSource = source is LocalSource, | ||||
|             displayMode = displayMode, | ||||
|             onDisplayModeChange = onDisplayModeChange, | ||||
|             navigateUp = navigateUp, | ||||
|             onSearchClick = { state.searchQuery = if (state.isUserQuery) state.currentFilter.query else "" }, | ||||
|             onWebViewClick = onWebViewClick, | ||||
|             onHelpClick = onHelpClick, | ||||
|             scrollBehavior = scrollBehavior, | ||||
|         ) | ||||
|     } else { | ||||
|         val cancelSearch = { state.searchQuery = null } | ||||
|         BrowseSourceSearchToolbar( | ||||
|             searchQuery = state.searchQuery!!, | ||||
|             onSearchQueryChanged = { state.searchQuery = it }, | ||||
|             placeholderText = stringResource(R.string.action_search_hint), | ||||
|             navigateUp = cancelSearch, | ||||
|             onResetClick = { state.searchQuery = "" }, | ||||
|             onSearchClick = { | ||||
|                 onSearch(it) | ||||
|                 cancelSearch() | ||||
|             }, | ||||
|             scrollBehavior = scrollBehavior, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|     // Avoid capturing unstable source in actions lambda | ||||
|     val title = source?.name | ||||
|     val isLocalSource = source is LocalSource | ||||
|  | ||||
| @Composable | ||||
| fun BrowseSourceRegularToolbar( | ||||
|     title: String, | ||||
|     isLocalSource: Boolean, | ||||
|     displayMode: LibraryDisplayMode, | ||||
|     onDisplayModeChange: (LibraryDisplayMode) -> Unit, | ||||
|     navigateUp: () -> Unit, | ||||
|     onSearchClick: () -> Unit, | ||||
|     onWebViewClick: () -> Unit, | ||||
|     onHelpClick: () -> Unit, | ||||
|     scrollBehavior: TopAppBarScrollBehavior?, | ||||
| ) { | ||||
|     AppBar( | ||||
|     SearchToolbar( | ||||
|         navigateUp = navigateUp, | ||||
|         title = title, | ||||
|         titleContent = { AppBarTitle(title) }, | ||||
|         searchQuery = state.searchQuery, | ||||
|         onChangeSearchQuery = { state.searchQuery = it }, | ||||
|         onSearch = onSearch, | ||||
|         onClickCloseSearch = navigateUp, | ||||
|         actions = { | ||||
|             var selectingDisplayMode by remember { mutableStateOf(false) } | ||||
|             AppBarActions( | ||||
|                 actions = listOf( | ||||
|                     AppBar.Action( | ||||
|                         title = stringResource(R.string.action_search), | ||||
|                         icon = Icons.Outlined.Search, | ||||
|                         onClick = onSearchClick, | ||||
|                     ), | ||||
|                     AppBar.Action( | ||||
|                         title = stringResource(R.string.action_display_mode), | ||||
|                         icon = if (displayMode == LibraryDisplayMode.List) Icons.Filled.ViewList else Icons.Filled.ViewModule, | ||||
| @@ -123,18 +80,21 @@ fun BrowseSourceRegularToolbar( | ||||
|                     text = { Text(text = stringResource(R.string.action_display_comfortable_grid)) }, | ||||
|                     isChecked = displayMode == LibraryDisplayMode.ComfortableGrid, | ||||
|                 ) { | ||||
|                     selectingDisplayMode = false | ||||
|                     onDisplayModeChange(LibraryDisplayMode.ComfortableGrid) | ||||
|                 } | ||||
|                 RadioMenuItem( | ||||
|                     text = { Text(text = stringResource(R.string.action_display_grid)) }, | ||||
|                     isChecked = displayMode == LibraryDisplayMode.CompactGrid, | ||||
|                 ) { | ||||
|                     selectingDisplayMode = false | ||||
|                     onDisplayModeChange(LibraryDisplayMode.CompactGrid) | ||||
|                 } | ||||
|                 RadioMenuItem( | ||||
|                     text = { Text(text = stringResource(R.string.action_display_list)) }, | ||||
|                     isChecked = displayMode == LibraryDisplayMode.List, | ||||
|                 ) { | ||||
|                     selectingDisplayMode = false | ||||
|                     onDisplayModeChange(LibraryDisplayMode.List) | ||||
|                 } | ||||
|             } | ||||
| @@ -142,34 +102,3 @@ fun BrowseSourceRegularToolbar( | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
| } | ||||
|  | ||||
| @Composable | ||||
| fun BrowseSourceSearchToolbar( | ||||
|     searchQuery: String, | ||||
|     onSearchQueryChanged: (String) -> Unit, | ||||
|     placeholderText: String?, | ||||
|     navigateUp: () -> Unit, | ||||
|     onResetClick: () -> Unit, | ||||
|     onSearchClick: (String) -> 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(searchQuery) | ||||
|                 focusManager.clearFocus() | ||||
|                 keyboardController?.hide() | ||||
|             }, | ||||
|         ), | ||||
|         onClickCloseSearch = navigateUp, | ||||
|         onClickResetSearch = onResetClick, | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| 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 | ||||
| @@ -13,6 +12,7 @@ import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.outlined.ArrowBack | ||||
| import androidx.compose.material.icons.outlined.Close | ||||
| import androidx.compose.material.icons.outlined.MoreVert | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material3.DropdownMenuItem | ||||
| import androidx.compose.material3.Icon | ||||
| import androidx.compose.material3.IconButton | ||||
| @@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.LaunchedEffect | ||||
| import androidx.compose.runtime.derivedStateOf | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.key | ||||
| import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.setValue | ||||
| @@ -34,8 +35,11 @@ import androidx.compose.ui.focus.FocusRequester | ||||
| import androidx.compose.ui.focus.focusRequester | ||||
| import androidx.compose.ui.graphics.SolidColor | ||||
| import androidx.compose.ui.graphics.vector.ImageVector | ||||
| import androidx.compose.ui.platform.LocalFocusManager | ||||
| import androidx.compose.ui.platform.LocalSoftwareKeyboardController | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.compose.ui.text.font.FontWeight | ||||
| import androidx.compose.ui.text.input.ImeAction | ||||
| import androidx.compose.ui.text.input.VisualTransformation | ||||
| import androidx.compose.ui.text.style.TextOverflow | ||||
| import androidx.compose.ui.unit.dp | ||||
| @@ -215,15 +219,22 @@ fun AppBarActions( | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param searchEnabled Set to false if you don't want to show search action. | ||||
|  * @param searchQuery If null, use normal toolbar. | ||||
|  * @param placeholderText If null, [R.string.action_search_hint] is used. | ||||
|  */ | ||||
| @Composable | ||||
| fun SearchToolbar( | ||||
|     searchQuery: String, | ||||
|     onChangeSearchQuery: (String) -> Unit, | ||||
|     titleContent: @Composable () -> Unit = {}, | ||||
|     navigateUp: (() -> Unit)? = null, | ||||
|     searchEnabled: Boolean = true, | ||||
|     searchQuery: String?, | ||||
|     onChangeSearchQuery: (String?) -> Unit, | ||||
|     placeholderText: String? = null, | ||||
|     keyboardOptions: KeyboardOptions = KeyboardOptions.Default, | ||||
|     keyboardActions: KeyboardActions = KeyboardActions.Default, | ||||
|     onClickCloseSearch: () -> Unit, | ||||
|     onClickResetSearch: () -> Unit, | ||||
|     onSearch: (String) -> Unit = {}, | ||||
|     onClickCloseSearch: () -> Unit = { onChangeSearchQuery(null) }, | ||||
|     actions: @Composable RowScope.() -> Unit = {}, | ||||
|     incognitoMode: Boolean = false, | ||||
|     downloadedOnlyMode: Boolean = false, | ||||
|     scrollBehavior: TopAppBarScrollBehavior? = null, | ||||
| @@ -231,9 +242,15 @@ fun SearchToolbar( | ||||
|     interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, | ||||
| ) { | ||||
|     val focusRequester = remember { FocusRequester() } | ||||
|     var searchClickCount by remember { mutableStateOf(0) } | ||||
|  | ||||
|     AppBar( | ||||
|         titleContent = { | ||||
|             if (searchQuery == null) return@AppBar titleContent() | ||||
|  | ||||
|             val keyboardController = LocalSoftwareKeyboardController.current | ||||
|             val focusManager = LocalFocusManager.current | ||||
|  | ||||
|             BasicTextField( | ||||
|                 value = searchQuery, | ||||
|                 onValueChange = onChangeSearchQuery, | ||||
| @@ -245,8 +262,14 @@ fun SearchToolbar( | ||||
|                     fontWeight = FontWeight.Normal, | ||||
|                     fontSize = 18.sp, | ||||
|                 ), | ||||
|                 keyboardOptions = keyboardOptions, | ||||
|                 keyboardActions = keyboardActions, | ||||
|                 keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), | ||||
|                 keyboardActions = KeyboardActions( | ||||
|                     onSearch = { | ||||
|                         onSearch(searchQuery) | ||||
|                         focusManager.clearFocus() | ||||
|                         keyboardController?.hide() | ||||
|                     }, | ||||
|                 ), | ||||
|                 singleLine = true, | ||||
|                 cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), | ||||
|                 visualTransformation = visualTransformation, | ||||
| @@ -260,7 +283,7 @@ fun SearchToolbar( | ||||
|                         visualTransformation = visualTransformation, | ||||
|                         interactionSource = interactionSource, | ||||
|                         placeholder = { | ||||
|                             if (!placeholderText.isNullOrEmpty()) { | ||||
|                             (placeholderText ?: stringResource(R.string.action_search_hint)).let { placeholderText -> | ||||
|                                 Text( | ||||
|                                     modifier = Modifier.secondaryItemAlpha(), | ||||
|                                     text = placeholderText, | ||||
| @@ -277,22 +300,41 @@ fun SearchToolbar( | ||||
|                 }, | ||||
|             ) | ||||
|         }, | ||||
|         navigationIcon = Icons.Outlined.ArrowBack, | ||||
|         navigateUp = onClickCloseSearch, | ||||
|         navigateUp = if (searchQuery == null) navigateUp else onClickCloseSearch, | ||||
|         actions = { | ||||
|             AnimatedVisibility(visible = searchQuery.isNotEmpty()) { | ||||
|                 IconButton(onClick = onClickResetSearch) { | ||||
|                     Icon(Icons.Outlined.Close, contentDescription = stringResource(R.string.action_reset)) | ||||
|             key("search") { | ||||
|                 val onClick = { | ||||
|                     searchClickCount++ | ||||
|                     onChangeSearchQuery("") | ||||
|                 } | ||||
|  | ||||
|                 if (!searchEnabled) { | ||||
|                     // Don't show search action | ||||
|                 } else if (searchQuery == null) { | ||||
|                     IconButton(onClick) { | ||||
|                         Icon(Icons.Outlined.Search, contentDescription = stringResource(R.string.action_search)) | ||||
|                     } | ||||
|                 } else if (searchQuery.isNotEmpty()) { | ||||
|                     IconButton(onClick) { | ||||
|                         Icon(Icons.Outlined.Close, contentDescription = stringResource(R.string.action_reset)) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             key("actions") { actions() } | ||||
|         }, | ||||
|         isActionMode = false, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         incognitoMode = incognitoMode, | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
|     LaunchedEffect(focusRequester) { | ||||
|         focusRequester.requestFocus() | ||||
|     LaunchedEffect(searchClickCount) { | ||||
|         if (searchQuery == null) return@LaunchedEffect | ||||
|         try { | ||||
|             focusRequester.requestFocus() | ||||
|         } catch (_: Throwable) { | ||||
|             // TextField is gone | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,6 @@ fun TabbedScreen( | ||||
|     tabs: List<TabContent>, | ||||
|     startIndex: Int? = null, | ||||
|     searchQuery: String? = null, | ||||
|     @StringRes placeholderRes: Int? = null, | ||||
|     onChangeSearchQuery: (String?) -> Unit = {}, | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
| @@ -42,28 +41,16 @@ fun TabbedScreen( | ||||
|  | ||||
|     Scaffold( | ||||
|         topBar = { | ||||
|             if (searchQuery == null) { | ||||
|                 AppBar( | ||||
|                     title = stringResource(titleRes), | ||||
|                     actions = { | ||||
|                         AppBarActions(tabs[state.currentPage].actions) | ||||
|                     }, | ||||
|                 ) | ||||
|             } else { | ||||
|                 SearchToolbar( | ||||
|                     searchQuery = searchQuery, | ||||
|                     placeholderText = placeholderRes?.let { stringResource(it) }, | ||||
|                     onChangeSearchQuery = { | ||||
|                         onChangeSearchQuery(it) | ||||
|                     }, | ||||
|                     onClickCloseSearch = { | ||||
|                         onChangeSearchQuery(null) | ||||
|                     }, | ||||
|                     onClickResetSearch = { | ||||
|                         onChangeSearchQuery("") | ||||
|                     }, | ||||
|                 ) | ||||
|             } | ||||
|             val tab = tabs[state.currentPage] | ||||
|             val searchEnabled = tab.searchEnabled | ||||
|  | ||||
|             SearchToolbar( | ||||
|                 titleContent = { AppBarTitle(stringResource(titleRes)) }, | ||||
|                 searchEnabled = searchEnabled, | ||||
|                 searchQuery = if (searchEnabled) searchQuery else null, | ||||
|                 onChangeSearchQuery = onChangeSearchQuery, | ||||
|                 actions = { AppBarActions(tab.actions) }, | ||||
|             ) | ||||
|         }, | ||||
|     ) { contentPadding -> | ||||
|         Column( | ||||
| @@ -108,6 +95,7 @@ fun TabbedScreen( | ||||
| data class TabContent( | ||||
|     @StringRes val titleRes: Int, | ||||
|     val badgeNumber: Int? = null, | ||||
|     val searchEnabled: Boolean = false, | ||||
|     val actions: List<AppBar.Action> = emptyList(), | ||||
|     val content: @Composable (contentPadding: PaddingValues) -> Unit, | ||||
| ) | ||||
|   | ||||
| @@ -1,19 +1,13 @@ | ||||
| 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 | ||||
| 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.AppBarTitle | ||||
| import eu.kanade.presentation.components.SearchToolbar | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.ui.recent.history.HistoryPresenter | ||||
| @@ -26,54 +20,12 @@ fun HistoryToolbar( | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
| ) { | ||||
|     val keyboardController = LocalSoftwareKeyboardController.current | ||||
|     val focusManager = LocalFocusManager.current | ||||
|  | ||||
|     if (state.searchQuery == null) { | ||||
|         HistoryRegularToolbar( | ||||
|             onClickSearch = { state.searchQuery = "" }, | ||||
|             onClickDelete = { state.dialog = HistoryPresenter.Dialog.DeleteAll }, | ||||
|             incognitoMode = incognitoMode, | ||||
|             downloadedOnlyMode = downloadedOnlyMode, | ||||
|             scrollBehavior = scrollBehavior, | ||||
|         ) | ||||
|     } else { | ||||
|         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() | ||||
|                 }, | ||||
|             ), | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @Composable | ||||
| fun HistoryRegularToolbar( | ||||
|     onClickSearch: () -> Unit, | ||||
|     onClickDelete: () -> Unit, | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
|     scrollBehavior: TopAppBarScrollBehavior, | ||||
| ) { | ||||
|     AppBar( | ||||
|         title = stringResource(R.string.history), | ||||
|     SearchToolbar( | ||||
|         titleContent = { AppBarTitle(stringResource(R.string.history)) }, | ||||
|         searchQuery = state.searchQuery, | ||||
|         onChangeSearchQuery = { state.searchQuery = it }, | ||||
|         actions = { | ||||
|             IconButton(onClick = onClickSearch) { | ||||
|                 Icon(Icons.Outlined.Search, contentDescription = stringResource(R.string.action_search)) | ||||
|             } | ||||
|             IconButton(onClick = onClickDelete) { | ||||
|             IconButton(onClick = { state.dialog = HistoryPresenter.Dialog.DeleteAll }) { | ||||
|                 Icon(Icons.Outlined.DeleteSweep, contentDescription = stringResource(R.string.pref_clear_history)) | ||||
|             } | ||||
|         }, | ||||
|   | ||||
| @@ -2,12 +2,9 @@ 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 | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material.icons.outlined.SelectAll | ||||
| import androidx.compose.material3.DropdownMenuItem | ||||
| import androidx.compose.material3.Icon | ||||
| @@ -19,10 +16,7 @@ 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 | ||||
| @@ -55,36 +49,13 @@ fun LibraryToolbar( | ||||
|         onClickSelectAll = onClickSelectAll, | ||||
|         onClickInvertSelection = onClickInvertSelection, | ||||
|     ) | ||||
|     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, | ||||
|         incognitoMode = incognitoMode, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         onClickSearch = { state.searchQuery = "" }, | ||||
|         searchQuery = state.searchQuery, | ||||
|         onChangeSearchQuery = { state.searchQuery = it }, | ||||
|         onClickFilter = onClickFilter, | ||||
|         onClickRefresh = onClickRefresh, | ||||
|         onClickOpenRandomManga = onClickOpenRandomManga, | ||||
| @@ -98,7 +69,8 @@ fun LibraryRegularToolbar( | ||||
|     hasFilters: Boolean, | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
|     onClickSearch: () -> Unit, | ||||
|     searchQuery: String?, | ||||
|     onChangeSearchQuery: (String?) -> Unit, | ||||
|     onClickFilter: () -> Unit, | ||||
|     onClickRefresh: () -> Unit, | ||||
|     onClickOpenRandomManga: () -> Unit, | ||||
| @@ -106,7 +78,7 @@ fun LibraryRegularToolbar( | ||||
| ) { | ||||
|     val pillAlpha = if (isSystemInDarkTheme()) 0.12f else 0.08f | ||||
|     val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current | ||||
|     AppBar( | ||||
|     SearchToolbar( | ||||
|         titleContent = { | ||||
|             Row(verticalAlignment = Alignment.CenterVertically) { | ||||
|                 Text( | ||||
| @@ -124,10 +96,9 @@ fun LibraryRegularToolbar( | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         searchQuery = searchQuery, | ||||
|         onChangeSearchQuery = onChangeSearchQuery, | ||||
|         actions = { | ||||
|             IconButton(onClick = onClickSearch) { | ||||
|                 Icon(Icons.Outlined.Search, contentDescription = stringResource(R.string.action_search)) | ||||
|             } | ||||
|             IconButton(onClick = onClickFilter) { | ||||
|                 Icon(Icons.Outlined.FilterList, contentDescription = stringResource(R.string.action_filter), tint = filterTint) | ||||
|             } | ||||
|   | ||||
| @@ -45,7 +45,6 @@ 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, | ||||
|         ) | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.extension | ||||
|  | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material.icons.outlined.Translate | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.res.stringResource | ||||
| @@ -21,13 +20,8 @@ fun extensionsTab( | ||||
| ) = TabContent( | ||||
|     titleRes = R.string.label_extensions, | ||||
|     badgeNumber = presenter.updates.takeIf { it > 0 }, | ||||
|     searchEnabled = true, | ||||
|     actions = listOf( | ||||
|         AppBar.Action( | ||||
|             title = stringResource(R.string.action_search), | ||||
|             icon = Icons.Outlined.Search, | ||||
|             onClick = { presenter.search("") }, | ||||
|         ), | ||||
|  | ||||
|         AppBar.Action( | ||||
|             title = stringResource(R.string.action_filter), | ||||
|             icon = Icons.Outlined.Translate, | ||||
|   | ||||
| @@ -119,11 +119,7 @@ open class BrowseSourceController(bundle: Bundle) : | ||||
|  | ||||
|     private fun navigateUp() { | ||||
|         when { | ||||
|             presenter.searchQuery != null -> presenter.searchQuery = null | ||||
|             presenter.isUserQuery -> { | ||||
|                 val (_, filters) = presenter.currentFilter as BrowseSourcePresenter.Filter.UserInput | ||||
|                 presenter.search(query = "", filters = filters) | ||||
|             } | ||||
|             !presenter.isUserQuery && presenter.searchQuery != null -> presenter.searchQuery = null | ||||
|             else -> router.popCurrentController() | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -163,6 +163,7 @@ open class BrowseSourcePresenter( | ||||
|         Filter.valueOf(query ?: "").let { | ||||
|             if (it !is Filter.UserInput) { | ||||
|                 state.currentFilter = it | ||||
|                 state.searchQuery = null | ||||
|                 return | ||||
|             } | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user