diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt index 60c070c7..09f2bdfe 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt @@ -95,7 +95,7 @@ class DocumentParser @Inject constructor( val alt = element.attr("alt").trim().takeIf { it.clearMarkdown().containsVisibleText() - } ?: src.substringBeforeLast(".") + } ?: "Image" element.append("\n[[$src|$alt]]\n") } @@ -113,7 +113,7 @@ class DocumentParser @Inject constructor( } == true } ?: return@forEach - val alt = src.substringBeforeLast(".") + val alt = "Image" element.append("\n[[$src|$alt]]\n") } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainEvent.kt index 9d285601..4a27a637 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainEvent.kt @@ -54,6 +54,7 @@ sealed class MainEvent { data class OnChangeHighlightedReadingThickness(val value: Int) : MainEvent() data class OnChangeChapterTitleAlignment(val value: String) : MainEvent() data class OnChangeImages(val value: Boolean) : MainEvent() + data class OnChangeImagesCaptions(val value: Boolean) : MainEvent() data class OnChangeImagesCornersRoundness(val value: Int) : MainEvent() data class OnChangeImagesAlignment(val value: String) : MainEvent() data class OnChangeImagesWidth(val value: Float) : MainEvent() diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainModel.kt b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainModel.kt index e64dd9aa..35af6acf 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainModel.kt @@ -416,6 +416,14 @@ class MainModel @Inject constructor( } ) + is MainEvent.OnChangeImagesCaptions -> handleDatastoreUpdate( + key = DataStoreData.IMAGES_CAPTIONS, + value = event.value, + updateState = { + it.copy(imagesCaptions = this) + } + ) + is MainEvent.OnChangeImagesCornersRoundness -> handleDatastoreUpdate( key = DataStoreData.IMAGES_CORNERS_ROUNDNESS, value = event.value, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainState.kt b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainState.kt index dbb64279..5bcab089 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/main/MainState.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/main/MainState.kt @@ -97,6 +97,7 @@ data class MainState( val highlightedReadingThickness: Int = provideDefaultValue { 2 }, val chapterTitleAlignment: ReaderTextAlignment = provideDefaultValue { ReaderTextAlignment.JUSTIFY }, val images: Boolean = provideDefaultValue { true }, + val imagesCaptions: Boolean = provideDefaultValue { true }, val imagesCornersRoundness: Int = provideDefaultValue { 8 }, val imagesAlignment: HorizontalAlignment = provideDefaultValue { HorizontalAlignment.START }, val imagesWidth: Float = provideDefaultValue { 0.8f }, @@ -327,6 +328,10 @@ data class MainState( IMAGES ) { images }, + imagesCaptions = provideValue( + IMAGES_CAPTIONS + ) { imagesCaptions }, + imagesCornersRoundness = provideValue( IMAGES_CORNERS_ROUNDNESS ) { imagesCornersRoundness }, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/main/data/DataStoreData.kt b/app/src/main/java/ua/acclorite/book_story/presentation/main/data/DataStoreData.kt index 0db9ceca..7ba2d70b 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/main/data/DataStoreData.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/main/data/DataStoreData.kt @@ -57,6 +57,7 @@ object DataStoreData { val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness") val CHAPTER_TITLE_ALIGNMENT = stringPreferencesKey("chapter_title_alignment") val IMAGES = booleanPreferencesKey("images") + val IMAGES_CAPTIONS = booleanPreferencesKey("images_captions") val IMAGES_CORNERS_ROUNDNESS = intPreferencesKey("images_corners_roundness") val IMAGES_ALIGNMENT = stringPreferencesKey("images_alignment") val IMAGES_WIDTH = doublePreferencesKey("images_width") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScreen.kt index 1082235c..ab5914cb 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScreen.kt @@ -439,6 +439,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable { backgroundColor = backgroundColor.value, fontColor = fontColor.value, images = mainState.value.images, + imagesCaptions = mainState.value.imagesCaptions, imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = mainState.value.imagesAlignment, imagesWidth = imagesWidth, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderContent.kt b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderContent.kt index cd368945..6bf9f108 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderContent.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderContent.kt @@ -72,6 +72,7 @@ fun ReaderContent( backgroundColor: Color, fontColor: Color, images: Boolean, + imagesCaptions: Boolean, imagesCornersRoundness: Dp, imagesAlignment: HorizontalAlignment, imagesWidth: Float, @@ -150,6 +151,7 @@ fun ReaderContent( backgroundColor = backgroundColor, fontColor = fontColor, images = images, + imagesCaptions = imagesCaptions, imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, imagesWidth = imagesWidth, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderLayout.kt b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderLayout.kt index b4622305..e7b88697 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderLayout.kt @@ -71,6 +71,7 @@ fun ReaderLayout( backgroundColor: Color, fontColor: Color, images: Boolean, + imagesCaptions: Boolean, imagesCornersRoundness: Dp, imagesAlignment: HorizontalAlignment, imagesWidth: Float, @@ -187,8 +188,11 @@ fun ReaderLayout( text, key = { index, _ -> index } ) { index, entry -> + val previousEntry = text.getOrNull(index - 1) + when { - !images && entry is ReaderText.Image -> return@itemsIndexed + !images && (entry is ReaderText.Image || previousEntry is ReaderText.Image) -> return@itemsIndexed + !imagesCaptions && previousEntry is ReaderText.Image -> return@itemsIndexed else -> { SpacedItem( index = index, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScaffold.kt b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScaffold.kt index b937d4b0..1791e81c 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScaffold.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScaffold.kt @@ -76,6 +76,7 @@ fun ReaderScaffold( backgroundColor: Color, fontColor: Color, images: Boolean, + imagesCaptions: Boolean, imagesCornersRoundness: Dp, imagesAlignment: HorizontalAlignment, imagesWidth: Float, @@ -180,6 +181,7 @@ fun ReaderScaffold( backgroundColor = backgroundColor, fontColor = fontColor, images = images, + imagesCaptions = imagesCaptions, imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, imagesWidth = imagesWidth, diff --git a/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/ImagesSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/ImagesSubcategory.kt index 69f60e60..f66abb27 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/ImagesSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/ImagesSubcategory.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.ui.settings.components.SettingsSubcategory import ua.acclorite.book_story.ui.settings.reader.images.components.ImagesAlignmentOption +import ua.acclorite.book_story.ui.settings.reader.images.components.ImagesCaptionsOption import ua.acclorite.book_story.ui.settings.reader.images.components.ImagesColorEffectsOption import ua.acclorite.book_story.ui.settings.reader.images.components.ImagesCornersRoundnessOption import ua.acclorite.book_story.ui.settings.reader.images.components.ImagesOption @@ -37,6 +38,10 @@ fun LazyListScope.ImagesSubcategory( ImagesOption() } + item { + ImagesCaptionsOption() + } + item { ImagesColorEffectsOption() } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/components/ImagesCaptionsOption.kt b/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/components/ImagesCaptionsOption.kt new file mode 100644 index 00000000..9b6437bc --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/ui/settings/reader/images/components/ImagesCaptionsOption.kt @@ -0,0 +1,38 @@ +/* + * Book's Story — free and open-source Material You eBook reader. + * Copyright (C) 2024-2025 Acclorite + * SPDX-License-Identifier: GPL-3.0-only + */ + +package ua.acclorite.book_story.ui.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.main.MainEvent +import ua.acclorite.book_story.presentation.main.MainModel +import ua.acclorite.book_story.ui.common.components.settings.SwitchWithTitle +import ua.acclorite.book_story.ui.theme.ExpandingTransition + +@Composable +fun ImagesCaptionsOption() { + val mainModel = hiltViewModel() + val state = mainModel.state.collectAsStateWithLifecycle() + + ExpandingTransition(visible = state.value.images) { + SwitchWithTitle( + selected = state.value.imagesCaptions, + title = stringResource(id = R.string.images_captions_option), + description = stringResource(id = R.string.images_captions_option_desc), + onClick = { + mainModel.onEvent( + MainEvent.OnChangeImagesCaptions( + !state.value.imagesCaptions + ) + ) + } + ) + } +} \ 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 8ace8e79..dc538b5f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -212,7 +212,9 @@ Підсвічувати початок кожного слова Товщина підсвічування Зображення - Показувати зображення разом із написами до них + Показувати зображення + Написи + Показувати написи під зображеннями Округлість кутків Розташування Розмір diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 735d99b4..18644aee 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -236,7 +236,9 @@ Highlight the beginning of each word Highlight thickness Images - Display images along with their captions + Display images + Captions + Display captions under images Corners roundness Alignment Size