🚀 Show Images option

* Option to show or hide images in Reader (caption will not be hidden any way)

Part-of: #69
This commit is contained in:
Acclorite 2025-01-08 19:27:14 +02:00
parent b1f7e6176f
commit c3e94931aa
16 changed files with 192 additions and 76 deletions

View file

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

View file

@ -48,6 +48,7 @@ object DataStoreConstants {
val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading") val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading")
val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness") val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness")
val CHAPTER_TITLE_ALIGNMENT = stringPreferencesKey("chapter_title_alignment") val CHAPTER_TITLE_ALIGNMENT = stringPreferencesKey("chapter_title_alignment")
val SHOW_IMAGES = booleanPreferencesKey("show_images")
// Browse settings // Browse settings
val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure")

View file

@ -55,6 +55,7 @@ fun ReaderContent(
bottomBarPadding: Dp, bottomBarPadding: Dp,
backgroundColor: Color, backgroundColor: Color,
fontColor: Color, fontColor: Color,
showImages: Boolean,
fontFamily: FontWithName, fontFamily: FontWithName,
lineHeight: TextUnit, lineHeight: TextUnit,
fontStyle: FontStyle, fontStyle: FontStyle,
@ -120,6 +121,7 @@ fun ReaderContent(
bottomBarPadding = bottomBarPadding, bottomBarPadding = bottomBarPadding,
backgroundColor = backgroundColor, backgroundColor = backgroundColor,
fontColor = fontColor, fontColor = fontColor,
showImages = showImages,
fontFamily = fontFamily, fontFamily = fontFamily,
lineHeight = lineHeight, lineHeight = lineHeight,
fontStyle = fontStyle, fontStyle = fontStyle,

View file

@ -2,7 +2,6 @@ package ua.acclorite.book_story.presentation.reader
import android.os.Build import android.os.Build
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues 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.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.domain.reader.ReaderTextAlignment
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar 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.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.LocalActivity
import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.presentation.core.util.noRippleClickable
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
@ -47,6 +48,7 @@ fun ReaderLayout(
sidePadding: Dp, sidePadding: Dp,
backgroundColor: Color, backgroundColor: Color,
fontColor: Color, fontColor: Color,
showImages: Boolean,
fontFamily: FontWithName, fontFamily: FontWithName,
lineHeight: TextUnit, lineHeight: TextUnit,
fontStyle: FontStyle, fontStyle: FontStyle,
@ -139,7 +141,6 @@ fun ReaderLayout(
horizontalGestureSensitivity = horizontalGestureSensitivity, horizontalGestureSensitivity = horizontalGestureSensitivity,
isLoading = isLoading isLoading = isLoading
), ),
verticalArrangement = Arrangement.spacedBy(paragraphHeight),
contentPadding = PaddingValues( contentPadding = PaddingValues(
top = (WindowInsets.displayCutout.asPaddingValues() top = (WindowInsets.displayCutout.asPaddingValues()
.calculateTopPadding() + paragraphHeight) .calculateTopPadding() + paragraphHeight)
@ -149,7 +150,17 @@ fun ReaderLayout(
.coerceAtLeast(18.dp), .coerceAtLeast(18.dp),
) )
) { ) {
for (entry in text) { itemsIndexed(
text,
key = { index, entry -> index }
) { index, entry ->
when {
!showImages && entry is ReaderText.Image -> return@itemsIndexed
else -> {
SpacedItem(
index = index,
spacing = paragraphHeight
) {
ReaderLayoutText( ReaderLayoutText(
activity = activity, activity = activity,
showMenu = showMenu, showMenu = showMenu,
@ -176,4 +187,7 @@ fun ReaderLayout(
} }
} }
} }
}
}
}
} }

View file

@ -1,9 +1,8 @@
@file:Suppress("FunctionName")
package ua.acclorite.book_story.presentation.reader package ua.acclorite.book_story.presentation.reader
import androidx.activity.ComponentActivity 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.Alignment
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontStyle 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.domain.reader.ReaderTextAlignment
import ua.acclorite.book_story.ui.reader.ReaderEvent import ua.acclorite.book_story.ui.reader.ReaderEvent
fun LazyListScope.ReaderLayoutText( @Composable
fun LazyItemScope.ReaderLayoutText(
activity: ComponentActivity, activity: ComponentActivity,
showMenu: Boolean, showMenu: Boolean,
entry: ReaderText, entry: ReaderText,
@ -40,25 +40,20 @@ fun LazyListScope.ReaderLayoutText(
) { ) {
when (entry) { when (entry) {
is ReaderText.Image -> { is ReaderText.Image -> {
item {
ReaderLayoutTextImage( ReaderLayoutTextImage(
entry = entry, entry = entry,
sidePadding = sidePadding sidePadding = sidePadding
) )
} }
}
is ReaderText.Separator -> { is ReaderText.Separator -> {
item {
ReaderLayoutTextSeparator( ReaderLayoutTextSeparator(
sidePadding = sidePadding, sidePadding = sidePadding,
fontColor = fontColor fontColor = fontColor
) )
} }
}
is ReaderText.Chapter -> { is ReaderText.Chapter -> {
item {
ReaderLayoutTextChapter( ReaderLayoutTextChapter(
chapter = entry, chapter = entry,
chapterTitleAlignment = chapterTitleAlignment, chapterTitleAlignment = chapterTitleAlignment,
@ -68,10 +63,8 @@ fun LazyListScope.ReaderLayoutText(
highlightedReadingThickness = highlightedReadingThickness highlightedReadingThickness = highlightedReadingThickness
) )
} }
}
is ReaderText.Text -> { is ReaderText.Text -> {
item {
ReaderLayoutTextParagraph( ReaderLayoutTextParagraph(
paragraph = entry, paragraph = entry,
activity = activity, activity = activity,
@ -96,5 +89,4 @@ fun LazyListScope.ReaderLayoutText(
) )
} }
} }
}
} }

View file

@ -59,6 +59,7 @@ fun ReaderScaffold(
bottomBarPadding: Dp, bottomBarPadding: Dp,
backgroundColor: Color, backgroundColor: Color,
fontColor: Color, fontColor: Color,
showImages: Boolean,
fontFamily: FontWithName, fontFamily: FontWithName,
lineHeight: TextUnit, lineHeight: TextUnit,
fontStyle: FontStyle, fontStyle: FontStyle,
@ -151,6 +152,7 @@ fun ReaderScaffold(
sidePadding = sidePadding, sidePadding = sidePadding,
backgroundColor = backgroundColor, backgroundColor = backgroundColor,
fontColor = fontColor, fontColor = fontColor,
showImages = showImages,
fontFamily = fontFamily, fontFamily = fontFamily,
lineHeight = lineHeight, lineHeight = lineHeight,
fontStyle = fontStyle, fontStyle = fontStyle,

View file

@ -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.appearance.colors.ColorsSubcategory
import ua.acclorite.book_story.presentation.settings.reader.chapters.ChaptersSubcategory 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.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.misc.MiscSubcategory
import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory
@ -121,6 +122,9 @@ fun ReaderSettingsBottomSheet(
TextSubcategory( TextSubcategory(
titleColor = { MaterialTheme.colorScheme.onSurface } titleColor = { MaterialTheme.colorScheme.onSurface }
) )
ImagesSubcategory(
titleColor = { MaterialTheme.colorScheme.onSurface }
)
ChaptersSubcategory( ChaptersSubcategory(
titleColor = { MaterialTheme.colorScheme.onSurface } titleColor = { MaterialTheme.colorScheme.onSurface }
) )

View file

@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import ua.acclorite.book_story.presentation.settings.reader.chapters.ChaptersSubcategory 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.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.misc.MiscSubcategory
import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory import ua.acclorite.book_story.presentation.settings.reader.padding.PaddingSubcategory
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory import ua.acclorite.book_story.presentation.settings.reader.reading_mode.ReadingModeSubcategory
@ -25,6 +26,9 @@ fun LazyListScope.ReaderSettingsCategory(
TextSubcategory( TextSubcategory(
titleColor = titleColor titleColor = titleColor
) )
ImagesSubcategory(
titleColor = titleColor
)
ChaptersSubcategory( ChaptersSubcategory(
titleColor = titleColor titleColor = titleColor
) )

View file

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

View file

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

View file

@ -50,4 +50,5 @@ sealed class MainEvent {
data class OnChangeHighlightedReading(val value: Boolean) : MainEvent() data class OnChangeHighlightedReading(val value: Boolean) : MainEvent()
data class OnChangeHighlightedReadingThickness(val value: Int) : MainEvent() data class OnChangeHighlightedReadingThickness(val value: Int) : MainEvent()
data class OnChangeChapterTitleAlignment(val value: String) : MainEvent() data class OnChangeChapterTitleAlignment(val value: String) : MainEvent()
data class OnChangeShowImages(val value: Boolean) : MainEvent()
} }

View file

@ -422,6 +422,14 @@ class MainModel @Inject constructor(
it.copy(chapterTitleAlignment = toTextAlignment()) it.copy(chapterTitleAlignment = toTextAlignment())
} }
) )
is MainEvent.OnChangeShowImages -> handleDatastoreUpdate(
key = DataStoreConstants.SHOW_IMAGES,
value = event.value,
updateState = {
it.copy(showImages = this)
}
)
} }
} }

View file

@ -93,6 +93,7 @@ data class MainState(
val highlightedReading: Boolean = provideDefaultValue { false }, val highlightedReading: Boolean = provideDefaultValue { false },
val highlightedReadingThickness: Int = provideDefaultValue { 2 }, val highlightedReadingThickness: Int = provideDefaultValue { 2 },
val chapterTitleAlignment: ReaderTextAlignment = provideDefaultValue { ReaderTextAlignment.JUSTIFY }, val chapterTitleAlignment: ReaderTextAlignment = provideDefaultValue { ReaderTextAlignment.JUSTIFY },
val showImages: Boolean = provideDefaultValue { true },
// Browse Settings // Browse Settings
val browseFilesStructure: BrowseFilesStructure = provideDefaultValue { val browseFilesStructure: BrowseFilesStructure = provideDefaultValue {
@ -310,6 +311,10 @@ data class MainState(
chapterTitleAlignment = provideValue( chapterTitleAlignment = provideValue(
CHAPTER_TITLE_ALIGNMENT, convert = { toTextAlignment() } CHAPTER_TITLE_ALIGNMENT, convert = { toTextAlignment() }
) { chapterTitleAlignment }, ) { chapterTitleAlignment },
showImages = provideValue(
SHOW_IMAGES
) { showImages },
) )
} }
} }

View file

@ -337,6 +337,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable {
bottomBarPadding = bottomBarPadding, bottomBarPadding = bottomBarPadding,
backgroundColor = backgroundColor.value, backgroundColor = backgroundColor.value,
fontColor = fontColor.value, fontColor = fontColor.value,
showImages = mainState.value.showImages,
fontFamily = fontFamily, fontFamily = fontFamily,
lineHeight = lineHeight, lineHeight = lineHeight,
fontStyle = fontStyle, fontStyle = fontStyle,

View file

@ -137,6 +137,7 @@
<string name="reading_mode_reader_settings">Режим читання</string> <string name="reading_mode_reader_settings">Режим читання</string>
<string name="system_reader_settings">Система</string> <string name="system_reader_settings">Система</string>
<string name="chapters_reader_settings">Розділи</string> <string name="chapters_reader_settings">Розділи</string>
<string name="images_reader_settings">Зображення</string>
<string name="theme_appearance_settings">Налаштування теми</string> <string name="theme_appearance_settings">Налаштування теми</string>
<string name="colors_appearance_settings">Кольори</string> <string name="colors_appearance_settings">Кольори</string>
<string name="general_browse_settings">Головні</string> <string name="general_browse_settings">Головні</string>
@ -196,6 +197,8 @@
<string name="highlighted_reading_option">Підсвічування слів</string> <string name="highlighted_reading_option">Підсвічування слів</string>
<string name="highlighted_reading_option_desc">Підсвічувати початок кожного слова</string> <string name="highlighted_reading_option_desc">Підсвічувати початок кожного слова</string>
<string name="highlighted_reading_thickness_option">Товщина підсвічування</string> <string name="highlighted_reading_thickness_option">Товщина підсвічування</string>
<string name="show_images_option">Показувати зображення</string>
<string name="show_images_option_desc">Показати зображення разом із написами до них</string>
<!-- Browse --> <!-- Browse -->
<string name="browse_files_structure_option">Структура файлів</string> <string name="browse_files_structure_option">Структура файлів</string>

View file

@ -190,6 +190,7 @@
<string name="reading_mode_reader_settings">Reading mode</string> <string name="reading_mode_reader_settings">Reading mode</string>
<string name="system_reader_settings">System</string> <string name="system_reader_settings">System</string>
<string name="chapters_reader_settings">Chapters</string> <string name="chapters_reader_settings">Chapters</string>
<string name="images_reader_settings">Images</string>
<string name="theme_appearance_settings">Theme preferences</string> <string name="theme_appearance_settings">Theme preferences</string>
<string name="colors_appearance_settings">Colors</string> <string name="colors_appearance_settings">Colors</string>
<string name="general_browse_settings">General</string> <string name="general_browse_settings">General</string>
@ -251,6 +252,8 @@
<string name="highlighted_reading_option">Highlight words</string> <string name="highlighted_reading_option">Highlight words</string>
<string name="highlighted_reading_option_desc">Highlight the beginning of each word</string> <string name="highlighted_reading_option_desc">Highlight the beginning of each word</string>
<string name="highlighted_reading_thickness_option">Highlight thickness</string> <string name="highlighted_reading_thickness_option">Highlight thickness</string>
<string name="show_images_option">Show images</string>
<string name="show_images_option_desc">Display images along with their captions</string>
<!-- Browse --> <!-- Browse -->
<string name="browse_files_structure_option">Files structure</string> <string name="browse_files_structure_option">Files structure</string>