mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Convert settings main and search views to full Compose
This commit is contained in:
		| @@ -1,13 +1,18 @@ | ||||
| package eu.kanade.presentation.components | ||||
|  | ||||
| import androidx.compose.animation.AnimatedVisibility | ||||
| import androidx.compose.foundation.layout.Column | ||||
| import androidx.compose.foundation.layout.RowScope | ||||
| import androidx.compose.foundation.layout.WindowInsets | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
| import androidx.compose.foundation.layout.statusBars | ||||
| import androidx.compose.foundation.text.BasicTextField | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.filled.ArrowBack | ||||
| import androidx.compose.material.icons.filled.Close | ||||
| import androidx.compose.material.icons.filled.MoreVert | ||||
| import androidx.compose.material.icons.outlined.ArrowBack | ||||
| import androidx.compose.material.icons.outlined.Close | ||||
| import androidx.compose.material3.DropdownMenuItem | ||||
| import androidx.compose.material3.Icon | ||||
| import androidx.compose.material3.IconButton | ||||
| @@ -18,18 +23,23 @@ import androidx.compose.material3.TopAppBarDefaults | ||||
| import androidx.compose.material3.TopAppBarScrollBehavior | ||||
| import androidx.compose.material3.surfaceColorAtElevation | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.LaunchedEffect | ||||
| import androidx.compose.runtime.derivedStateOf | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.setValue | ||||
| import androidx.compose.ui.Modifier | ||||
| 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.res.stringResource | ||||
| import androidx.compose.ui.text.font.FontWeight | ||||
| import androidx.compose.ui.text.style.TextOverflow | ||||
| import androidx.compose.ui.unit.dp | ||||
| import eu.kanade.tachiyomi.R | ||||
| import kotlinx.coroutines.delay | ||||
|  | ||||
| @Composable | ||||
| fun AppBar( | ||||
| @@ -206,6 +216,51 @@ fun AppBarActions( | ||||
|     } | ||||
| } | ||||
|  | ||||
| @Composable | ||||
| fun SearchToolbar( | ||||
|     searchQuery: String, | ||||
|     onChangeSearchQuery: (String) -> Unit, | ||||
|     onClickCloseSearch: () -> Unit, | ||||
|     onClickResetSearch: () -> Unit, | ||||
|     incognitoMode: Boolean = false, | ||||
|     downloadedOnlyMode: Boolean = false, | ||||
|     scrollBehavior: TopAppBarScrollBehavior? = null, | ||||
| ) { | ||||
|     val focusRequester = remember { FocusRequester.Default } | ||||
|     AppBar( | ||||
|         titleContent = { | ||||
|             BasicTextField( | ||||
|                 value = searchQuery, | ||||
|                 onValueChange = onChangeSearchQuery, | ||||
|                 modifier = Modifier | ||||
|                     .fillMaxWidth() | ||||
|                     .focusRequester(focusRequester), | ||||
|                 textStyle = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground), | ||||
|                 singleLine = true, | ||||
|                 cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), | ||||
|             ) | ||||
|         }, | ||||
|         navigationIcon = Icons.Outlined.ArrowBack, | ||||
|         navigateUp = onClickCloseSearch, | ||||
|         actions = { | ||||
|             AnimatedVisibility(visible = searchQuery.isNotEmpty()) { | ||||
|                 IconButton(onClick = onClickResetSearch) { | ||||
|                     Icon(Icons.Outlined.Close, contentDescription = stringResource(R.string.action_reset)) | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         isActionMode = false, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         incognitoMode = incognitoMode, | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
|     LaunchedEffect(focusRequester) { | ||||
|         // TODO: https://issuetracker.google.com/issues/204502668 | ||||
|         delay(100) | ||||
|         focusRequester.requestFocus() | ||||
|     } | ||||
| } | ||||
|  | ||||
| sealed interface AppBar { | ||||
|     sealed interface AppBarAction | ||||
|  | ||||
|   | ||||
| @@ -1,30 +1,18 @@ | ||||
| package eu.kanade.presentation.history.components | ||||
|  | ||||
| import androidx.compose.animation.AnimatedVisibility | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
| import androidx.compose.foundation.text.BasicTextField | ||||
| 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.DeleteSweep | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.material3.Icon | ||||
| import androidx.compose.material3.IconButton | ||||
| import androidx.compose.material3.MaterialTheme | ||||
| import androidx.compose.material3.TopAppBarScrollBehavior | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.LaunchedEffect | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.focus.FocusRequester | ||||
| import androidx.compose.ui.focus.focusRequester | ||||
| import androidx.compose.ui.graphics.SolidColor | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import eu.kanade.presentation.components.AppBar | ||||
| import eu.kanade.presentation.components.SearchToolbar | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.ui.recent.history.HistoryPresenter | ||||
| import eu.kanade.tachiyomi.ui.recent.history.HistoryState | ||||
| import kotlinx.coroutines.delay | ||||
|  | ||||
| @Composable | ||||
| fun HistoryToolbar( | ||||
| @@ -42,7 +30,7 @@ fun HistoryToolbar( | ||||
|             scrollBehavior = scrollBehavior, | ||||
|         ) | ||||
|     } else { | ||||
|         HistorySearchToolbar( | ||||
|         SearchToolbar( | ||||
|             searchQuery = state.searchQuery!!, | ||||
|             onChangeSearchQuery = { state.searchQuery = it }, | ||||
|             onClickCloseSearch = { state.searchQuery = null }, | ||||
| @@ -76,46 +64,3 @@ fun HistoryRegularToolbar( | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
| } | ||||
|  | ||||
| @Composable | ||||
| fun HistorySearchToolbar( | ||||
|     searchQuery: String, | ||||
|     onChangeSearchQuery: (String) -> Unit, | ||||
|     onClickCloseSearch: () -> Unit, | ||||
|     onClickResetSearch: () -> Unit, | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
| ) { | ||||
|     val focusRequester = remember { FocusRequester.Default } | ||||
|     AppBar( | ||||
|         titleContent = { | ||||
|             BasicTextField( | ||||
|                 value = searchQuery, | ||||
|                 onValueChange = onChangeSearchQuery, | ||||
|                 modifier = Modifier | ||||
|                     .fillMaxWidth() | ||||
|                     .focusRequester(focusRequester), | ||||
|                 textStyle = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground), | ||||
|                 singleLine = true, | ||||
|                 cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), | ||||
|             ) | ||||
|         }, | ||||
|         navigationIcon = Icons.Outlined.ArrowBack, | ||||
|         navigateUp = onClickCloseSearch, | ||||
|         actions = { | ||||
|             AnimatedVisibility(visible = searchQuery.isNotEmpty()) { | ||||
|                 IconButton(onClick = onClickResetSearch) { | ||||
|                     Icon(Icons.Outlined.Close, contentDescription = stringResource(R.string.action_reset)) | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         isActionMode = false, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         incognitoMode = incognitoMode, | ||||
|     ) | ||||
|     LaunchedEffect(focusRequester) { | ||||
|         // TODO: https://issuetracker.google.com/issues/204502668 | ||||
|         delay(100) | ||||
|         focusRequester.requestFocus() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,8 @@ | ||||
| package eu.kanade.presentation.library.components | ||||
|  | ||||
| import androidx.compose.animation.AnimatedVisibility | ||||
| import androidx.compose.foundation.isSystemInDarkTheme | ||||
| import androidx.compose.foundation.layout.Row | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
| import androidx.compose.foundation.text.BasicTextField | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.outlined.Close | ||||
| import androidx.compose.material.icons.outlined.FilterList | ||||
| import androidx.compose.material.icons.outlined.FlipToBack | ||||
| import androidx.compose.material.icons.outlined.Refresh | ||||
| @@ -19,22 +15,17 @@ import androidx.compose.material3.MaterialTheme | ||||
| import androidx.compose.material3.Text | ||||
| import androidx.compose.material3.TopAppBarScrollBehavior | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.LaunchedEffect | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.ui.Alignment | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.focus.FocusRequester | ||||
| import androidx.compose.ui.focus.focusRequester | ||||
| import androidx.compose.ui.graphics.SolidColor | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import androidx.compose.ui.text.style.TextOverflow | ||||
| import androidx.compose.ui.unit.sp | ||||
| import eu.kanade.presentation.components.AppBar | ||||
| import eu.kanade.presentation.components.Pill | ||||
| import eu.kanade.presentation.components.SearchToolbar | ||||
| import eu.kanade.presentation.library.LibraryState | ||||
| import eu.kanade.presentation.theme.active | ||||
| import eu.kanade.tachiyomi.R | ||||
| import kotlinx.coroutines.delay | ||||
|  | ||||
| @Composable | ||||
| fun LibraryToolbar( | ||||
| @@ -57,14 +48,14 @@ fun LibraryToolbar( | ||||
|         onClickSelectAll = onClickSelectAll, | ||||
|         onClickInvertSelection = onClickInvertSelection, | ||||
|     ) | ||||
|     state.searchQuery != null -> LibrarySearchToolbar( | ||||
|     state.searchQuery != null -> SearchToolbar( | ||||
|         searchQuery = state.searchQuery!!, | ||||
|         incognitoMode = incognitoMode, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         onChangeSearchQuery = { state.searchQuery = it }, | ||||
|         onClickCloseSearch = { state.searchQuery = null }, | ||||
|         onClickResetSearch = { state.searchQuery = "" }, | ||||
|         scrollBehavior = scrollBehavior, | ||||
|         incognitoMode = incognitoMode, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|     ) | ||||
|     else -> LibraryRegularToolbar( | ||||
|         title = title, | ||||
| @@ -152,49 +143,6 @@ fun LibrarySelectionToolbar( | ||||
|     ) | ||||
| } | ||||
|  | ||||
| @Composable | ||||
| fun LibrarySearchToolbar( | ||||
|     searchQuery: String, | ||||
|     incognitoMode: Boolean, | ||||
|     downloadedOnlyMode: Boolean, | ||||
|     onChangeSearchQuery: (String) -> Unit, | ||||
|     onClickCloseSearch: () -> Unit, | ||||
|     onClickResetSearch: () -> Unit, | ||||
|     scrollBehavior: TopAppBarScrollBehavior?, | ||||
| ) { | ||||
|     val focusRequester = remember { FocusRequester.Default } | ||||
|     AppBar( | ||||
|         navigateUp = onClickCloseSearch, | ||||
|         titleContent = { | ||||
|             BasicTextField( | ||||
|                 value = searchQuery, | ||||
|                 onValueChange = onChangeSearchQuery, | ||||
|                 modifier = Modifier | ||||
|                     .fillMaxWidth() | ||||
|                     .focusRequester(focusRequester), | ||||
|                 textStyle = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground), | ||||
|                 singleLine = true, | ||||
|                 cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), | ||||
|             ) | ||||
|             LaunchedEffect(focusRequester) { | ||||
|                 // TODO: https://issuetracker.google.com/issues/204502668 | ||||
|                 delay(100) | ||||
|                 focusRequester.requestFocus() | ||||
|             } | ||||
|         }, | ||||
|         actions = { | ||||
|             AnimatedVisibility(visible = searchQuery.isNotEmpty()) { | ||||
|                 IconButton(onClick = onClickResetSearch) { | ||||
|                     Icon(Icons.Outlined.Close, contentDescription = stringResource(R.string.action_reset)) | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         incognitoMode = incognitoMode, | ||||
|         downloadedOnlyMode = downloadedOnlyMode, | ||||
|         scrollBehavior = scrollBehavior, | ||||
|     ) | ||||
| } | ||||
|  | ||||
| data class LibraryToolbarTitle( | ||||
|     val text: String, | ||||
|     val numberOfManga: Int? = null, | ||||
|   | ||||
| @@ -4,31 +4,58 @@ import androidx.annotation.StringRes | ||||
| import androidx.compose.foundation.layout.WindowInsets | ||||
| import androidx.compose.foundation.layout.asPaddingValues | ||||
| import androidx.compose.foundation.layout.navigationBars | ||||
| import androidx.compose.foundation.layout.statusBarsPadding | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.outlined.Search | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.graphics.painter.Painter | ||||
| import androidx.compose.ui.input.nestedscroll.NestedScrollConnection | ||||
| import androidx.compose.ui.input.nestedscroll.nestedScroll | ||||
| import androidx.compose.ui.res.stringResource | ||||
| import eu.kanade.presentation.components.AppBar | ||||
| import eu.kanade.presentation.components.AppBarActions | ||||
| import eu.kanade.presentation.components.PreferenceRow | ||||
| import eu.kanade.presentation.components.Scaffold | ||||
| import eu.kanade.presentation.components.ScrollbarLazyColumn | ||||
| import eu.kanade.presentation.util.plus | ||||
| import eu.kanade.tachiyomi.R | ||||
|  | ||||
| @Composable | ||||
| fun SettingsMainScreen( | ||||
|     nestedScrollInterop: NestedScrollConnection, | ||||
|     navigateUp: () -> Unit, | ||||
|     sections: List<SettingsSection>, | ||||
|     onClickSearch: () -> Unit, | ||||
| ) { | ||||
|     ScrollbarLazyColumn( | ||||
|         modifier = Modifier.nestedScroll(nestedScrollInterop), | ||||
|         contentPadding = WindowInsets.navigationBars.asPaddingValues(), | ||||
|     ) { | ||||
|         sections.map { | ||||
|             item { | ||||
|                 PreferenceRow( | ||||
|                     title = stringResource(it.titleRes), | ||||
|                     painter = it.painter, | ||||
|                     onClick = it.onClick, | ||||
|                 ) | ||||
|     Scaffold( | ||||
|         modifier = Modifier.statusBarsPadding(), | ||||
|         topBar = { | ||||
|             AppBar( | ||||
|                 title = stringResource(R.string.label_settings), | ||||
|                 navigateUp = navigateUp, | ||||
|                 actions = { | ||||
|                     AppBarActions( | ||||
|                         listOf( | ||||
|                             AppBar.Action( | ||||
|                                 title = stringResource(R.string.action_search), | ||||
|                                 icon = Icons.Outlined.Search, | ||||
|                                 onClick = onClickSearch, | ||||
|                             ), | ||||
|                         ), | ||||
|                     ) | ||||
|                 }, | ||||
|             ) | ||||
|         }, | ||||
|     ) { paddingValues -> | ||||
|         ScrollbarLazyColumn( | ||||
|             contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues(), | ||||
|         ) { | ||||
|             sections.map { | ||||
|                 item { | ||||
|                     PreferenceRow( | ||||
|                         title = stringResource(it.titleRes), | ||||
|                         painter = it.painter, | ||||
|                         onClick = it.onClick, | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -7,19 +7,23 @@ import androidx.compose.foundation.layout.asPaddingValues | ||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||
| import androidx.compose.foundation.layout.navigationBars | ||||
| import androidx.compose.foundation.layout.padding | ||||
| import androidx.compose.foundation.layout.statusBarsPadding | ||||
| import androidx.compose.foundation.lazy.items | ||||
| import androidx.compose.foundation.lazy.rememberLazyListState | ||||
| import androidx.compose.material3.MaterialTheme | ||||
| import androidx.compose.material3.Text | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.runtime.collectAsState | ||||
| import androidx.compose.runtime.getValue | ||||
| import androidx.compose.runtime.mutableStateOf | ||||
| import androidx.compose.runtime.remember | ||||
| import androidx.compose.runtime.setValue | ||||
| import androidx.compose.ui.Modifier | ||||
| import androidx.compose.ui.input.nestedscroll.NestedScrollConnection | ||||
| import androidx.compose.ui.input.nestedscroll.nestedScroll | ||||
| 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.presentation.util.plus | ||||
| import eu.kanade.tachiyomi.ui.setting.SettingsController | ||||
| import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchHelper | ||||
| import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchPresenter | ||||
| @@ -27,24 +31,39 @@ import kotlin.reflect.full.createInstance | ||||
|  | ||||
| @Composable | ||||
| fun SettingsSearchScreen( | ||||
|     nestedScroll: NestedScrollConnection, | ||||
|     navigateUp: () -> Unit, | ||||
|     presenter: SettingsSearchPresenter, | ||||
|     onClickResult: (SettingsController) -> Unit, | ||||
| ) { | ||||
|     val results by presenter.state.collectAsState() | ||||
|     var query by remember { mutableStateOf("") } | ||||
|  | ||||
|     val scrollState = rememberLazyListState() | ||||
|     ScrollbarLazyColumn( | ||||
|         modifier = Modifier | ||||
|             .nestedScroll(nestedScroll), | ||||
|         contentPadding = WindowInsets.navigationBars.asPaddingValues(), | ||||
|         state = scrollState, | ||||
|     ) { | ||||
|         items( | ||||
|             items = results, | ||||
|             key = { it.key.toString() }, | ||||
|         ) { result -> | ||||
|             SearchResult(result, onClickResult) | ||||
|     Scaffold( | ||||
|         modifier = Modifier.statusBarsPadding(), | ||||
|         topBar = { | ||||
|             SearchToolbar( | ||||
|                 searchQuery = query, | ||||
|                 onChangeSearchQuery = { | ||||
|                     query = it | ||||
|                     presenter.searchSettings(it) | ||||
|                 }, | ||||
|                 onClickCloseSearch = navigateUp, | ||||
|                 onClickResetSearch = { query = "" }, | ||||
|             ) | ||||
|  | ||||
|             // TODO: search placeholder | ||||
|             // Text(stringResource(R.string.action_search_settings)) | ||||
|         }, | ||||
|     ) { paddingValues -> | ||||
|         ScrollbarLazyColumn( | ||||
|             contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues(), | ||||
|         ) { | ||||
|             items( | ||||
|                 items = results, | ||||
|                 key = { it.key.toString() }, | ||||
|             ) { result -> | ||||
|                 SearchResult(result, onClickResult) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -299,8 +299,6 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun defaultUserAgent() = flowPrefs.getString(Keys.defaultUserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0") | ||||
|  | ||||
|     fun lastSearchQuerySearchSettings() = flowPrefs.getString("last_search_query", "") | ||||
|  | ||||
|     fun filterChapterByRead() = prefs.getInt(Keys.defaultChapterFilterByRead, DomainManga.SHOW_ALL.toInt()) | ||||
|  | ||||
|     fun filterChapterByDownloaded() = prefs.getInt(Keys.defaultChapterFilterByDownloaded, DomainManga.SHOW_ALL.toInt()) | ||||
|   | ||||
| @@ -51,28 +51,6 @@ abstract class ComposeController<P : Presenter<*>>(bundle: Bundle? = null) : | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Basic Compose controller without a presenter. | ||||
|  */ | ||||
| abstract class BasicComposeController : | ||||
|     BaseController<ComposeControllerBinding>(), | ||||
|     ComposeContentController { | ||||
|  | ||||
|     override fun createBinding(inflater: LayoutInflater) = | ||||
|         ComposeControllerBinding.inflate(inflater) | ||||
|  | ||||
|     override fun onViewCreated(view: View) { | ||||
|         super.onViewCreated(view) | ||||
|  | ||||
|         binding.root.apply { | ||||
|             setComposeContent { | ||||
|                 val nestedScrollInterop = rememberNestedScrollInteropConnection() | ||||
|                 ComposeContent(nestedScrollInterop) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Basic Compose controller without a presenter. | ||||
|  */ | ||||
|   | ||||
| @@ -37,7 +37,7 @@ class ExtensionDetailsPresenter( | ||||
|  | ||||
|         presenterScope.launchIO { | ||||
|             extensionManager.getInstalledExtensionsFlow() | ||||
|                 .map { it.firstOrNull { pkg-> pkg.pkgName == pkgName } } | ||||
|                 .map { it.firstOrNull { pkg -> pkg.pkgName == pkgName } } | ||||
|                 .collectLatest { extension -> | ||||
|                     // If extension is null it's most likely uninstalled | ||||
|                     if (extension == null) { | ||||
|   | ||||
| @@ -1,9 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.ui.setting | ||||
|  | ||||
| import android.view.Menu | ||||
| import android.view.MenuInflater | ||||
| import android.view.MenuItem | ||||
| import androidx.appcompat.widget.SearchView | ||||
| import androidx.compose.material.icons.Icons | ||||
| import androidx.compose.material.icons.outlined.ChromeReaderMode | ||||
| import androidx.compose.material.icons.outlined.Code | ||||
| @@ -15,25 +11,18 @@ import androidx.compose.material.icons.outlined.Sync | ||||
| import androidx.compose.material.icons.outlined.Tune | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.graphics.vector.rememberVectorPainter | ||||
| import androidx.compose.ui.input.nestedscroll.NestedScrollConnection | ||||
| import androidx.compose.ui.res.painterResource | ||||
| import eu.kanade.presentation.more.settings.SettingsMainScreen | ||||
| import eu.kanade.presentation.more.settings.SettingsSection | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.ui.base.controller.BasicComposeController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.BasicFullComposeController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.pushController | ||||
| import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchController | ||||
| import uy.kohesive.injekt.injectLazy | ||||
|  | ||||
| class SettingsMainController : BasicComposeController() { | ||||
|  | ||||
|     private val preferences: PreferencesHelper by injectLazy() | ||||
|  | ||||
|     override fun getTitle() = resources?.getString(R.string.label_settings) | ||||
| class SettingsMainController : BasicFullComposeController() { | ||||
|  | ||||
|     @Composable | ||||
|     override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { | ||||
|     override fun ComposeContent() { | ||||
|         val settingsSections = listOf( | ||||
|             SettingsSection( | ||||
|                 titleRes = R.string.pref_category_general, | ||||
| @@ -88,34 +77,9 @@ class SettingsMainController : BasicComposeController() { | ||||
|         ) | ||||
|  | ||||
|         SettingsMainScreen( | ||||
|             nestedScrollInterop = nestedScrollInterop, | ||||
|             navigateUp = router::popCurrentController, | ||||
|             sections = settingsSections, | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { | ||||
|         inflater.inflate(R.menu.settings_main, menu) | ||||
|  | ||||
|         // Initialize search option. | ||||
|         val searchItem = menu.findItem(R.id.action_search) | ||||
|         val searchView = searchItem.actionView as SearchView | ||||
|         searchView.maxWidth = Int.MAX_VALUE | ||||
|  | ||||
|         // Change hint to show global search. | ||||
|         searchView.queryHint = applicationContext?.getString(R.string.action_search_settings) | ||||
|  | ||||
|         searchItem.setOnActionExpandListener( | ||||
|             object : MenuItem.OnActionExpandListener { | ||||
|                 override fun onMenuItemActionExpand(item: MenuItem): Boolean { | ||||
|                     preferences.lastSearchQuerySearchSettings().set("") // reset saved search query | ||||
|                     router.pushController(SettingsSearchController()) | ||||
|                     return true | ||||
|                 } | ||||
|  | ||||
|                 override fun onMenuItemActionCollapse(item: MenuItem): Boolean { | ||||
|                     return true | ||||
|                 } | ||||
|             }, | ||||
|             onClickSearch = { router.pushController(SettingsSearchController()) }, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,80 +1,20 @@ | ||||
| package eu.kanade.tachiyomi.ui.setting.search | ||||
|  | ||||
| import android.view.Menu | ||||
| import android.view.MenuInflater | ||||
| import android.view.MenuItem | ||||
| import androidx.appcompat.widget.SearchView | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.input.nestedscroll.NestedScrollConnection | ||||
| import eu.kanade.presentation.more.settings.SettingsSearchScreen | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.ui.base.controller.ComposeController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.FullComposeController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.pushController | ||||
|  | ||||
| class SettingsSearchController : ComposeController<SettingsSearchPresenter>() { | ||||
|  | ||||
|     private lateinit var searchView: SearchView | ||||
|  | ||||
|     init { | ||||
|         setHasOptionsMenu(true) | ||||
|     } | ||||
|  | ||||
|     override fun getTitle() = presenter.query | ||||
| class SettingsSearchController : FullComposeController<SettingsSearchPresenter>() { | ||||
|  | ||||
|     override fun createPresenter() = SettingsSearchPresenter() | ||||
|  | ||||
|     @Composable | ||||
|     override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { | ||||
|     override fun ComposeContent() { | ||||
|         SettingsSearchScreen( | ||||
|             nestedScroll = nestedScrollInterop, | ||||
|             navigateUp = router::popCurrentController, | ||||
|             presenter = presenter, | ||||
|             onClickResult = { controller -> | ||||
|                 searchView.query.let { | ||||
|                     presenter.setLastSearchQuerySearchSettings(it.toString()) | ||||
|                 } | ||||
|                 router.pushController(controller) | ||||
|             }, | ||||
|             onClickResult = { router.pushController(it) }, | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { | ||||
|         inflater.inflate(R.menu.settings_main, menu) | ||||
|  | ||||
|         // Initialize search menu | ||||
|         val searchItem = menu.findItem(R.id.action_search) | ||||
|         searchView = searchItem.actionView as SearchView | ||||
|         searchView.maxWidth = Int.MAX_VALUE | ||||
|         searchView.queryHint = applicationContext?.getString(R.string.action_search_settings) | ||||
|  | ||||
|         searchItem.expandActionView() | ||||
|  | ||||
|         searchItem.setOnActionExpandListener( | ||||
|             object : MenuItem.OnActionExpandListener { | ||||
|                 override fun onMenuItemActionExpand(item: MenuItem): Boolean { | ||||
|                     return true | ||||
|                 } | ||||
|  | ||||
|                 override fun onMenuItemActionCollapse(item: MenuItem): Boolean { | ||||
|                     router.popCurrentController() | ||||
|                     return false | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|         searchView.setOnQueryTextListener( | ||||
|             object : SearchView.OnQueryTextListener { | ||||
|                 override fun onQueryTextSubmit(query: String?): Boolean { | ||||
|                     presenter.searchSettings(query) | ||||
|                     return false | ||||
|                 } | ||||
|  | ||||
|                 override fun onQueryTextChange(newText: String?): Boolean { | ||||
|                     presenter.searchSettings(newText) | ||||
|                     return false | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|         searchView.setQuery(presenter.getLastSearchQuerySearchSettings(), true) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,14 +23,6 @@ class SettingsSearchPresenter( | ||||
|         SettingsSearchHelper.initPreferenceSearchResults(preferences.context) | ||||
|     } | ||||
|  | ||||
|     fun getLastSearchQuerySearchSettings(): String { | ||||
|         return preferences.lastSearchQuerySearchSettings().get() | ||||
|     } | ||||
|  | ||||
|     fun setLastSearchQuerySearchSettings(query: String) { | ||||
|         preferences.lastSearchQuerySearchSettings().set(query) | ||||
|     } | ||||
|  | ||||
|     fun searchSettings(query: String?) { | ||||
|         _state.value = if (!query.isNullOrBlank()) { | ||||
|             SettingsSearchHelper.getFilteredResults(query) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user