🚀 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 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")

View file

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

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.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<String>? = 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<String>)?.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()
)
}
}

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.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()
)
}
}
}
}
}

View file

@ -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!!,

View file

@ -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,

View file

@ -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(

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.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,

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="fast_color_preset_change_option">Швидка зміна пресета кольорів</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_grid_size_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_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 -->
<string name="dynamic_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="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="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_grid_size_option">Grid size</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_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 -->
<string name="dynamic_theme">Mercury</string>
<string name="blue_theme">Neptune</string>