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 348d3ae6..27dc86d3 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 @@ -25,6 +25,7 @@ object DataStoreConstants { val LINE_HEIGHT = intPreferencesKey("line_height") val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height") val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation") + val TEXT_ALIGNMENT = stringPreferencesKey("text_alignment") // 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 6388907c..e7b22175 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 @@ -28,4 +28,5 @@ sealed class MainEvent { data class OnChangeBrowseSortOrder(val order: String) : MainEvent() data class OnChangeBrowseSortOrderDescending(val bool: Boolean) : MainEvent() data class OnChangeBrowseIncludedFilterItem(val item: String) : MainEvent() + data class OnChangeTextAlignment(val alignment: String) : 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 235c946b..83f19e73 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 @@ -15,6 +15,8 @@ import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data. import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseLayout import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toFilesStructure +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.ReaderTextAlignment +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.toTextAlignment import ua.acclorite.book_story.presentation.ui.DarkTheme import ua.acclorite.book_story.presentation.ui.PureDark import ua.acclorite.book_story.presentation.ui.Theme @@ -58,6 +60,7 @@ data class MainState( val browseSortOrder: BrowseSortOrder? = null, val browseSortOrderDescending: Boolean? = null, val browseIncludedFilterItems: List? = null, + val textAlignment: ReaderTextAlignment? = null, ) : Parcelable { companion object { /** @@ -147,11 +150,13 @@ data class MainState( data[BROWSE_SORT_ORDER_DESCENDING.name] as? Boolean ?: true - val browseIncludedFilterItems = (data[BROWSE_INCLUDED_FILTER_ITEMS.name] as? Set)?.toList() ?: emptyList() + val textAlignment = data[TEXT_ALIGNMENT.name] as? String + ?: ReaderTextAlignment.START.name + return MainState( language = language, theme = theme.toTheme(), @@ -176,7 +181,8 @@ data class MainState( browsePinFavoriteDirectories = browsePinFavoriteDirectories, browseSortOrder = browseSortOrder.toBrowseSortOrder(), browseSortOrderDescending = browseSortOrderDescending, - browseIncludedFilterItems = browseIncludedFilterItems + browseIncludedFilterItems = browseIncludedFilterItems, + textAlignment = textAlignment.toTextAlignment() ) } } 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 a631d026..63b7077b 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 @@ -23,6 +23,7 @@ import ua.acclorite.book_story.presentation.screens.settings.data.SettingsViewMo import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseLayout import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toFilesStructure +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.toTextAlignment import ua.acclorite.book_story.presentation.ui.toDarkTheme import ua.acclorite.book_story.presentation.ui.toPureDark import ua.acclorite.book_story.presentation.ui.toTheme @@ -330,6 +331,20 @@ class MainViewModel @Inject constructor( } } } + + is MainEvent.OnChangeTextAlignment -> { + viewModelScope.launch(Dispatchers.IO) { + setDatastore.execute( + DataStoreConstants.TEXT_ALIGNMENT, + event.alignment + ) + updateStateWithSavedHandle { + it.copy( + textAlignment = event.alignment.toTextAlignment() + ) + } + } + } } } 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 9c3c0a53..22661fd1 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 @@ -397,6 +397,7 @@ private fun ReaderScreen( fontColor = fontColor.value, lineHeight = lineHeight, fontStyle = fontStyle, + textAlignment = mainState.value.textAlignment!!, fontSize = mainState.value.fontSize!!.sp, sidePadding = sidePadding, paragraphIndentation = mainState.value.paragraphIndentation!!, 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 d05fb875..e8b01632 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 @@ -12,17 +12,20 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.text.BasicText import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.LineBreak +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import ua.acclorite.book_story.R import ua.acclorite.book_story.domain.model.FontWithName import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.ReaderTextAlignment /** * Reader Text Paragraph item. @@ -33,6 +36,7 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent * @param fontColor Line's font color. * @param lineHeight Line's line height. * @param fontStyle Line's font style. + * @param textAlignment Line's text alignment. * @param fontSize Line's font size. * @param sidePadding Line's side padding. * @param paragraphIndentation Whether Paragraph Indentation is enabled for this line. @@ -49,6 +53,7 @@ fun LazyItemScope.ReaderTextParagraph( fontColor: Color, lineHeight: TextUnit, fontStyle: FontStyle, + textAlignment: ReaderTextAlignment, fontSize: TextUnit, sidePadding: Dp, paragraphIndentation: Boolean, @@ -63,7 +68,12 @@ fun LazyItemScope.ReaderTextParagraph( .padding( horizontal = sidePadding ), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, + horizontalAlignment = when (textAlignment) { + ReaderTextAlignment.START, ReaderTextAlignment.JUSTIFY -> Alignment.Start + ReaderTextAlignment.CENTER -> Alignment.CenterHorizontally + ReaderTextAlignment.END -> Alignment.End + } ) { BasicText( text = buildAnnotatedString { @@ -109,6 +119,12 @@ fun LazyItemScope.ReaderTextParagraph( ), style = TextStyle( fontFamily = fontFamily.font, + textAlign = when (textAlignment) { + ReaderTextAlignment.START -> TextAlign.Start + ReaderTextAlignment.JUSTIFY -> TextAlign.Justify + ReaderTextAlignment.CENTER -> TextAlign.Center + ReaderTextAlignment.END -> TextAlign.End + }, fontStyle = fontStyle, fontSize = fontSize, lineHeight = lineHeight, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/browse/components/settings/BrowseFilesStructureSetting.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/browse/components/settings/BrowseFilesStructureSetting.kt index 26c20bdc..4de8e8bc 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/browse/components/settings/BrowseFilesStructureSetting.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/browse/components/settings/BrowseFilesStructureSetting.kt @@ -23,7 +23,7 @@ fun LazyItemScope.BrowseFilesStructureSetting( onMainEvent: (MainEvent) -> Unit ) { SegmentedButtonWithTitle( - title = stringResource(id = R.string.files_structure_option), + title = stringResource(id = R.string.browse_files_structure_option), modifier = Modifier.animateItem(), buttons = BrowseFilesStructure.entries.map { ButtonItem( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/TextAlignmentSetting.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/TextAlignmentSetting.kt new file mode 100644 index 00000000..709592ee --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/settings/TextAlignmentSetting.kt @@ -0,0 +1,49 @@ +package ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings + +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.material3.MaterialTheme +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.domain.model.ButtonItem +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.SegmentedButtonWithTitle +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.ReaderTextAlignment + +/** + * Text Alignment setting. + * Changes Reader's text alignment (Start/Justify/Center/End). + */ +@Composable +fun LazyItemScope.TextAlignmentSetting( + state: State, + onMainEvent: (MainEvent) -> Unit +) { + SegmentedButtonWithTitle( + title = stringResource(id = R.string.text_alignment_option), + modifier = Modifier.animateItem(), + buttons = ReaderTextAlignment.entries.map { + ButtonItem( + id = it.toString(), + title = when (it) { + ReaderTextAlignment.START -> stringResource(id = R.string.text_alignment_start) + ReaderTextAlignment.JUSTIFY -> stringResource(id = R.string.text_alignment_justify) + ReaderTextAlignment.CENTER -> stringResource(id = R.string.text_alignment_center) + ReaderTextAlignment.END -> stringResource(id = R.string.text_alignment_end) + }, + textStyle = MaterialTheme.typography.labelLarge, + selected = it == state.value.textAlignment!! + ) + }, + onClick = { + onMainEvent( + MainEvent.OnChangeTextAlignment( + it.id + ) + ) + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/TextSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/TextSubcategory.kt index 986578a6..de2902ac 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/TextSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/components/subcategories/TextSubcategory.kt @@ -23,6 +23,7 @@ import ua.acclorite.book_story.presentation.screens.settings.nested.reader.compo import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.ParagraphHeightSetting import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.ParagraphIndentationSetting import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.SidePaddingSetting +import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.TextAlignmentSetting /** * Text subcategory. @@ -58,6 +59,13 @@ fun LazyListScope.TextSubcategory( } } + item { + TextAlignmentSetting( + state = state, + onMainEvent = onMainEvent + ) + } + item { SidePaddingSetting( state = state, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/data/ReaderTextAlignment.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/data/ReaderTextAlignment.kt new file mode 100644 index 00000000..5aa06c4e --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/settings/nested/reader/data/ReaderTextAlignment.kt @@ -0,0 +1,9 @@ +package ua.acclorite.book_story.presentation.screens.settings.nested.reader.data + +enum class ReaderTextAlignment { + START, JUSTIFY, CENTER, END +} + +fun String.toTextAlignment(): ReaderTextAlignment { + return ReaderTextAlignment.valueOf(this) +} \ No newline at end of file diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 741992d2..3c2e2ff7 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -232,7 +232,8 @@ Двічі клацніть на абзац, щоб перекласти його Швидка зміна пресета кольорів Проведіть вліво або вправо, щоб змінити пресет кольорів - Структура файлів + Розташування текста + Структура файлів Режим відображення Кількість комірок Закріпити улюблені директорії @@ -284,6 +285,12 @@ Остання зміна Розмір файла + + Старт + Рівномірно + Центр + Кінець + Меркурій Нептун diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5a82c989..2f006da0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -251,7 +251,8 @@ Double click on paragraph to translate it Fast color preset change Swipe left or right to change color preset - Files structure + Text alignment + Files structure Display mode Grid size Pin favorite directories @@ -303,6 +304,12 @@ Last modified File size + + Start + Justify + Center + End + Mercury Neptune