From 1dcf4e7f46727341ce30f5da6635496fcbbcf972 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <99822064+revonateB0T@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:32:36 +0800 Subject: [PATCH] Implement some reader settings (#856) * Initial SpinnerChoice * Apply bgColor * Introduce SwitchChoice --------- Co-authored-by: GG Bond --- .../kotlin/com/hippo/ehviewer/Settings.kt | 2 + .../com/hippo/ehviewer/ui/reader/General.kt | 27 +++++++ .../hippo/ehviewer/ui/reader/ReaderScreen.kt | 41 ++++++++-- .../hippo/ehviewer/ui/reader/SettingsPager.kt | 13 ++- .../com/hippo/ehviewer/ui/reader/Widget.kt | 79 +++++++++++++++++++ 5 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 app/src/main/kotlin/com/hippo/ehviewer/ui/reader/General.kt create mode 100644 app/src/main/kotlin/com/hippo/ehviewer/ui/reader/Widget.kt diff --git a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt index 6bb62e6d8..e6da812a3 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt @@ -185,7 +185,9 @@ object Settings : DataStorePreferences(null) { val readingMode = intPref("pref_default_reading_mode_key", ReadingModeType.LEFT_TO_RIGHT.flagValue) val orientationMode = intPref("pref_default_orientation_type_key", OrientationType.FREE.flagValue) val showReaderSeekbar = boolPref("pref_show_reader_seekbar", true) + val showPageNumber = boolPref("pref_show_page_number_key", true) var newReader by boolPref("new_compose_reader", false) + val readerTheme = intPref("pref_reader_theme_key", 1) init { if ("CN" == Locale.getDefault().country) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/General.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/General.kt new file mode 100644 index 000000000..275f407b4 --- /dev/null +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/General.kt @@ -0,0 +1,27 @@ +package com.hippo.ehviewer.ui.reader + +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringArrayResource +import androidx.compose.ui.res.stringResource +import com.hippo.ehviewer.R +import com.hippo.ehviewer.Settings +import com.hippo.ehviewer.asMutableState + +@Composable +fun ReaderGeneralSetting() = Column { + SpinnerChoice( + title = stringResource(id = R.string.pref_reader_theme), + entries = stringArrayResource(id = R.array.reader_themes), + values = stringArrayResource(id = R.array.reader_themes_values), + field = Settings.readerTheme.asMutableState(), + ) + SwitchChoice( + title = stringResource(id = R.string.pref_show_page_number), + field = Settings.showPageNumber.asMutableState(), + ) + SwitchChoice( + title = stringResource(id = R.string.pref_show_reader_seekbar), + field = Settings.showReaderSeekbar.asMutableState(), + ) +} diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt index 95317dd34..449ebda01 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderScreen.kt @@ -1,9 +1,11 @@ package com.hippo.ehviewer.ui.reader +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.pager.rememberPagerState @@ -15,14 +17,18 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.util.VelocityTrackerAddPointsFix +import androidx.compose.ui.res.colorResource import androidx.compose.ui.zIndex +import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.data.BaseGalleryInfo import com.hippo.ehviewer.collectAsState @@ -98,7 +104,7 @@ fun ReaderScreen(info: BaseGalleryInfo, page: Int = -1, navigator: DestinationsN dragHandle = null, windowInsets = WindowInsets(0), ) { - SettingsPager(modifier = Modifier.fillMaxWidth()) + SettingsPager(modifier = Modifier.fillMaxSize()) Spacer(modifier = Modifier.navigationBarsPadding()) } } @@ -106,13 +112,17 @@ fun ReaderScreen(info: BaseGalleryInfo, page: Int = -1, navigator: DestinationsN }, modifier = Modifier.zIndex(1f), ) - CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodySmall) { - PageIndicatorText( - currentPage = syncState.sliderValue, - totalPages = pageLoader.size, - modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding().zIndex(0.5f), - ) + val showPageNumber by Settings.showPageNumber.collectAsState() + if (showPageNumber) { + CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodySmall) { + PageIndicatorText( + currentPage = syncState.sliderValue, + totalPages = pageLoader.size, + modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding().zIndex(0.5f), + ) + } } + val bgColor by collectBackgroundColorAsState() GalleryPager( type = readingMode, pagerState = pagerState, @@ -143,7 +153,22 @@ fun ReaderScreen(info: BaseGalleryInfo, page: Int = -1, navigator: DestinationsN } }, onMenuRegionClick = { appbarVisible = !appbarVisible }, + modifier = Modifier.background(bgColor), ) } } } + +@Composable +private fun collectBackgroundColorAsState(): State { + val grey = colorResource(R.color.reader_background_dark) + val dark = isSystemInDarkTheme() + return Settings.readerTheme.collectAsState { theme -> + when (theme) { + 0 -> Color.White + 2 -> grey + 3 -> if (dark) grey else Color.White + else -> Color.Black + } + } +} diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/SettingsPager.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/SettingsPager.kt index 7d93dc537..8698cad3d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/SettingsPager.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/SettingsPager.kt @@ -11,6 +11,7 @@ import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -40,7 +41,15 @@ fun SettingsPager(modifier: Modifier = Modifier) { ) } } - HorizontalPager(modifier = modifier, state = pagerState) { - Spacer(modifier = Modifier.size(200.dp)) + HorizontalPager( + modifier = modifier, + state = pagerState, + verticalAlignment = Alignment.Top, + ) { page -> + when (page) { + 0 -> Spacer(modifier = Modifier.size(200.dp)) + 1 -> ReaderGeneralSetting() + 2 -> Spacer(modifier = Modifier.size(200.dp)) + } } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/Widget.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/Widget.kt new file mode 100644 index 000000000..f3a560ecf --- /dev/null +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/Widget.kt @@ -0,0 +1,79 @@ +package com.hippo.ehviewer.ui.reader + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun SpinnerChoice(title: String, entries: Array, values: Array, field: MutableState) { + var value by field + var dropdown by remember { mutableStateOf(false) } + val data = remember { entries zip values.map { v -> v.toInt() } } + Row( + modifier = Modifier.fillMaxWidth().height(48.dp).clickable { dropdown = true }.padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text(text = title, modifier = Modifier.weight(0.5f)) + Row(modifier = Modifier.weight(0.5f)) { + Text(text = data.firstNotNullOf { (k, v) -> k.takeIf { v == value } }, modifier = Modifier.weight(1f)) + Icon( + imageVector = Icons.Default.KeyboardArrowDown, + contentDescription = null, + modifier = Modifier.size(24.dp), + ) + DropdownMenu(expanded = dropdown, onDismissRequest = { dropdown = false }) { + data.forEach { (k, v) -> + DropdownMenuItem( + text = { Text(text = k) }, + onClick = { + dropdown = false + value = v + }, + modifier = Modifier.width(192.dp), + leadingIcon = { + if (value == v) { + Icon(imageVector = Icons.Default.Check, contentDescription = null) + } + }, + ) + } + } + } + } +} + +@Composable +fun SwitchChoice(title: String, field: MutableState) { + var value by field + Row( + modifier = Modifier.fillMaxWidth().height(48.dp).clickable { value = !value }.padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text(text = title, modifier = Modifier.weight(1f)) + Switch( + checked = value, + onCheckedChange = { value = !value }, + ) + } +}