diff --git a/app/src/main/java/ua/acclorite/book_story/domain/util/DataStoreConstants.kt b/app/src/main/java/ua/acclorite/book_story/domain/util/DataStoreConstants.kt index 0c262624..eee4310b 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/util/DataStoreConstants.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/util/DataStoreConstants.kt @@ -27,6 +27,7 @@ object DataStoreConstants { val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height") val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation") val TEXT_ALIGNMENT = stringPreferencesKey("text_alignment") + val LETTER_SPACING = intPreferencesKey("letter_spacing") // Browse settings val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt index bed48b01..a260b95d 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainEvent.kt @@ -30,4 +30,5 @@ sealed class MainEvent { data class OnChangeBrowseIncludedFilterItem(val item: String) : MainEvent() data class OnChangeTextAlignment(val alignment: String) : MainEvent() data class OnChangeDoublePressExit(val bool: Boolean) : MainEvent() + data class OnChangeLetterSpacing(val spacing: Int) : MainEvent() } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainState.kt b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainState.kt index b2df2a23..6267744f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainState.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainState.kt @@ -57,6 +57,7 @@ data class MainState( val doubleClickTranslation: Boolean? = null, val fastColorPresetChange: Boolean? = null, val textAlignment: ReaderTextAlignment? = null, + val letterSpacing: Int? = null, // Browse Settings val browseFilesStructure: BrowseFilesStructure? = null, @@ -166,6 +167,9 @@ data class MainState( val doublePressExit = data[DOUBLE_PRESS_EXIT.name] as? Boolean ?: false + val letterSpacing = data[LETTER_SPACING.name] as? Int + ?: 0 + return MainState( language = language, theme = theme.toTheme(), @@ -192,7 +196,8 @@ data class MainState( browseSortOrderDescending = browseSortOrderDescending, browseIncludedFilterItems = browseIncludedFilterItems, textAlignment = textAlignment.toTextAlignment(), - doublePressExit = doublePressExit + doublePressExit = doublePressExit, + letterSpacing = letterSpacing, ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt index b48da7d9..1b8da273 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/data/MainViewModel.kt @@ -359,6 +359,20 @@ class MainViewModel @Inject constructor( } } } + + is MainEvent.OnChangeLetterSpacing -> { + viewModelScope.launch(Dispatchers.IO) { + setDatastore.execute( + DataStoreConstants.LETTER_SPACING, + event.spacing + ) + updateStateWithSavedHandle { + it.copy( + letterSpacing = event.spacing + ) + } + } + } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt index 24baabee..b7e227ef 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/ReaderScreen.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat @@ -209,10 +210,15 @@ private fun ReaderScreen( settingsState.value.selectedColorPreset.fontColor, label = "" ) - val lineHeight = - remember(mainState.value.fontSize, mainState.value.lineHeight) { - (mainState.value.fontSize!! + mainState.value.lineHeight!!).sp - } + val lineHeight = remember( + mainState.value.fontSize, + mainState.value.lineHeight + ) { + (mainState.value.fontSize!! + mainState.value.lineHeight!!).sp + } + val letterSpacing = remember(mainState.value.letterSpacing) { + (mainState.value.letterSpacing!! / 100f).em + } val sidePadding = remember(mainState.value.sidePadding) { (mainState.value.sidePadding!! * 3).dp } @@ -407,6 +413,7 @@ private fun ReaderScreen( fontStyle = fontStyle, textAlignment = mainState.value.textAlignment!!, fontSize = mainState.value.fontSize!!.sp, + letterSpacing = letterSpacing, sidePadding = sidePadding, paragraphIndentation = mainState.value.paragraphIndentation!!, doubleClickTranslationEnabled = mainState.value.doubleClickTranslation!!, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderTextParagraph.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderTextParagraph.kt index e8b01632..08d85bb1 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderTextParagraph.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/reader/components/ReaderTextParagraph.kt @@ -38,6 +38,7 @@ import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data. * @param fontStyle Line's font style. * @param textAlignment Line's text alignment. * @param fontSize Line's font size. + * @param letterSpacing Letter spacing. * @param sidePadding Line's side padding. * @param paragraphIndentation Whether Paragraph Indentation is enabled for this line. * @param doubleClickTranslationEnabled Whether Double Click Translation is enabled. @@ -55,6 +56,7 @@ fun LazyItemScope.ReaderTextParagraph( fontStyle: FontStyle, textAlignment: ReaderTextAlignment, fontSize: TextUnit, + letterSpacing: TextUnit, sidePadding: Dp, paragraphIndentation: Boolean, doubleClickTranslationEnabled: Boolean, @@ -126,6 +128,7 @@ fun LazyItemScope.ReaderTextParagraph( ReaderTextAlignment.END -> TextAlign.End }, fontStyle = fontStyle, + letterSpacing = letterSpacing, fontSize = fontSize, lineHeight = lineHeight, color = fontColor, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/LetterSpacingSetting.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/LetterSpacingSetting.kt new file mode 100644 index 00000000..5c196bda --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/LetterSpacingSetting.kt @@ -0,0 +1,34 @@ +package ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings + +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import ua.acclorite.book_story.R +import ua.acclorite.book_story.presentation.data.MainEvent +import ua.acclorite.book_story.presentation.data.MainState +import ua.acclorite.book_story.presentation.screens.settings.components.SliderWithTitle + +/** + * Letter Spacing setting. + * Changes Reader's letter spacing. + */ +@Composable +fun LazyItemScope.LetterSpacingSetting( + state: State, + onMainEvent: (MainEvent) -> Unit +) { + SliderWithTitle( + value = state.value.letterSpacing!! to "pt", + modifier = Modifier.animateItem(), + fromValue = -8, + toValue = 16, + title = stringResource(id = R.string.letter_spacing_option), + onValueChange = { + onMainEvent( + MainEvent.OnChangeLetterSpacing(it) + ) + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/FontSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/FontSubcategory.kt index 814d14c8..7dc065a2 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/FontSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/FontSubcategory.kt @@ -22,6 +22,7 @@ import ua.acclorite.book_story.presentation.data.MainState import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.FontFamilySetting import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.FontSizeSetting import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.FontStyleSetting +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.LetterSpacingSetting /** * Font subcategory. @@ -78,6 +79,13 @@ fun LazyListScope.FontSubcategory( ) } + item { + LetterSpacingSetting( + state = state, + onMainEvent = onMainEvent + ) + } + item { Spacer( modifier = Modifier diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 3d34c8e9..1ce1b341 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -238,6 +238,7 @@ Швидка зміна пресета кольорів Проведіть вліво або вправо, щоб змінити пресет кольорів Розташування текста + Відстань між літерами Структура файлів diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6649bbae..15c4d345 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -257,6 +257,7 @@ Fast color preset change Swipe left or right to change color preset Text alignment + Letter spacing Files structure