feat(ui): add line height multiple preference for reading page (#620)

This commit is contained in:
junkfood 2024-03-10 21:15:16 +08:00 committed by GitHub
parent 53523e44ab
commit 098ec08663
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 99 additions and 7 deletions

View File

@ -58,6 +58,7 @@ fun Preferences.toSettings(): Settings {
readingPageTonalElevation = ReadingPageTonalElevationPreference.fromPreferences(this),
readingAutoHideToolbar = ReadingAutoHideToolbarPreference.fromPreferences(this),
readingTextFontSize = ReadingTextFontSizePreference.fromPreferences(this),
readingTextLineHeight = ReadingTextLineHeightPreference.fromPreferences(this),
readingLetterSpacing = ReadingLetterSpacingPreference.fromPreferences(this),
readingTextHorizontalPadding = ReadingTextHorizontalPaddingPreference.fromPreferences(this),
readingTextAlign = ReadingTextAlignPreference.fromPreferences(this),

View File

@ -0,0 +1,25 @@
package me.ash.reader.infrastructure.preference
import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
data object ReadingTextLineHeightPreference {
const val default = 1f
private val range = 0.8f..2f
fun put(context: Context, scope: CoroutineScope, value: Float) {
scope.launch {
context.dataStore.put(DataStoreKeys.ReadingLineHeight, value)
}
}
fun Float.coerceToRange() = coerceIn(range)
fun fromPreferences(preferences: Preferences) =
preferences[DataStoreKeys.ReadingLineHeight.key] ?: default
}

View File

@ -57,6 +57,7 @@ data class Settings(
val readingPageTonalElevation: ReadingPageTonalElevationPreference = ReadingPageTonalElevationPreference.default,
val readingAutoHideToolbar: ReadingAutoHideToolbarPreference = ReadingAutoHideToolbarPreference.default,
val readingTextFontSize: Int = ReadingTextFontSizePreference.default,
val readingTextLineHeight: Float = ReadingTextLineHeightPreference.default,
val readingLetterSpacing: Double = ReadingLetterSpacingPreference.default,
val readingTextHorizontalPadding: Int = ReadingTextHorizontalPaddingPreference.default,
val readingTextAlign: ReadingTextAlignPreference = ReadingTextAlignPreference.default,
@ -158,6 +159,7 @@ val LocalReadingPageTonalElevation =
val LocalReadingAutoHideToolbar =
compositionLocalOf<ReadingAutoHideToolbarPreference> { ReadingAutoHideToolbarPreference.default }
val LocalReadingTextFontSize = compositionLocalOf { ReadingTextFontSizePreference.default }
val LocalReadingTextLineHeight = compositionLocalOf { ReadingTextLineHeightPreference.default }
val LocalReadingLetterSpacing = compositionLocalOf { ReadingLetterSpacingPreference.default }
val LocalReadingTextHorizontalPadding =
compositionLocalOf { ReadingTextHorizontalPaddingPreference.default }
@ -261,6 +263,7 @@ fun SettingsProvider(
LocalReadingPageTonalElevation provides settings.readingPageTonalElevation,
LocalReadingAutoHideToolbar provides settings.readingAutoHideToolbar,
LocalReadingTextFontSize provides settings.readingTextFontSize,
LocalReadingTextLineHeight provides settings.readingTextLineHeight,
LocalReadingLetterSpacing provides settings.readingLetterSpacing,
LocalReadingTextHorizontalPadding provides settings.readingTextHorizontalPadding,
LocalReadingTextAlign provides settings.readingTextAlign,

View File

@ -295,6 +295,12 @@ sealed class DataStoreKeys<T> {
get() = intPreferencesKey("readingTextFontSize")
}
object ReadingLineHeight : DataStoreKeys<Float>() {
override val key: Preferences.Key<Float>
get() = floatPreferencesKey("readingTextLineHeight")
}
object ReadingLetterSpacing : DataStoreKeys<Double>() {
override val key: Preferences.Key<Double>

View File

@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
@ -25,6 +26,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems
@ -32,6 +36,7 @@ import me.ash.reader.R
import me.ash.reader.infrastructure.preference.LocalPullToSwitchArticle
import me.ash.reader.infrastructure.preference.LocalReadingAutoHideToolbar
import me.ash.reader.infrastructure.preference.LocalReadingPageTonalElevation
import me.ash.reader.infrastructure.preference.LocalReadingTextLineHeight
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.showToast
import me.ash.reader.ui.motion.materialSharedAxisY
@ -169,9 +174,13 @@ fun ReadingPage(
saver = LazyListState.Saver
) { LazyListState() }
CompositionLocalProvider(
LocalOverscrollConfiguration provides
if (isPullToSwitchArticleEnabled) null else LocalOverscrollConfiguration.current
if (isPullToSwitchArticleEnabled) null else LocalOverscrollConfiguration.current,
LocalTextStyle provides LocalTextStyle.current.run {
merge(lineHeight = if (lineHeight.isSpecified) (lineHeight.value * LocalReadingTextLineHeight.current).sp else TextUnit.Unspecified)
}
) {
Box(
modifier = Modifier.fillMaxSize(),

View File

@ -18,6 +18,7 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import me.ash.reader.R
import me.ash.reader.infrastructure.preference.*
import me.ash.reader.infrastructure.preference.ReadingTextLineHeightPreference.coerceToRange
import me.ash.reader.ui.component.base.*
import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.theme.palette.onLight
@ -31,18 +32,21 @@ fun ReadingTextPage(
val readingTheme = LocalReadingTheme.current
val fontSize = LocalReadingTextFontSize.current
val lineHeight = LocalReadingTextLineHeight.current
val letterSpacing = LocalReadingLetterSpacing.current
val horizontalPadding = LocalReadingTextHorizontalPadding.current
val align = LocalReadingTextAlign.current
val bold = LocalReadingTextBold.current
var fontSizeDialogVisible by remember { mutableStateOf(false) }
var lineHeightDialogVisible by remember { mutableStateOf(false) }
var letterSpacingDialogVisible by remember { mutableStateOf(false) }
var horizontalPaddingDialogVisible by remember { mutableStateOf(false) }
var alignDialogVisible by remember { mutableStateOf(false) }
var fontSizeValue: Int? by remember { mutableStateOf(fontSize) }
var letterSpacingValue: String? by remember { mutableStateOf(letterSpacing.toString()) }
var lineHeightMultipleValue: String by remember(lineHeight) { mutableStateOf(lineHeight.toString()) }
var horizontalPaddingValue: Int? by remember { mutableStateOf(horizontalPadding) }
RYScaffold(
@ -110,6 +114,11 @@ fun ReadingTextPage(
desc = "${letterSpacing}sp",
onClick = { letterSpacingDialogVisible = true },
) {}
SettingItem(
title = stringResource(R.string.line_height_multiple),
desc = lineHeightMultipleValue,
onClick = { lineHeightDialogVisible = true },
) {}
SettingItem(
title = stringResource(R.string.horizontal_padding),
desc = "${horizontalPadding}dp",
@ -148,6 +157,29 @@ fun ReadingTextPage(
}
)
TextFieldDialog(
visible = lineHeightDialogVisible,
title = stringResource(R.string.line_height_multiple),
value = lineHeightMultipleValue,
placeholder = stringResource(R.string.value),
onValueChange = {
lineHeightMultipleValue = it
},
onDismissRequest = {
lineHeightDialogVisible = false
},
onConfirm = {
ReadingTextLineHeightPreference.put(
context,
scope,
(lineHeightMultipleValue.toFloatOrNull()
?: ReadingTextLineHeightPreference.default).coerceToRange()
)
ReadingThemePreference.Custom.put(context, scope)
lineHeightDialogVisible = false
}
)
TextFieldDialog(
visible = letterSpacingDialogVisible,
title = stringResource(R.string.letter_spacing),
@ -160,7 +192,11 @@ fun ReadingTextPage(
letterSpacingDialogVisible = false
},
onConfirm = {
ReadingLetterSpacingPreference.put(context, scope, letterSpacingValue?.toDoubleOrNull() ?: 0.0)
ReadingLetterSpacingPreference.put(
context,
scope,
letterSpacingValue?.toDoubleOrNull() ?: 0.0
)
ReadingThemePreference.Custom.put(context, scope)
letterSpacingDialogVisible = false
}

View File

@ -1,9 +1,12 @@
package me.ash.reader.ui.page.settings.color.reading
import androidx.compose.foundation.LocalOverscrollConfiguration
import androidx.compose.foundation.layout.*
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -11,7 +14,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.sp
import me.ash.reader.R
import me.ash.reader.infrastructure.preference.*
import me.ash.reader.ui.component.reader.bodyStyle
@ -62,10 +68,15 @@ fun TitleAndTextPreview() {
.padding(horizontal = textHorizontalPadding().dp)
)
Spacer(modifier = Modifier.height(20.dp))
Text(
text = stringResource(id = R.string.preview_article_desc),
style = bodyStyle(),
modifier = Modifier.padding(horizontal = textHorizontalPadding().dp)
)
CompositionLocalProvider(
LocalTextStyle provides LocalTextStyle.current.run {
merge(lineHeight = if (lineHeight.isSpecified) (lineHeight.value * LocalReadingTextLineHeight.current).sp else TextUnit.Unspecified)
}) {
Text(
text = stringResource(id = R.string.preview_article_desc),
style = bodyStyle(),
modifier = Modifier.padding(horizontal = textHorizontalPadding().dp)
)
}
}
}

View File

@ -419,6 +419,7 @@
<string name="none">None</string>
<string name="toggle_read">Toggle read</string>
<string name="toggle_starred">Toggle starred</string>
<string name="line_height_multiple">Line height multiple</string>
<string name="export">Export</string>
<string name="pull_to_switch_article">Pull to switch article</string>
<string name="mark_above_as_read">Mark above as read</string>