mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +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