Convert settings main and search views to full Compose

This commit is contained in:
arkon 2022-08-29 16:39:35 -04:00
parent 761635b572
commit f5c7aa1142
12 changed files with 148 additions and 294 deletions

View File

@ -1,13 +1,18 @@
package eu.kanade.presentation.components package eu.kanade.presentation.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.MoreVert 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.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -18,18 +23,23 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier 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.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import kotlinx.coroutines.delay
@Composable @Composable
fun AppBar( 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 AppBar {
sealed interface AppBarAction sealed interface AppBarAction

View File

@ -1,30 +1,18 @@
package eu.kanade.presentation.history.components 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.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.DeleteSweep
import androidx.compose.material.icons.outlined.Search import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable 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 androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.recent.history.HistoryPresenter import eu.kanade.tachiyomi.ui.recent.history.HistoryPresenter
import eu.kanade.tachiyomi.ui.recent.history.HistoryState import eu.kanade.tachiyomi.ui.recent.history.HistoryState
import kotlinx.coroutines.delay
@Composable @Composable
fun HistoryToolbar( fun HistoryToolbar(
@ -42,7 +30,7 @@ fun HistoryToolbar(
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
} else { } else {
HistorySearchToolbar( SearchToolbar(
searchQuery = state.searchQuery!!, searchQuery = state.searchQuery!!,
onChangeSearchQuery = { state.searchQuery = it }, onChangeSearchQuery = { state.searchQuery = it },
onClickCloseSearch = { state.searchQuery = null }, onClickCloseSearch = { state.searchQuery = null },
@ -76,46 +64,3 @@ fun HistoryRegularToolbar(
scrollBehavior = scrollBehavior, 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()
}
}

View File

@ -1,12 +1,8 @@
package eu.kanade.presentation.library.components package eu.kanade.presentation.library.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Row 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.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.FilterList import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.Refresh 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.Text
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.Pill import eu.kanade.presentation.components.Pill
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.library.LibraryState import eu.kanade.presentation.library.LibraryState
import eu.kanade.presentation.theme.active import eu.kanade.presentation.theme.active
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import kotlinx.coroutines.delay
@Composable @Composable
fun LibraryToolbar( fun LibraryToolbar(
@ -57,14 +48,14 @@ fun LibraryToolbar(
onClickSelectAll = onClickSelectAll, onClickSelectAll = onClickSelectAll,
onClickInvertSelection = onClickInvertSelection, onClickInvertSelection = onClickInvertSelection,
) )
state.searchQuery != null -> LibrarySearchToolbar( state.searchQuery != null -> SearchToolbar(
searchQuery = state.searchQuery!!, searchQuery = state.searchQuery!!,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
onChangeSearchQuery = { state.searchQuery = it }, onChangeSearchQuery = { state.searchQuery = it },
onClickCloseSearch = { state.searchQuery = null }, onClickCloseSearch = { state.searchQuery = null },
onClickResetSearch = { state.searchQuery = "" }, onClickResetSearch = { state.searchQuery = "" },
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
incognitoMode = incognitoMode,
downloadedOnlyMode = downloadedOnlyMode,
) )
else -> LibraryRegularToolbar( else -> LibraryRegularToolbar(
title = title, 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( data class LibraryToolbarTitle(
val text: String, val text: String,
val numberOfManga: Int? = null, val numberOfManga: Int? = null,

View File

@ -4,31 +4,58 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBars 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.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter 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 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.PreferenceRow
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R
@Composable @Composable
fun SettingsMainScreen( fun SettingsMainScreen(
nestedScrollInterop: NestedScrollConnection, navigateUp: () -> Unit,
sections: List<SettingsSection>, sections: List<SettingsSection>,
onClickSearch: () -> Unit,
) { ) {
ScrollbarLazyColumn( Scaffold(
modifier = Modifier.nestedScroll(nestedScrollInterop), modifier = Modifier.statusBarsPadding(),
contentPadding = WindowInsets.navigationBars.asPaddingValues(), topBar = {
) { AppBar(
sections.map { title = stringResource(R.string.label_settings),
item { navigateUp = navigateUp,
PreferenceRow( actions = {
title = stringResource(it.titleRes), AppBarActions(
painter = it.painter, listOf(
onClick = it.onClick, 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,
)
}
} }
} }
} }

View File

@ -7,19 +7,23 @@ import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue 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.Modifier
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.util.horizontalPadding 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.SettingsController
import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchHelper import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchHelper
import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchPresenter import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchPresenter
@ -27,24 +31,39 @@ import kotlin.reflect.full.createInstance
@Composable @Composable
fun SettingsSearchScreen( fun SettingsSearchScreen(
nestedScroll: NestedScrollConnection, navigateUp: () -> Unit,
presenter: SettingsSearchPresenter, presenter: SettingsSearchPresenter,
onClickResult: (SettingsController) -> Unit, onClickResult: (SettingsController) -> Unit,
) { ) {
val results by presenter.state.collectAsState() val results by presenter.state.collectAsState()
var query by remember { mutableStateOf("") }
val scrollState = rememberLazyListState() Scaffold(
ScrollbarLazyColumn( modifier = Modifier.statusBarsPadding(),
modifier = Modifier topBar = {
.nestedScroll(nestedScroll), SearchToolbar(
contentPadding = WindowInsets.navigationBars.asPaddingValues(), searchQuery = query,
state = scrollState, onChangeSearchQuery = {
) { query = it
items( presenter.searchSettings(it)
items = results, },
key = { it.key.toString() }, onClickCloseSearch = navigateUp,
) { result -> onClickResetSearch = { query = "" },
SearchResult(result, onClickResult) )
// 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)
}
} }
} }
} }

View File

@ -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 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 filterChapterByRead() = prefs.getInt(Keys.defaultChapterFilterByRead, DomainManga.SHOW_ALL.toInt())
fun filterChapterByDownloaded() = prefs.getInt(Keys.defaultChapterFilterByDownloaded, DomainManga.SHOW_ALL.toInt()) fun filterChapterByDownloaded() = prefs.getInt(Keys.defaultChapterFilterByDownloaded, DomainManga.SHOW_ALL.toInt())

View File

@ -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. * Basic Compose controller without a presenter.
*/ */

View File

@ -37,7 +37,7 @@ class ExtensionDetailsPresenter(
presenterScope.launchIO { presenterScope.launchIO {
extensionManager.getInstalledExtensionsFlow() extensionManager.getInstalledExtensionsFlow()
.map { it.firstOrNull { pkg-> pkg.pkgName == pkgName } } .map { it.firstOrNull { pkg -> pkg.pkgName == pkgName } }
.collectLatest { extension -> .collectLatest { extension ->
// If extension is null it's most likely uninstalled // If extension is null it's most likely uninstalled
if (extension == null) { if (extension == null) {

View File

@ -1,9 +1,5 @@
package eu.kanade.tachiyomi.ui.setting 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.Icons
import androidx.compose.material.icons.outlined.ChromeReaderMode import androidx.compose.material.icons.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code 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.material.icons.outlined.Tune
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import eu.kanade.presentation.more.settings.SettingsMainScreen import eu.kanade.presentation.more.settings.SettingsMainScreen
import eu.kanade.presentation.more.settings.SettingsSection import eu.kanade.presentation.more.settings.SettingsSection
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.base.controller.BasicFullComposeController
import eu.kanade.tachiyomi.ui.base.controller.BasicComposeController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController
import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchController import eu.kanade.tachiyomi.ui.setting.search.SettingsSearchController
import uy.kohesive.injekt.injectLazy
class SettingsMainController : BasicComposeController() { class SettingsMainController : BasicFullComposeController() {
private val preferences: PreferencesHelper by injectLazy()
override fun getTitle() = resources?.getString(R.string.label_settings)
@Composable @Composable
override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { override fun ComposeContent() {
val settingsSections = listOf( val settingsSections = listOf(
SettingsSection( SettingsSection(
titleRes = R.string.pref_category_general, titleRes = R.string.pref_category_general,
@ -88,34 +77,9 @@ class SettingsMainController : BasicComposeController() {
) )
SettingsMainScreen( SettingsMainScreen(
nestedScrollInterop = nestedScrollInterop, navigateUp = router::popCurrentController,
sections = settingsSections, sections = settingsSections,
) onClickSearch = { router.pushController(SettingsSearchController()) },
}
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
}
},
) )
} }
} }

View File

@ -1,80 +1,20 @@
package eu.kanade.tachiyomi.ui.setting.search 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.runtime.Composable
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import eu.kanade.presentation.more.settings.SettingsSearchScreen import eu.kanade.presentation.more.settings.SettingsSearchScreen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
import eu.kanade.tachiyomi.ui.base.controller.ComposeController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController
class SettingsSearchController : ComposeController<SettingsSearchPresenter>() { class SettingsSearchController : FullComposeController<SettingsSearchPresenter>() {
private lateinit var searchView: SearchView
init {
setHasOptionsMenu(true)
}
override fun getTitle() = presenter.query
override fun createPresenter() = SettingsSearchPresenter() override fun createPresenter() = SettingsSearchPresenter()
@Composable @Composable
override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { override fun ComposeContent() {
SettingsSearchScreen( SettingsSearchScreen(
nestedScroll = nestedScrollInterop, navigateUp = router::popCurrentController,
presenter = presenter, presenter = presenter,
onClickResult = { controller -> onClickResult = { router.pushController(it) },
searchView.query.let {
presenter.setLastSearchQuerySearchSettings(it.toString())
}
router.pushController(controller)
},
) )
} }
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)
}
} }

View File

@ -23,14 +23,6 @@ class SettingsSearchPresenter(
SettingsSearchHelper.initPreferenceSearchResults(preferences.context) SettingsSearchHelper.initPreferenceSearchResults(preferences.context)
} }
fun getLastSearchQuerySearchSettings(): String {
return preferences.lastSearchQuerySearchSettings().get()
}
fun setLastSearchQuerySearchSettings(query: String) {
preferences.lastSearchQuerySearchSettings().set(query)
}
fun searchSettings(query: String?) { fun searchSettings(query: String?) {
_state.value = if (!query.isNullOrBlank()) { _state.value = if (!query.isNullOrBlank()) {
SettingsSearchHelper.getFilteredResults(query) SettingsSearchHelper.getFilteredResults(query)

View File

@ -1,12 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search_24dp"
android:title="@string/action_search"
app:actionViewClass="eu.kanade.tachiyomi.widget.TachiyomiSearchView"
app:iconTint="?attr/colorOnSurface"
app:showAsAction="collapseActionView|ifRoom" />
</menu>