|
@@ -1,7 +1,13 @@
|
|
|
package eu.kanade.presentation.more.settings.screen
|
|
|
|
|
|
import androidx.annotation.StringRes
|
|
|
+import androidx.compose.foundation.background
|
|
|
+import androidx.compose.foundation.isSystemInDarkTheme
|
|
|
+import androidx.compose.foundation.layout.padding
|
|
|
+import androidx.compose.foundation.lazy.items
|
|
|
+import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
import androidx.compose.material.icons.Icons
|
|
|
+import androidx.compose.material.icons.filled.ArrowBack
|
|
|
import androidx.compose.material.icons.outlined.ChromeReaderMode
|
|
|
import androidx.compose.material.icons.outlined.Code
|
|
|
import androidx.compose.material.icons.outlined.CollectionsBookmark
|
|
@@ -13,103 +19,210 @@ import androidx.compose.material.icons.outlined.Security
|
|
|
import androidx.compose.material.icons.outlined.SettingsBackupRestore
|
|
|
import androidx.compose.material.icons.outlined.Sync
|
|
|
import androidx.compose.material.icons.outlined.Tune
|
|
|
+import androidx.compose.material3.Icon
|
|
|
+import androidx.compose.material3.IconButton
|
|
|
+import androidx.compose.material3.LocalContentColor
|
|
|
+import androidx.compose.material3.MaterialTheme
|
|
|
+import androidx.compose.material3.Text
|
|
|
+import androidx.compose.material3.TopAppBar
|
|
|
import androidx.compose.runtime.Composable
|
|
|
-import androidx.compose.runtime.NonRestartableComposable
|
|
|
-import androidx.compose.runtime.ReadOnlyComposable
|
|
|
+import androidx.compose.runtime.CompositionLocalProvider
|
|
|
+import androidx.compose.runtime.remember
|
|
|
+import androidx.compose.ui.Modifier
|
|
|
+import androidx.compose.ui.draw.clip
|
|
|
+import androidx.compose.ui.graphics.Color
|
|
|
+import androidx.compose.ui.graphics.toArgb
|
|
|
+import androidx.compose.ui.graphics.vector.ImageVector
|
|
|
import androidx.compose.ui.res.stringResource
|
|
|
+import androidx.compose.ui.unit.dp
|
|
|
+import androidx.compose.ui.util.fastFirstOrNull
|
|
|
+import androidx.core.graphics.ColorUtils
|
|
|
+import cafe.adriel.voyager.core.screen.Screen
|
|
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
|
|
+import cafe.adriel.voyager.navigator.Navigator
|
|
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
|
|
import eu.kanade.presentation.components.AppBar
|
|
|
import eu.kanade.presentation.components.AppBarActions
|
|
|
-import eu.kanade.presentation.more.settings.Preference
|
|
|
-import eu.kanade.presentation.more.settings.PreferenceScaffold
|
|
|
+import eu.kanade.presentation.components.LazyColumn
|
|
|
+import eu.kanade.presentation.components.Scaffold
|
|
|
+import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
|
|
|
import eu.kanade.presentation.util.LocalBackPress
|
|
|
import eu.kanade.tachiyomi.R
|
|
|
|
|
|
-object SettingsMainScreen : SearchableSettings {
|
|
|
-
|
|
|
+object SettingsMainScreen : Screen {
|
|
|
@Composable
|
|
|
- @ReadOnlyComposable
|
|
|
- @StringRes
|
|
|
- override fun getTitleRes() = R.string.label_settings
|
|
|
+ override fun Content() {
|
|
|
+ Content(twoPane = false)
|
|
|
+ }
|
|
|
|
|
|
@Composable
|
|
|
- @NonRestartableComposable
|
|
|
- override fun getPreferences(): List<Preference> {
|
|
|
- val navigator = LocalNavigator.currentOrThrow
|
|
|
- return listOf(
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_general),
|
|
|
- icon = Icons.Outlined.Tune,
|
|
|
- onClick = { navigator.push(SettingsGeneralScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_appearance),
|
|
|
- icon = Icons.Outlined.Palette,
|
|
|
- onClick = { navigator.push(SettingsAppearanceScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_library),
|
|
|
- icon = Icons.Outlined.CollectionsBookmark,
|
|
|
- onClick = { navigator.push(SettingsLibraryScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_reader),
|
|
|
- icon = Icons.Outlined.ChromeReaderMode,
|
|
|
- onClick = { navigator.push(SettingsReaderScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_downloads),
|
|
|
- icon = Icons.Outlined.GetApp,
|
|
|
- onClick = { navigator.push(SettingsDownloadScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_tracking),
|
|
|
- icon = Icons.Outlined.Sync,
|
|
|
- onClick = { navigator.push(SettingsTrackingScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.browse),
|
|
|
- icon = Icons.Outlined.Explore,
|
|
|
- onClick = { navigator.push(SettingsBrowseScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.label_backup),
|
|
|
- icon = Icons.Outlined.SettingsBackupRestore,
|
|
|
- onClick = { navigator.push(SettingsBackupScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_security),
|
|
|
- icon = Icons.Outlined.Security,
|
|
|
- onClick = { navigator.push(SettingsSecurityScreen()) },
|
|
|
- ),
|
|
|
- Preference.PreferenceItem.TextPreference(
|
|
|
- title = stringResource(R.string.pref_category_advanced),
|
|
|
- icon = Icons.Outlined.Code,
|
|
|
- onClick = { navigator.push(SettingsAdvancedScreen()) },
|
|
|
- ),
|
|
|
- )
|
|
|
+ private fun getPalerSurface(): Color {
|
|
|
+ val surface = MaterialTheme.colorScheme.surface
|
|
|
+ val dark = isSystemInDarkTheme()
|
|
|
+ return remember(surface, dark) {
|
|
|
+ val arr = FloatArray(3)
|
|
|
+ ColorUtils.colorToHSL(surface.toArgb(), arr)
|
|
|
+ arr[2] = if (dark) {
|
|
|
+ arr[2] - 0.05f
|
|
|
+ } else {
|
|
|
+ arr[2] + 0.02f
|
|
|
+ }.coerceIn(0f, 1f)
|
|
|
+ Color.hsl(arr[0], arr[1], arr[2])
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Composable
|
|
|
- override fun Content() {
|
|
|
+ fun Content(twoPane: Boolean) {
|
|
|
val navigator = LocalNavigator.currentOrThrow
|
|
|
val backPress = LocalBackPress.currentOrThrow
|
|
|
- PreferenceScaffold(
|
|
|
- titleRes = getTitleRes(),
|
|
|
- actions = {
|
|
|
- AppBarActions(
|
|
|
- listOf(
|
|
|
- AppBar.Action(
|
|
|
- title = stringResource(R.string.action_search),
|
|
|
- icon = Icons.Outlined.Search,
|
|
|
- onClick = { navigator.push(SettingsSearchScreen()) },
|
|
|
- ),
|
|
|
- ),
|
|
|
- )
|
|
|
+ val containerColor = if (twoPane) getPalerSurface() else MaterialTheme.colorScheme.surface
|
|
|
+ Scaffold(
|
|
|
+ topBar = { scrollBehavior ->
|
|
|
+ // https://issuetracker.google.com/issues/249688556
|
|
|
+ MaterialTheme(
|
|
|
+ colorScheme = MaterialTheme.colorScheme.copy(surface = containerColor),
|
|
|
+ ) {
|
|
|
+ TopAppBar(
|
|
|
+ title = {
|
|
|
+ Text(
|
|
|
+ text = stringResource(R.string.label_settings),
|
|
|
+ modifier = Modifier.padding(start = 8.dp),
|
|
|
+ )
|
|
|
+ },
|
|
|
+ navigationIcon = {
|
|
|
+ IconButton(onClick = backPress::invoke) {
|
|
|
+ Icon(
|
|
|
+ imageVector = Icons.Default.ArrowBack,
|
|
|
+ contentDescription = stringResource(R.string.abc_action_bar_up_description),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ actions = {
|
|
|
+ AppBarActions(
|
|
|
+ listOf(
|
|
|
+ AppBar.Action(
|
|
|
+ title = stringResource(R.string.action_search),
|
|
|
+ icon = Icons.Outlined.Search,
|
|
|
+ onClick = { navigator.navigate(SettingsSearchScreen(), twoPane) },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ },
|
|
|
+ scrollBehavior = scrollBehavior,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ containerColor = containerColor,
|
|
|
+ content = { contentPadding ->
|
|
|
+ LazyColumn(contentPadding = contentPadding) {
|
|
|
+ items(
|
|
|
+ items = items,
|
|
|
+ key = { it.hashCode() },
|
|
|
+ ) { item ->
|
|
|
+ var modifier: Modifier = Modifier
|
|
|
+ var contentColor = LocalContentColor.current
|
|
|
+ if (twoPane) {
|
|
|
+ val selected = navigator.items.fastFirstOrNull { it::class == item.screen::class } != null
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(horizontal = 8.dp)
|
|
|
+ .clip(RoundedCornerShape(24.dp))
|
|
|
+ .then(
|
|
|
+ if (selected) {
|
|
|
+ Modifier.background(MaterialTheme.colorScheme.surfaceVariant)
|
|
|
+ } else {
|
|
|
+ Modifier
|
|
|
+ },
|
|
|
+ )
|
|
|
+ if (selected) {
|
|
|
+ contentColor = MaterialTheme.colorScheme.onSurfaceVariant
|
|
|
+ }
|
|
|
+ }
|
|
|
+ CompositionLocalProvider(LocalContentColor provides contentColor) {
|
|
|
+ TextPreferenceWidget(
|
|
|
+ modifier = modifier,
|
|
|
+ title = stringResource(item.titleRes),
|
|
|
+ subtitle = stringResource(item.subtitleRes),
|
|
|
+ icon = item.icon,
|
|
|
+ onPreferenceClick = { navigator.navigate(item.screen, twoPane) },
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
- onBackPressed = backPress::invoke,
|
|
|
- itemsProvider = { getPreferences() },
|
|
|
)
|
|
|
}
|
|
|
+
|
|
|
+ private fun Navigator.navigate(screen: Screen, twoPane: Boolean) {
|
|
|
+ if (twoPane) replaceAll(screen) else push(screen)
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+private data class Item(
|
|
|
+ @StringRes val titleRes: Int,
|
|
|
+ @StringRes val subtitleRes: Int,
|
|
|
+ val icon: ImageVector,
|
|
|
+ val screen: Screen,
|
|
|
+)
|
|
|
+
|
|
|
+private val items = listOf(
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_general,
|
|
|
+ subtitleRes = R.string.pref_general_summary,
|
|
|
+ icon = Icons.Outlined.Tune,
|
|
|
+ screen = SettingsGeneralScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_appearance,
|
|
|
+ subtitleRes = R.string.pref_appearance_summary,
|
|
|
+ icon = Icons.Outlined.Palette,
|
|
|
+ screen = SettingsAppearanceScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_library,
|
|
|
+ subtitleRes = R.string.pref_library_summary,
|
|
|
+ icon = Icons.Outlined.CollectionsBookmark,
|
|
|
+ screen = SettingsLibraryScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_reader,
|
|
|
+ subtitleRes = R.string.pref_reader_summary,
|
|
|
+ icon = Icons.Outlined.ChromeReaderMode,
|
|
|
+ screen = SettingsReaderScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_downloads,
|
|
|
+ subtitleRes = R.string.pref_downloads_summary,
|
|
|
+ icon = Icons.Outlined.GetApp,
|
|
|
+ screen = SettingsDownloadScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_tracking,
|
|
|
+ subtitleRes = R.string.pref_tracking_summary,
|
|
|
+ icon = Icons.Outlined.Sync,
|
|
|
+ screen = SettingsTrackingScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.browse,
|
|
|
+ subtitleRes = R.string.pref_browse_summary,
|
|
|
+ icon = Icons.Outlined.Explore,
|
|
|
+ screen = SettingsBrowseScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.label_backup,
|
|
|
+ subtitleRes = R.string.pref_backup_summary,
|
|
|
+ icon = Icons.Outlined.SettingsBackupRestore,
|
|
|
+ screen = SettingsBackupScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_security,
|
|
|
+ subtitleRes = R.string.pref_security_summary,
|
|
|
+ icon = Icons.Outlined.Security,
|
|
|
+ screen = SettingsSecurityScreen(),
|
|
|
+ ),
|
|
|
+ Item(
|
|
|
+ titleRes = R.string.pref_category_advanced,
|
|
|
+ subtitleRes = R.string.pref_advanced_summary,
|
|
|
+ icon = Icons.Outlined.Code,
|
|
|
+ screen = SettingsAdvancedScreen(),
|
|
|
+ ),
|
|
|
+)
|