diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/components/common/SpacedItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/components/common/SpacedItem.kt new file mode 100644 index 00000000..908b9d39 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/components/common/SpacedItem.kt @@ -0,0 +1,17 @@ +package ua.acclorite.book_story.presentation.core.components.common + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +fun SpacedItem( + index: Int, + spacing: Dp, + content: @Composable () -> Unit +) { + if (index > 0) Spacer(Modifier.height(spacing)) + content() +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt index 8924b849..21a215e9 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt @@ -48,6 +48,7 @@ object DataStoreConstants { val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading") val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness") val CHAPTER_TITLE_ALIGNMENT = stringPreferencesKey("chapter_title_alignment") + val SHOW_IMAGES = booleanPreferencesKey("show_images") // Browse settings val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt index d4eb4a7d..50915d10 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt @@ -55,6 +55,7 @@ fun ReaderContent( bottomBarPadding: Dp, backgroundColor: Color, fontColor: Color, + showImages: Boolean, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -120,6 +121,7 @@ fun ReaderContent( bottomBarPadding = bottomBarPadding, backgroundColor = backgroundColor, fontColor = fontColor, + showImages = showImages, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt index 3fe32731..c3169cb5 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt @@ -2,7 +2,6 @@ package ua.acclorite.book_story.presentation.reader import android.os.Build import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues @@ -10,6 +9,7 @@ import androidx.compose.foundation.layout.displayCutout import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -27,6 +27,7 @@ import ua.acclorite.book_story.domain.reader.ReaderText import ua.acclorite.book_story.domain.reader.ReaderTextAlignment import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar import ua.acclorite.book_story.presentation.core.components.common.SelectionContainer +import ua.acclorite.book_story.presentation.core.components.common.SpacedItem import ua.acclorite.book_story.presentation.core.util.LocalActivity import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.presentation.core.util.showToast @@ -47,6 +48,7 @@ fun ReaderLayout( sidePadding: Dp, backgroundColor: Color, fontColor: Color, + showImages: Boolean, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -139,7 +141,6 @@ fun ReaderLayout( horizontalGestureSensitivity = horizontalGestureSensitivity, isLoading = isLoading ), - verticalArrangement = Arrangement.spacedBy(paragraphHeight), contentPadding = PaddingValues( top = (WindowInsets.displayCutout.asPaddingValues() .calculateTopPadding() + paragraphHeight) @@ -149,30 +150,43 @@ fun ReaderLayout( .coerceAtLeast(18.dp), ) ) { - for (entry in text) { - ReaderLayoutText( - activity = activity, - showMenu = showMenu, - entry = entry, - fontFamily = fontFamily, - fontColor = fontColor, - lineHeight = lineHeight, - fontStyle = fontStyle, - chapterTitleAlignment = chapterTitleAlignment, - textAlignment = textAlignment, - horizontalAlignment = horizontalAlignment, - fontSize = fontSize, - letterSpacing = letterSpacing, - sidePadding = sidePadding, - paragraphIndentation = paragraphIndentation, - fullscreenMode = fullscreenMode, - doubleClickTranslation = doubleClickTranslation, - highlightedReading = highlightedReading, - highlightedReadingThickness = highlightedReadingThickness, - toolbarHidden = toolbarHidden, - openTranslator = openTranslator, - menuVisibility = menuVisibility - ) + itemsIndexed( + text, + key = { index, entry -> index } + ) { index, entry -> + when { + !showImages && entry is ReaderText.Image -> return@itemsIndexed + else -> { + SpacedItem( + index = index, + spacing = paragraphHeight + ) { + ReaderLayoutText( + activity = activity, + showMenu = showMenu, + entry = entry, + fontFamily = fontFamily, + fontColor = fontColor, + lineHeight = lineHeight, + fontStyle = fontStyle, + chapterTitleAlignment = chapterTitleAlignment, + textAlignment = textAlignment, + horizontalAlignment = horizontalAlignment, + fontSize = fontSize, + letterSpacing = letterSpacing, + sidePadding = sidePadding, + paragraphIndentation = paragraphIndentation, + fullscreenMode = fullscreenMode, + doubleClickTranslation = doubleClickTranslation, + highlightedReading = highlightedReading, + highlightedReadingThickness = highlightedReadingThickness, + toolbarHidden = toolbarHidden, + openTranslator = openTranslator, + menuVisibility = menuVisibility + ) + } + } + } } } } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt index 7e07a865..3c90430b 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt @@ -1,9 +1,8 @@ -@file:Suppress("FunctionName") - package ua.acclorite.book_story.presentation.reader import androidx.activity.ComponentActivity -import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontStyle @@ -15,7 +14,8 @@ import ua.acclorite.book_story.domain.reader.ReaderText import ua.acclorite.book_story.domain.reader.ReaderTextAlignment import ua.acclorite.book_story.ui.reader.ReaderEvent -fun LazyListScope.ReaderLayoutText( +@Composable +fun LazyItemScope.ReaderLayoutText( activity: ComponentActivity, showMenu: Boolean, entry: ReaderText, @@ -40,61 +40,53 @@ fun LazyListScope.ReaderLayoutText( ) { when (entry) { is ReaderText.Image -> { - item { - ReaderLayoutTextImage( - entry = entry, - sidePadding = sidePadding - ) - } + ReaderLayoutTextImage( + entry = entry, + sidePadding = sidePadding + ) } is ReaderText.Separator -> { - item { - ReaderLayoutTextSeparator( - sidePadding = sidePadding, - fontColor = fontColor - ) - } + ReaderLayoutTextSeparator( + sidePadding = sidePadding, + fontColor = fontColor + ) } is ReaderText.Chapter -> { - item { - ReaderLayoutTextChapter( - chapter = entry, - chapterTitleAlignment = chapterTitleAlignment, - fontColor = fontColor, - sidePadding = sidePadding, - highlightedReading = highlightedReading, - highlightedReadingThickness = highlightedReadingThickness - ) - } + ReaderLayoutTextChapter( + chapter = entry, + chapterTitleAlignment = chapterTitleAlignment, + fontColor = fontColor, + sidePadding = sidePadding, + highlightedReading = highlightedReading, + highlightedReadingThickness = highlightedReadingThickness + ) } is ReaderText.Text -> { - item { - ReaderLayoutTextParagraph( - paragraph = entry, - activity = activity, - showMenu = showMenu, - fontFamily = fontFamily, - fontColor = fontColor, - lineHeight = lineHeight, - fontStyle = fontStyle, - textAlignment = textAlignment, - horizontalAlignment = horizontalAlignment, - fontSize = fontSize, - letterSpacing = letterSpacing, - sidePadding = sidePadding, - paragraphIndentation = paragraphIndentation, - fullscreenMode = fullscreenMode, - doubleClickTranslation = doubleClickTranslation, - highlightedReading = highlightedReading, - highlightedReadingThickness = highlightedReadingThickness, - toolbarHidden = toolbarHidden, - openTranslator = openTranslator, - menuVisibility = menuVisibility - ) - } + ReaderLayoutTextParagraph( + paragraph = entry, + activity = activity, + showMenu = showMenu, + fontFamily = fontFamily, + fontColor = fontColor, + lineHeight = lineHeight, + fontStyle = fontStyle, + textAlignment = textAlignment, + horizontalAlignment = horizontalAlignment, + fontSize = fontSize, + letterSpacing = letterSpacing, + sidePadding = sidePadding, + paragraphIndentation = paragraphIndentation, + fullscreenMode = fullscreenMode, + doubleClickTranslation = doubleClickTranslation, + highlightedReading = highlightedReading, + highlightedReadingThickness = highlightedReadingThickness, + toolbarHidden = toolbarHidden, + openTranslator = openTranslator, + menuVisibility = menuVisibility + ) } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt index cf725857..270ba979 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt @@ -59,6 +59,7 @@ fun ReaderScaffold( bottomBarPadding: Dp, backgroundColor: Color, fontColor: Color, + showImages: Boolean, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -151,6 +152,7 @@ fun ReaderScaffold( sidePadding = sidePadding, backgroundColor = backgroundColor, fontColor = fontColor, + showImages = showImages, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderSettingsBottomSheet.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderSettingsBottomSheet.kt index d71244c4..fffd4839 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderSettingsBottomSheet.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderSettingsBottomSheet.kt @@ -25,6 +25,7 @@ import ua.acclorite.book_story.presentation.core.util.LocalActivity import ua.acclorite.book_story.presentation.settings.appearance.colors.ColorsSubcategory import ua.acclorite.book_story.presentation.settings.reader.chapters.ChaptersSubcategory import ua.acclorite.book_story.presentation.settings.reader.font.FontSubcategory +import ua.acclorite.book_story.presentation.settings.reader.images.ImagesSubcategory import ua.acclorite.book_story.presentation.settings.reader.misc.MiscSubcategory import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory @@ -121,6 +122,9 @@ fun ReaderSettingsBottomSheet( TextSubcategory( titleColor = { MaterialTheme.colorScheme.onSurface } ) + ImagesSubcategory( + titleColor = { MaterialTheme.colorScheme.onSurface } + ) ChaptersSubcategory( titleColor = { MaterialTheme.colorScheme.onSurface } ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/ReaderSettingsCategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/ReaderSettingsCategory.kt index cd526f00..850af2ba 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/ReaderSettingsCategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/ReaderSettingsCategory.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import ua.acclorite.book_story.presentation.settings.reader.chapters.ChaptersSubcategory import ua.acclorite.book_story.presentation.settings.reader.font.FontSubcategory +import ua.acclorite.book_story.presentation.settings.reader.images.ImagesSubcategory import ua.acclorite.book_story.presentation.settings.reader.misc.MiscSubcategory import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory @@ -25,6 +26,9 @@ fun LazyListScope.ReaderSettingsCategory( TextSubcategory( titleColor = titleColor ) + ImagesSubcategory( + titleColor = titleColor + ) ChaptersSubcategory( titleColor = titleColor ) diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt new file mode 100644 index 00000000..d676e9ef --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt @@ -0,0 +1,30 @@ +@file:Suppress("FunctionName") + +package ua.acclorite.book_story.presentation.settings.reader.images + +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import ua.acclorite.book_story.R +import ua.acclorite.book_story.presentation.settings.components.SettingsSubcategory +import ua.acclorite.book_story.presentation.settings.reader.images.components.ShowImagesOption + +fun LazyListScope.ImagesSubcategory( + titleColor: @Composable () -> Color = { MaterialTheme.colorScheme.primary }, + title: @Composable () -> String = { stringResource(id = R.string.images_reader_settings) }, + showTitle: Boolean = true, + showDivider: Boolean = true, +) { + SettingsSubcategory( + titleColor = titleColor, + title = title, + showTitle = showTitle, + showDivider = showDivider + ) { + item { + ShowImagesOption() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ShowImagesOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ShowImagesOption.kt new file mode 100644 index 00000000..060a3311 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ShowImagesOption.kt @@ -0,0 +1,29 @@ +package ua.acclorite.book_story.presentation.settings.reader.images.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import ua.acclorite.book_story.R +import ua.acclorite.book_story.presentation.core.components.settings.SwitchWithTitle +import ua.acclorite.book_story.ui.main.MainEvent +import ua.acclorite.book_story.ui.main.MainModel + +@Composable +fun ShowImagesOption() { + val mainModel = hiltViewModel() + val state = mainModel.state.collectAsStateWithLifecycle() + + SwitchWithTitle( + selected = state.value.showImages, + title = stringResource(id = R.string.show_images_option), + description = stringResource(id = R.string.show_images_option_desc), + onClick = { + mainModel.onEvent( + MainEvent.OnChangeShowImages( + !state.value.showImages + ) + ) + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt index d1135adf..d071c114 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt @@ -50,4 +50,5 @@ sealed class MainEvent { data class OnChangeHighlightedReading(val value: Boolean) : MainEvent() data class OnChangeHighlightedReadingThickness(val value: Int) : MainEvent() data class OnChangeChapterTitleAlignment(val value: String) : MainEvent() + data class OnChangeShowImages(val value: Boolean) : MainEvent() } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt index eb435773..7db02b7e 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt @@ -422,6 +422,14 @@ class MainModel @Inject constructor( it.copy(chapterTitleAlignment = toTextAlignment()) } ) + + is MainEvent.OnChangeShowImages -> handleDatastoreUpdate( + key = DataStoreConstants.SHOW_IMAGES, + value = event.value, + updateState = { + it.copy(showImages = this) + } + ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt index 03557cc0..79a7451a 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt @@ -93,6 +93,7 @@ data class MainState( val highlightedReading: Boolean = provideDefaultValue { false }, val highlightedReadingThickness: Int = provideDefaultValue { 2 }, val chapterTitleAlignment: ReaderTextAlignment = provideDefaultValue { ReaderTextAlignment.JUSTIFY }, + val showImages: Boolean = provideDefaultValue { true }, // Browse Settings val browseFilesStructure: BrowseFilesStructure = provideDefaultValue { @@ -310,6 +311,10 @@ data class MainState( chapterTitleAlignment = provideValue( CHAPTER_TITLE_ALIGNMENT, convert = { toTextAlignment() } ) { chapterTitleAlignment }, + + showImages = provideValue( + SHOW_IMAGES + ) { showImages }, ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt index b5014df8..e814b612 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt @@ -337,6 +337,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable { bottomBarPadding = bottomBarPadding, backgroundColor = backgroundColor.value, fontColor = fontColor.value, + showImages = mainState.value.showImages, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 86a5bd40..d79c39a7 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -137,6 +137,7 @@ Режим читання Система Розділи + Зображення Налаштування теми Кольори Головні @@ -196,6 +197,8 @@ Підсвічування слів Підсвічувати початок кожного слова Товщина підсвічування + Показувати зображення + Показати зображення разом із написами до них Структура файлів diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce9e2ee0..39385b6d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -190,6 +190,7 @@ Reading mode System Chapters + Images Theme preferences Colors General @@ -251,6 +252,8 @@ Highlight words Highlight the beginning of each word Highlight thickness + Show images + Display images along with their captions Files structure