🚀 Add Text Alignment

Added Text Alignment to Reader. Lets user choose how text should align.

Resolves: #28
This commit is contained in:
Acclorite 2024-08-19 15:44:02 +03:00
parent 127d251ee6
commit 1cf5188874
12 changed files with 126 additions and 6 deletions

View file

@ -25,6 +25,7 @@ object DataStoreConstants {
val LINE_HEIGHT = intPreferencesKey("line_height") val LINE_HEIGHT = intPreferencesKey("line_height")
val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height") val PARAGRAPH_HEIGHT = intPreferencesKey("paragraph_height")
val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation") val PARAGRAPH_INDENTATION = booleanPreferencesKey("paragraph_indentation")
val TEXT_ALIGNMENT = stringPreferencesKey("text_alignment")
// Browse settings // Browse settings
val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure")

View file

@ -28,4 +28,5 @@ sealed class MainEvent {
data class OnChangeBrowseSortOrder(val order: String) : MainEvent() data class OnChangeBrowseSortOrder(val order: String) : MainEvent()
data class OnChangeBrowseSortOrderDescending(val bool: Boolean) : MainEvent() data class OnChangeBrowseSortOrderDescending(val bool: Boolean) : MainEvent()
data class OnChangeBrowseIncludedFilterItem(val item: String) : MainEvent() data class OnChangeBrowseIncludedFilterItem(val item: String) : MainEvent()
data class OnChangeTextAlignment(val alignment: String) : MainEvent()
} }

View file

@ -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.toBrowseLayout
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder 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.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.DarkTheme
import ua.acclorite.book_story.presentation.ui.PureDark import ua.acclorite.book_story.presentation.ui.PureDark
import ua.acclorite.book_story.presentation.ui.Theme import ua.acclorite.book_story.presentation.ui.Theme
@ -58,6 +60,7 @@ data class MainState(
val browseSortOrder: BrowseSortOrder? = null, val browseSortOrder: BrowseSortOrder? = null,
val browseSortOrderDescending: Boolean? = null, val browseSortOrderDescending: Boolean? = null,
val browseIncludedFilterItems: List<String>? = null, val browseIncludedFilterItems: List<String>? = null,
val textAlignment: ReaderTextAlignment? = null,
) : Parcelable { ) : Parcelable {
companion object { companion object {
/** /**
@ -147,11 +150,13 @@ data class MainState(
data[BROWSE_SORT_ORDER_DESCENDING.name] as? Boolean data[BROWSE_SORT_ORDER_DESCENDING.name] as? Boolean
?: true ?: true
val browseIncludedFilterItems = val browseIncludedFilterItems =
(data[BROWSE_INCLUDED_FILTER_ITEMS.name] as? Set<String>)?.toList() (data[BROWSE_INCLUDED_FILTER_ITEMS.name] as? Set<String>)?.toList()
?: emptyList() ?: emptyList()
val textAlignment = data[TEXT_ALIGNMENT.name] as? String
?: ReaderTextAlignment.START.name
return MainState( return MainState(
language = language, language = language,
theme = theme.toTheme(), theme = theme.toTheme(),
@ -176,7 +181,8 @@ data class MainState(
browsePinFavoriteDirectories = browsePinFavoriteDirectories, browsePinFavoriteDirectories = browsePinFavoriteDirectories,
browseSortOrder = browseSortOrder.toBrowseSortOrder(), browseSortOrder = browseSortOrder.toBrowseSortOrder(),
browseSortOrderDescending = browseSortOrderDescending, browseSortOrderDescending = browseSortOrderDescending,
browseIncludedFilterItems = browseIncludedFilterItems browseIncludedFilterItems = browseIncludedFilterItems,
textAlignment = textAlignment.toTextAlignment()
) )
} }
} }

View file

@ -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.toBrowseLayout
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder 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.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.toDarkTheme
import ua.acclorite.book_story.presentation.ui.toPureDark import ua.acclorite.book_story.presentation.ui.toPureDark
import ua.acclorite.book_story.presentation.ui.toTheme 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()
)
}
}
}
} }
} }

View file

@ -397,6 +397,7 @@ private fun ReaderScreen(
fontColor = fontColor.value, fontColor = fontColor.value,
lineHeight = lineHeight, lineHeight = lineHeight,
fontStyle = fontStyle, fontStyle = fontStyle,
textAlignment = mainState.value.textAlignment!!,
fontSize = mainState.value.fontSize!!.sp, fontSize = mainState.value.fontSize!!.sp,
sidePadding = sidePadding, sidePadding = sidePadding,
paragraphIndentation = mainState.value.paragraphIndentation!!, paragraphIndentation = mainState.value.paragraphIndentation!!,

View file

@ -12,17 +12,20 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.text.BasicText import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.LineBreak 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.Dp
import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnit
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.model.FontWithName 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.reader.data.ReaderEvent
import ua.acclorite.book_story.presentation.screens.settings.nested.reader.data.ReaderTextAlignment
/** /**
* Reader Text Paragraph item. * 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 fontColor Line's font color.
* @param lineHeight Line's line height. * @param lineHeight Line's line height.
* @param fontStyle Line's font style. * @param fontStyle Line's font style.
* @param textAlignment Line's text alignment.
* @param fontSize Line's font size. * @param fontSize Line's font size.
* @param sidePadding Line's side padding. * @param sidePadding Line's side padding.
* @param paragraphIndentation Whether Paragraph Indentation is enabled for this line. * @param paragraphIndentation Whether Paragraph Indentation is enabled for this line.
@ -49,6 +53,7 @@ fun LazyItemScope.ReaderTextParagraph(
fontColor: Color, fontColor: Color,
lineHeight: TextUnit, lineHeight: TextUnit,
fontStyle: FontStyle, fontStyle: FontStyle,
textAlignment: ReaderTextAlignment,
fontSize: TextUnit, fontSize: TextUnit,
sidePadding: Dp, sidePadding: Dp,
paragraphIndentation: Boolean, paragraphIndentation: Boolean,
@ -63,7 +68,12 @@ fun LazyItemScope.ReaderTextParagraph(
.padding( .padding(
horizontal = sidePadding 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( BasicText(
text = buildAnnotatedString { text = buildAnnotatedString {
@ -109,6 +119,12 @@ fun LazyItemScope.ReaderTextParagraph(
), ),
style = TextStyle( style = TextStyle(
fontFamily = fontFamily.font, fontFamily = fontFamily.font,
textAlign = when (textAlignment) {
ReaderTextAlignment.START -> TextAlign.Start
ReaderTextAlignment.JUSTIFY -> TextAlign.Justify
ReaderTextAlignment.CENTER -> TextAlign.Center
ReaderTextAlignment.END -> TextAlign.End
},
fontStyle = fontStyle, fontStyle = fontStyle,
fontSize = fontSize, fontSize = fontSize,
lineHeight = lineHeight, lineHeight = lineHeight,

View file

@ -23,7 +23,7 @@ fun LazyItemScope.BrowseFilesStructureSetting(
onMainEvent: (MainEvent) -> Unit onMainEvent: (MainEvent) -> Unit
) { ) {
SegmentedButtonWithTitle( SegmentedButtonWithTitle(
title = stringResource(id = R.string.files_structure_option), title = stringResource(id = R.string.browse_files_structure_option),
modifier = Modifier.animateItem(), modifier = Modifier.animateItem(),
buttons = BrowseFilesStructure.entries.map { buttons = BrowseFilesStructure.entries.map {
ButtonItem( ButtonItem(

View file

@ -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<MainState>,
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
)
)
}
)
}

View file

@ -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.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.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.SidePaddingSetting
import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.settings.TextAlignmentSetting
/** /**
* Text subcategory. * Text subcategory.
@ -58,6 +59,13 @@ fun LazyListScope.TextSubcategory(
} }
} }
item {
TextAlignmentSetting(
state = state,
onMainEvent = onMainEvent
)
}
item { item {
SidePaddingSetting( SidePaddingSetting(
state = state, state = state,

View file

@ -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)
}

View file

@ -232,7 +232,8 @@
<string name="double_click_translation_option_desc">Двічі клацніть на абзац, щоб перекласти його</string> <string name="double_click_translation_option_desc">Двічі клацніть на абзац, щоб перекласти його</string>
<string name="fast_color_preset_change_option">Швидка зміна пресета кольорів</string> <string name="fast_color_preset_change_option">Швидка зміна пресета кольорів</string>
<string name="fast_color_preset_change_option_desc">Проведіть вліво або вправо, щоб змінити пресет кольорів</string> <string name="fast_color_preset_change_option_desc">Проведіть вліво або вправо, щоб змінити пресет кольорів</string>
<string name="files_structure_option">Структура файлів</string> <string name="text_alignment_option">Розташування текста</string>
<string name="browse_files_structure_option">Структура файлів</string>
<string name="browse_layout_option">Режим відображення</string> <string name="browse_layout_option">Режим відображення</string>
<string name="browse_grid_size_option">Кількість комірок</string> <string name="browse_grid_size_option">Кількість комірок</string>
<string name="browse_pin_favorite_directories_option">Закріпити улюблені директорії</string> <string name="browse_pin_favorite_directories_option">Закріпити улюблені директорії</string>
@ -284,6 +285,12 @@
<string name="browse_sort_order_last_modified">Остання зміна</string> <string name="browse_sort_order_last_modified">Остання зміна</string>
<string name="browse_sort_order_file_size">Розмір файла</string> <string name="browse_sort_order_file_size">Розмір файла</string>
<!-- Text Alignment properties -->
<string name="text_alignment_start">Старт</string>
<string name="text_alignment_justify">Рівномірно</string>
<string name="text_alignment_center">Центр</string>
<string name="text_alignment_end">Кінець</string>
<!-- Themes --> <!-- Themes -->
<string name="dynamic_theme">Меркурій</string> <string name="dynamic_theme">Меркурій</string>
<string name="blue_theme">Нептун</string> <string name="blue_theme">Нептун</string>

View file

@ -251,7 +251,8 @@
<string name="double_click_translation_option_desc">Double click on paragraph to translate it</string> <string name="double_click_translation_option_desc">Double click on paragraph to translate it</string>
<string name="fast_color_preset_change_option">Fast color preset change</string> <string name="fast_color_preset_change_option">Fast color preset change</string>
<string name="fast_color_preset_change_option_desc">Swipe left or right to change color preset</string> <string name="fast_color_preset_change_option_desc">Swipe left or right to change color preset</string>
<string name="files_structure_option">Files structure</string> <string name="text_alignment_option">Text alignment</string>
<string name="browse_files_structure_option">Files structure</string>
<string name="browse_layout_option">Display mode</string> <string name="browse_layout_option">Display mode</string>
<string name="browse_grid_size_option">Grid size</string> <string name="browse_grid_size_option">Grid size</string>
<string name="browse_pin_favorite_directories_option">Pin favorite directories</string> <string name="browse_pin_favorite_directories_option">Pin favorite directories</string>
@ -303,6 +304,12 @@
<string name="browse_sort_order_last_modified">Last modified</string> <string name="browse_sort_order_last_modified">Last modified</string>
<string name="browse_sort_order_file_size">File size</string> <string name="browse_sort_order_file_size">File size</string>
<!-- Text Alignment properties -->
<string name="text_alignment_start">Start</string>
<string name="text_alignment_justify">Justify</string>
<string name="text_alignment_center">Center</string>
<string name="text_alignment_end">End</string>
<!-- Themes --> <!-- Themes -->
<string name="dynamic_theme">Mercury</string> <string name="dynamic_theme">Mercury</string>
<string name="blue_theme">Neptune</string> <string name="blue_theme">Neptune</string>