tachiyomi/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsMainScreen.kt
arkon 0d1bced122 Replace remaining Android-specific strings
Also renaming the helper composables so it's a bit easier to find/replace everything
in forks.
2023-11-18 19:41:33 -05:00

239 lines
9.7 KiB
Kotlin

package eu.kanade.presentation.more.settings.screen
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ChromeReaderMode
import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.CollectionsBookmark
import androidx.compose.material.icons.outlined.Explore
import androidx.compose.material.icons.outlined.GetApp
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Palette
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material.icons.outlined.Security
import androidx.compose.material.icons.outlined.Storage
import androidx.compose.material.icons.outlined.Sync
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
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.unit.dp
import androidx.core.graphics.ColorUtils
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentOrThrow
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.more.settings.screen.about.AboutScreen
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.util.LocalBackPress
import eu.kanade.presentation.util.Screen
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import cafe.adriel.voyager.core.screen.Screen as VoyagerScreen
object SettingsMainScreen : Screen() {
@Composable
override fun Content() {
Content(twoPane = false)
}
@Composable
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
fun Content(twoPane: Boolean) {
val navigator = LocalNavigator.currentOrThrow
val backPress = LocalBackPress.currentOrThrow
val containerColor = if (twoPane) getPalerSurface() else MaterialTheme.colorScheme.surface
val topBarState = rememberTopAppBarState()
Scaffold(
topBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topBarState),
topBar = { scrollBehavior ->
AppBar(
title = stringResource(MR.strings.label_settings),
navigateUp = backPress::invoke,
actions = {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(MR.strings.action_search),
icon = Icons.Outlined.Search,
onClick = { navigator.navigate(SettingsSearchScreen(), twoPane) },
),
),
)
},
scrollBehavior = scrollBehavior,
)
},
containerColor = containerColor,
content = { contentPadding ->
val state = rememberLazyListState()
val indexSelected = if (twoPane) {
items.indexOfFirst { it.screen::class == navigator.items.first()::class }
.also {
LaunchedEffect(Unit) {
state.animateScrollToItem(it)
if (it > 0) {
// Lift scroll
topBarState.contentOffset = topBarState.heightOffsetLimit
}
}
}
} else {
null
}
LazyColumn(
state = state,
contentPadding = contentPadding,
) {
itemsIndexed(
items = items,
key = { _, item -> item.hashCode() },
) { index, item ->
val selected = indexSelected == index
var modifier: Modifier = Modifier
var contentColor = LocalContentColor.current
if (twoPane) {
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 = item.formatSubtitle(),
icon = item.icon,
onPreferenceClick = { navigator.navigate(item.screen, twoPane) },
)
}
}
}
},
)
}
private fun Navigator.navigate(screen: VoyagerScreen, twoPane: Boolean) {
if (twoPane) replaceAll(screen) else push(screen)
}
private data class Item(
val titleRes: StringResource,
val subtitleRes: StringResource? = null,
val formatSubtitle: @Composable () -> String? = { subtitleRes?.let { stringResource(it) } },
val icon: ImageVector,
val screen: VoyagerScreen,
)
private val items = listOf(
Item(
titleRes = MR.strings.pref_category_appearance,
subtitleRes = MR.strings.pref_appearance_summary,
icon = Icons.Outlined.Palette,
screen = SettingsAppearanceScreen,
),
Item(
titleRes = MR.strings.pref_category_library,
subtitleRes = MR.strings.pref_library_summary,
icon = Icons.Outlined.CollectionsBookmark,
screen = SettingsLibraryScreen,
),
Item(
titleRes = MR.strings.pref_category_reader,
subtitleRes = MR.strings.pref_reader_summary,
icon = Icons.AutoMirrored.Outlined.ChromeReaderMode,
screen = SettingsReaderScreen,
),
Item(
titleRes = MR.strings.pref_category_downloads,
subtitleRes = MR.strings.pref_downloads_summary,
icon = Icons.Outlined.GetApp,
screen = SettingsDownloadScreen,
),
Item(
titleRes = MR.strings.pref_category_tracking,
subtitleRes = MR.strings.pref_tracking_summary,
icon = Icons.Outlined.Sync,
screen = SettingsTrackingScreen,
),
Item(
titleRes = MR.strings.browse,
subtitleRes = MR.strings.pref_browse_summary,
icon = Icons.Outlined.Explore,
screen = SettingsBrowseScreen,
),
Item(
titleRes = MR.strings.label_data_storage,
subtitleRes = MR.strings.pref_backup_summary,
icon = Icons.Outlined.Storage,
screen = SettingsDataScreen,
),
Item(
titleRes = MR.strings.pref_category_security,
subtitleRes = MR.strings.pref_security_summary,
icon = Icons.Outlined.Security,
screen = SettingsSecurityScreen,
),
Item(
titleRes = MR.strings.pref_category_advanced,
subtitleRes = MR.strings.pref_advanced_summary,
icon = Icons.Outlined.Code,
screen = SettingsAdvancedScreen,
),
Item(
titleRes = MR.strings.pref_category_about,
formatSubtitle = {
"${stringResource(MR.strings.app_name)} ${AboutScreen.getVersionName(withBuildDate = false)}"
},
icon = Icons.Outlined.Info,
screen = AboutScreen,
),
)
}