HelpScreen: Moved HelpTips to Constants.HELP_TIPS + Added "How do I use double click translation?", "How do I create and modify color presets?", "How do I use color presets?".

This commit is contained in:
acclorite 2024-07-28 23:55:55 +03:00
parent 96d0d1e3f6
commit 0544e74636
23 changed files with 598 additions and 911 deletions

View file

@ -0,0 +1,16 @@
package ua.acclorite.book_story.domain.model
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.text.AnnotatedString
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
@Immutable
data class HelpTip(
@StringRes val title: Int,
val description: @Composable AnnotatedString.Builder.(onNavigate: OnNavigate, fromStart: Boolean) -> Unit,
val customContent: @Composable ColumnScope.(onHelpEvent: (HelpEvent) -> Unit) -> Unit = {},
)

View file

@ -3,6 +3,7 @@ package ua.acclorite.book_story.domain.util
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Person
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
@ -14,8 +15,11 @@ import ua.acclorite.book_story.domain.model.Category
import ua.acclorite.book_story.domain.model.ColorPreset import ua.acclorite.book_story.domain.model.ColorPreset
import ua.acclorite.book_story.domain.model.Credit import ua.acclorite.book_story.domain.model.Credit
import ua.acclorite.book_story.domain.model.FontWithName import ua.acclorite.book_story.domain.model.FontWithName
import ua.acclorite.book_story.domain.model.HelpTip
import ua.acclorite.book_story.domain.model.NavigationItem import ua.acclorite.book_story.domain.model.NavigationItem
import ua.acclorite.book_story.presentation.data.Screen import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.content.HelpFindBooksContent
import ua.acclorite.book_story.presentation.ui.Theme import ua.acclorite.book_story.presentation.ui.Theme
object Constants { object Constants {
@ -115,6 +119,236 @@ object Constants {
), ),
) )
// Help Tips
val HELP_TIPS = listOf(
HelpTip(
title = R.string.help_title_how_to_find_books,
description = { _, _ ->
append(stringResource(id = R.string.help_desc_how_to_find_books))
},
customContent = { onHelpEvent ->
HelpFindBooksContent(onEvent = onHelpEvent)
}
),
HelpTip(
title = R.string.help_title_how_to_add_books,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_add_books_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Browse, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_add_books_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_add_books_3) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_add_books_4))
}
append(".")
}
),
HelpTip(
title = R.string.help_title_how_to_customize_app,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_customize_app_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Settings, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_customize_app_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_customize_app_3))
}
),
HelpTip(
title = R.string.help_title_how_to_move_or_delete_books,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_3))
}
),
HelpTip(
title = R.string.help_title_how_to_edit_book,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_edit_book_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_edit_book_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_edit_book_3))
}
),
HelpTip(
title = R.string.help_title_how_to_read_book,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_read_book_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_read_book_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_read_book_3))
}
),
HelpTip(
title = R.string.help_title_how_to_customize_reader,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_customize_reader_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Settings, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_customize_reader_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_customize_reader_3))
}
),
HelpTip(
title = R.string.help_title_how_to_update_book,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_update_book_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_update_book_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_update_book_3))
}
),
HelpTip(
title = R.string.help_title_how_to_manage_history,
description = { onNavigate, fromStart ->
append(stringResource(id = R.string.help_desc_how_to_manage_history_1) + " ")
HelpAnnotation(
onClick = {
if (!fromStart) {
onNavigate {
navigate(Screen.History, useBackAnimation = true)
}
}
}
) {
append(stringResource(id = R.string.help_desc_how_to_manage_history_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_manage_history_3))
}
),
HelpTip(
title = R.string.help_title_how_to_use_tooltip,
description = { _, _ ->
append(stringResource(id = R.string.help_desc_how_to_use_tooltip_1))
}
),
HelpTip(
title = R.string.help_title_how_to_use_double_click_translation,
description = { _, _ ->
append(stringResource(id = R.string.help_desc_how_to_use_double_click_translation_1))
}
),
HelpTip(
title = R.string.help_title_how_to_create_color_presets,
description = { _, _ ->
append(stringResource(id = R.string.help_desc_how_to_create_color_presets_1))
}
),
HelpTip(
title = R.string.help_title_how_to_use_color_presets,
description = { _, _ ->
append(stringResource(id = R.string.help_desc_how_to_use_color_presets_1))
}
),
)
// About Badges // About Badges
val ABOUT_BADGES = listOf( val ABOUT_BADGES = listOf(
Badge( Badge(

View file

@ -33,27 +33,20 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.Constants
import ua.acclorite.book_story.domain.util.OnNavigate import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomIconButton import ua.acclorite.book_story.presentation.components.CustomIconButton
import ua.acclorite.book_story.presentation.components.GoBackButton import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.components.customItems
import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.data.LocalNavigator
import ua.acclorite.book_story.presentation.data.MainEvent import ua.acclorite.book_story.presentation.data.MainEvent
import ua.acclorite.book_story.presentation.data.MainViewModel import ua.acclorite.book_story.presentation.data.MainViewModel
import ua.acclorite.book_story.presentation.data.Screen import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpAddBooksItem import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpClickMeNoteItem import ua.acclorite.book_story.presentation.screens.help.components.items.HelpClickMeNoteItem
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpCustomizeApp
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpCustomizeReader
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpEditBook
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpFindBooksItem
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpManageHistory
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpMoveOrDeleteBooks
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpReadBook
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpUpdateBook
import ua.acclorite.book_story.presentation.screens.help.components.items.HelpUseTooltips
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState import ua.acclorite.book_story.presentation.screens.help.data.HelpState
import ua.acclorite.book_story.presentation.screens.help.data.HelpViewModel import ua.acclorite.book_story.presentation.screens.help.data.HelpViewModel
@ -179,10 +172,7 @@ private fun HelpScreen(
} }
item { item {
HelpClickMeNoteItem( HelpClickMeNoteItem()
state = state,
onEvent = onEvent
)
} }
item { item {
@ -193,81 +183,12 @@ private fun HelpScreen(
) )
} }
item { customItems(Constants.HELP_TIPS, key = { it.title }) { helpTip ->
HelpFindBooksItem( HelpItem(
state = state, helpTip = helpTip,
onEvent = onEvent
)
}
item {
HelpAddBooksItem(
state = state,
onNavigate = onNavigate, onNavigate = onNavigate,
onEvent = onEvent fromStart = state.value.fromStart,
) onHelpEvent = onEvent
}
item {
HelpCustomizeApp(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpMoveOrDeleteBooks(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpEditBook(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpReadBook(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpCustomizeReader(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpUpdateBook(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpManageHistory(
state = state,
onNavigate = onNavigate,
onEvent = onEvent
)
}
item {
HelpUseTooltips(
state = state,
onEvent = onEvent
) )
} }

View file

@ -3,19 +3,29 @@ package ua.acclorite.book_story.presentation.screens.help.components
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withLink
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
/** /**
* Help clickable annotation. Mainly used for highlighting screens. * Help clickable annotation.
* Mainly used for highlighting screens.
*
* @param onClick OnClick callback, to, for example navigate to another screen.
* @param block Lambda to append all text to be highlighted.
*/ */
@Composable @Composable
fun AnnotatedString.Builder.HelpAnnotation( fun AnnotatedString.Builder.HelpAnnotation(
tag: String, onClick: () -> Unit,
block: @Composable AnnotatedString.Builder.() -> Unit block: @Composable AnnotatedString.Builder.() -> Unit
) { ) {
pushStringAnnotation(tag = tag, annotation = "") withLink(
LinkAnnotation.Url("", style = null) {
onClick()
}
) {
withStyle( withStyle(
style = SpanStyle( style = SpanStyle(
color = MaterialTheme.colorScheme.tertiary, color = MaterialTheme.colorScheme.tertiary,
@ -24,5 +34,5 @@ fun AnnotatedString.Builder.HelpAnnotation(
) { ) {
block() block()
} }
pop() }
} }

View file

@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
@ -21,16 +23,15 @@ import ua.acclorite.book_story.presentation.components.CustomTooltip
import ua.acclorite.book_story.presentation.ui.SlidingTransition import ua.acclorite.book_story.presentation.ui.SlidingTransition
/** /**
* When clicked returns a Tag from [tags] (if present in [text]) * Help Clickable Note.
* Collapsible simple note to user.
*
* @param text [AnnotatedString].
*/ */
@Composable @Composable
fun LazyItemScope.HelpClickableNote( fun LazyItemScope.HelpClickableNote(text: AnnotatedString) {
text: AnnotatedString, val showNote = rememberSaveable { mutableStateOf(true) }
tags: List<String> = emptyList(),
isNoteFullyShown: Boolean,
onIconClick: () -> Unit,
onTagClick: (String) -> Unit
) {
Column(Modifier.animateItem()) { Column(Modifier.animateItem()) {
CustomTooltip(text = stringResource(R.string.note_content_desc)) { CustomTooltip(text = stringResource(R.string.note_content_desc)) {
Icon( Icon(
@ -38,29 +39,22 @@ fun LazyItemScope.HelpClickableNote(
modifier = Modifier modifier = Modifier
.size(20.dp) .size(20.dp)
.clickable(interactionSource = null, indication = null) { .clickable(interactionSource = null, indication = null) {
onIconClick() showNote.value = !showNote.value
}, },
contentDescription = stringResource(R.string.note_content_desc), contentDescription = stringResource(R.string.note_content_desc),
tint = MaterialTheme.colorScheme.onSurfaceVariant tint = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
SlidingTransition(visible = isNoteFullyShown) { SlidingTransition(visible = showNote.value) {
Column { Column {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
ClickableText( Text(
text = text, text = text,
style = MaterialTheme.typography.bodySmall.copy( style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
) { offset -> )
tags.forEach { tag ->
text.getStringAnnotations(tag = tag, start = offset, end = offset)
.firstOrNull()?.let {
onTagClick(tag)
}
}
}
} }
} }
} }

View file

@ -4,15 +4,14 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropUp import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -20,50 +19,61 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.model.HelpTip
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.ui.SlidingTransition import ua.acclorite.book_story.presentation.ui.SlidingTransition
/** /**
* Help Item. Can be Expanded or Collapsed. * Help Item.
* Can be Expanded or Collapsed.
*
* @param helpTip [HelpTip] to be shown.
* @param onNavigate Navigator callback.
* @param fromStart Whether user came from Start screen.
* @param onHelpEvent [HelpEvent] callback.
*/ */
@Composable @Composable
fun LazyItemScope.HelpItem( fun LazyItemScope.HelpItem(
title: String, helpTip: HelpTip,
description: AnnotatedString, onNavigate: OnNavigate,
customContent: @Composable ColumnScope.() -> Unit = {}, fromStart: Boolean,
tags: List<String>, onHelpEvent: (HelpEvent) -> Unit
shouldShowDescription: Boolean,
onTitleClick: () -> Unit,
onTagClick: (String) -> Unit
) { ) {
val showDescription = rememberSaveable {
mutableStateOf(false)
}
val animatedArrowRotation by animateFloatAsState( val animatedArrowRotation by animateFloatAsState(
targetValue = if (shouldShowDescription) 0f else -180f, targetValue = if (showDescription.value) 0f else -180f,
animationSpec = tween(300), animationSpec = tween(300),
label = stringResource(id = R.string.arrow_anim_content_desc) label = stringResource(id = R.string.arrow_anim_content_desc)
) )
Column(
Column(Modifier.animateItem()) { Modifier
Spacer( .animateItem()
modifier = Modifier.height(8.dp) .fillMaxWidth()
) .padding(vertical = 8.dp)
) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(interactionSource = null, indication = null) { .clickable(interactionSource = null, indication = null) {
onTitleClick() showDescription.value = !showDescription.value
}, },
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Text( Text(
text = title, text = stringResource(id = helpTip.title),
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f)
@ -79,31 +89,28 @@ fun LazyItemScope.HelpItem(
) )
} }
SlidingTransition( SlidingTransition(
visible = shouldShowDescription visible = showDescription.value
) { ) {
Column { Column(Modifier.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
ClickableText( Text(
text = description, text = buildAnnotatedString {
helpTip.description.invoke(
this@buildAnnotatedString,
onNavigate,
fromStart
)
},
style = MaterialTheme.typography.bodyMedium.copy( style = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
) { offset -> )
tags.forEach { tag -> helpTip.customContent.invoke(
description.getStringAnnotations(tag = tag, start = offset, end = offset) this,
.firstOrNull()?.let { onHelpEvent
onTagClick(tag)
}
}
}
customContent()
}
}
Spacer(
modifier = Modifier.height(8.dp)
) )
} }
} }
}
}

View file

@ -0,0 +1,162 @@
package ua.acclorite.book_story.presentation.screens.help.components.content
import android.widget.Toast
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.components.CustomIconButton
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.ui.SlidingTransition
/**
* Help Find Books Content.
* [ua.acclorite.book_story.domain.model.HelpTip]'s custom content.
*/
@Composable
fun HelpFindBooksContent(onEvent: (HelpEvent) -> Unit) {
val context = LocalContext.current
val text = remember { mutableStateOf("") }
val showError = remember { mutableStateOf(false) }
val sites = stringArrayResource(id = R.array.book_sites)
val supportingText = buildAnnotatedString {
append(stringResource(id = R.string.help_field_support) + " ")
sites.forEachIndexed { index, string ->
HelpAnnotation(
onClick = {
onEvent(
HelpEvent.OnNavigateToBrowserPage(
page = string.substringAfterLast("|"),
context = context,
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
) {
append(string.substringBeforeLast("|"))
}
if (index < sites.lastIndex) {
append(", ")
}
}
}
Spacer(modifier = Modifier.height(4.dp))
OutlinedTextField(
value = text.value,
modifier = Modifier
.fillMaxWidth(),
onValueChange = { value ->
text.value = value
showError.value = false
},
label = {
Text(text = stringResource(id = R.string.help_field_placeholder))
},
keyboardActions = KeyboardActions(
onSearch = {
onEvent(
HelpEvent.OnSearchInWeb(
page = text.value,
context = context,
error = {
showError.value = true
},
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
),
keyboardOptions = KeyboardOptions(
KeyboardCapitalization.Words,
imeAction = ImeAction.Search
),
trailingIcon = {
CustomIconButton(
icon = Icons.Default.Search,
contentDescription = R.string.search_content_desc,
disableOnClick = false,
enabled = !showError.value,
color = when (showError.value) {
true -> MaterialTheme.colorScheme.outline
false -> MaterialTheme.colorScheme.primary
},
onClick = {
onEvent(
HelpEvent.OnSearchInWeb(
page = text.value,
context = context,
error = { showError.value = true },
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
)
},
supportingText = {
Column {
Spacer(modifier = Modifier.height(2.dp))
Box {
SlidingTransition(visible = showError.value) {
Text(
text = stringResource(id = R.string.help_field_error),
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall
)
}
SlidingTransition(visible = !showError.value) {
Text(
text = supportingText,
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant
)
)
}
}
}
},
singleLine = true
)
}

View file

@ -1,68 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpAddBooksItem(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_add_books),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_add_books_1) + " ")
HelpAnnotation(tag = "browse") {
append(stringResource(id = R.string.help_desc_how_to_add_books_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_add_books_3) + " ")
HelpAnnotation(tag = "library") {
append(stringResource(id = R.string.help_desc_how_to_add_books_4))
}
append(".")
},
tags = listOf("browse", "library"),
shouldShowDescription = state.value.showHelpItem2,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem2 = !it.showHelpItem2
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"browse" -> {
if (!state.value.fromStart) {
navigate(Screen.Browse, useBackAnimation = true)
}
}
"library" -> {
if (!state.value.fromStart) {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -3,54 +3,38 @@ package ua.acclorite.book_story.presentation.screens.help.components.items
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpClickableNote import ua.acclorite.book_story.presentation.screens.help.components.HelpClickableNote
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
/**
* Help Click Me Note Item.
* Shows an example to user on how to interact with highlighted text.
*/
@Composable @Composable
fun LazyItemScope.HelpClickMeNoteItem( fun LazyItemScope.HelpClickMeNoteItem() {
state: State<HelpState>,
onEvent: (HelpEvent) -> Unit
) {
val context = LocalContext.current val context = LocalContext.current
HelpClickableNote( HelpClickableNote(
text = buildAnnotatedString { text = buildAnnotatedString {
append(stringResource(id = R.string.help_clickable_note_1) + " ") append(stringResource(id = R.string.help_clickable_note_1) + " ")
HelpAnnotation(tag = "note") { HelpAnnotation(
append(stringResource(id = R.string.help_clickable_note_2)) onClick = {
}
append(" " + stringResource(id = R.string.help_clickable_note_3))
},
tags = listOf("note"),
isNoteFullyShown = state.value.showNote1,
onIconClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showNote1 = !it.showNote1
)
}
)
},
onTagClick = { tag ->
when (tag) {
"note" -> {
Toast.makeText( Toast.makeText(
context, context,
context.getString(R.string.help_clickable_note_action), context.getString(R.string.help_clickable_note_action),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
) {
append(stringResource(id = R.string.help_clickable_note_2))
} }
append(" " + stringResource(id = R.string.help_clickable_note_3))
} }
) )
} }

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpCustomizeApp(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_customize_app),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_customize_app_1) + " ")
HelpAnnotation(tag = "settings") {
append(stringResource(id = R.string.help_desc_how_to_customize_app_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_customize_app_3))
},
tags = listOf("settings"),
shouldShowDescription = state.value.showHelpItem3,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem3 = !it.showHelpItem3
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"settings" -> {
if (!state.value.fromStart) {
navigate(Screen.Settings, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpCustomizeReader(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_customize_reader),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_customize_reader_1) + " ")
HelpAnnotation(tag = "settings") {
append(stringResource(id = R.string.help_desc_how_to_customize_reader_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_customize_reader_3))
},
tags = listOf("settings"),
shouldShowDescription = state.value.showHelpItem7,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem7 = !it.showHelpItem7
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"settings" -> {
if (!state.value.fromStart) {
navigate(Screen.Settings, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpEditBook(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_edit_book),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_edit_book_1) + " ")
HelpAnnotation(tag = "library") {
append(stringResource(id = R.string.help_desc_how_to_edit_book_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_edit_book_3))
},
tags = listOf("library"),
shouldShowDescription = state.value.showHelpItem5,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem5 = !it.showHelpItem5
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"library" -> {
if (!state.value.fromStart) {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,189 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import android.widget.Toast
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.components.CustomIconButton
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
import ua.acclorite.book_story.presentation.ui.SlidingTransition
@Composable
fun LazyItemScope.HelpFindBooksItem(
state: State<HelpState>,
onEvent: (HelpEvent) -> Unit
) {
val context = LocalContext.current
val sites = stringArrayResource(id = R.array.book_sites)
val text = buildAnnotatedString {
append(stringResource(id = R.string.help_field_support) + " ")
sites.forEachIndexed { index, string ->
HelpAnnotation(tag = string) {
append(string.substringBeforeLast("|"))
}
if (index < sites.lastIndex) {
append(", ")
}
}
}
HelpItem(
title = stringResource(id = R.string.help_title_how_to_find_books),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_find_books))
},
tags = emptyList(),
shouldShowDescription = state.value.showHelpItem1,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem1 = !it.showHelpItem1
)
}
)
},
customContent = {
Spacer(modifier = Modifier.height(4.dp))
OutlinedTextField(
value = state.value.textFieldValue,
modifier = Modifier
.fillMaxWidth(),
onValueChange = { value ->
onEvent(
HelpEvent.OnUpdateState {
it.copy(
textFieldValue = value,
showError = false
)
}
)
},
label = {
Text(text = stringResource(id = R.string.help_field_placeholder))
},
keyboardActions = KeyboardActions(
onSearch = {
onEvent(
HelpEvent.OnSearchInWeb(
context = context,
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
),
keyboardOptions = KeyboardOptions(
KeyboardCapitalization.Words,
imeAction = ImeAction.Search
),
trailingIcon = {
CustomIconButton(
icon = Icons.Default.Search,
contentDescription = R.string.search_content_desc,
disableOnClick = false,
enabled = !state.value.showError,
color = if (state.value.showError) {
MaterialTheme.colorScheme.outline
} else {
MaterialTheme.colorScheme.primary
}
) {
onEvent(
HelpEvent.OnSearchInWeb(
context = context,
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
},
supportingText = {
Column {
Spacer(modifier = Modifier.height(2.dp))
Box {
SlidingTransition(visible = state.value.showError) {
Text(
text = stringResource(id = R.string.help_field_error),
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall
)
}
SlidingTransition(visible = !state.value.showError) {
ClickableText(
text = text,
style = MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant
)
) { offset ->
sites.forEach { tag ->
text.getStringAnnotations(
tag = tag,
start = offset,
end = offset
).firstOrNull()?.let {
onEvent(
HelpEvent.OnNavigateToBrowserPage(
page = tag.substringAfterLast("|"),
context = context,
noAppsFound = {
Toast.makeText(
context,
context.getString(R.string.error_no_browser),
Toast.LENGTH_SHORT
).show()
}
)
)
}
}
}
}
}
}
},
singleLine = true
)
},
onTagClick = {}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpManageHistory(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_manage_history),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_manage_history_1) + " ")
HelpAnnotation(tag = "history") {
append(stringResource(id = R.string.help_desc_how_to_manage_history_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_manage_history_3))
},
tags = listOf("history"),
shouldShowDescription = state.value.showHelpItem9,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem9 = !it.showHelpItem9
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"history" -> {
if (!state.value.fromStart) {
navigate(Screen.History, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpMoveOrDeleteBooks(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_move_or_delete_books),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_1) + " ")
HelpAnnotation(tag = "library") {
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_move_or_delete_books_3))
},
tags = listOf("library"),
shouldShowDescription = state.value.showHelpItem4,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem4 = !it.showHelpItem4
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"library" -> {
if (!state.value.fromStart) {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpReadBook(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_read_book),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_read_book_1) + " ")
HelpAnnotation(tag = "library") {
append(stringResource(id = R.string.help_desc_how_to_read_book_2))
}
append(". ")
append(stringResource(id = R.string.help_desc_how_to_read_book_3))
},
tags = listOf("library"),
shouldShowDescription = state.value.showHelpItem6,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem6 = !it.showHelpItem6
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"library" -> {
if (!state.value.fromStart) {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,57 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpUpdateBook(
state: State<HelpState>,
onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_update_book),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_update_book_1) + " ")
HelpAnnotation(tag = "library") {
append(stringResource(id = R.string.help_desc_how_to_update_book_2))
}
append(" ")
append(stringResource(id = R.string.help_desc_how_to_update_book_3))
},
tags = listOf("library"),
shouldShowDescription = state.value.showHelpItem8,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem8 = !it.showHelpItem8
)
}
)
},
onTagClick = { tag ->
onNavigate {
when (tag) {
"library" -> {
if (!state.value.fromStart) {
navigate(Screen.Library, useBackAnimation = true)
}
}
}
}
}
)
}

View file

@ -1,36 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.items
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
import ua.acclorite.book_story.presentation.screens.help.data.HelpEvent
import ua.acclorite.book_story.presentation.screens.help.data.HelpState
@Composable
fun LazyItemScope.HelpUseTooltips(
state: State<HelpState>,
onEvent: (HelpEvent) -> Unit
) {
HelpItem(
title = stringResource(id = R.string.help_title_how_to_use_tooltip),
description = buildAnnotatedString {
append(stringResource(id = R.string.help_desc_how_to_use_tooltip_1))
},
tags = emptyList(),
shouldShowDescription = state.value.showHelpItem10,
onTitleClick = {
onEvent(
HelpEvent.OnUpdateState {
it.copy(
showHelpItem10 = !it.showHelpItem10
)
}
)
},
onTagClick = {}
)
}

View file

@ -5,11 +5,10 @@ import androidx.compose.runtime.Immutable
@Immutable @Immutable
sealed class HelpEvent { sealed class HelpEvent {
data class OnUpdateState(val block: (HelpState) -> HelpState) : HelpEvent()
data class OnSearchInWeb( data class OnSearchInWeb(
val page: String,
val context: Context, val context: Context,
val error: () -> Unit,
val noAppsFound: () -> Unit val noAppsFound: () -> Unit
) : HelpEvent() ) : HelpEvent()

View file

@ -4,23 +4,5 @@ import androidx.compose.runtime.Immutable
@Immutable @Immutable
data class HelpState( data class HelpState(
val fromStart: Boolean = false, val fromStart: Boolean = false
val showNote1: Boolean = true,
val showHelpItem1: Boolean = false,
val textFieldValue: String = "",
val showError: Boolean = false,
val showHelpItem2: Boolean = false,
val showHelpItem3: Boolean = false,
val showHelpItem4: Boolean = false,
val showHelpItem5: Boolean = false,
val showHelpItem6: Boolean = false,
val showHelpItem7: Boolean = false,
val showHelpItem8: Boolean = false,
val showHelpItem9: Boolean = false,
val showHelpItem10: Boolean = false,
val showHelpItem11: Boolean = false,
val showHelpItem12: Boolean = false,
) )

View file

@ -40,12 +40,8 @@ class HelpViewModel @Inject constructor(
is HelpEvent.OnSearchInWeb -> { is HelpEvent.OnSearchInWeb -> {
viewModelScope.launch { viewModelScope.launch {
if (_state.value.textFieldValue.isBlank()) { if (event.page.isBlank()) {
_state.update { event.error()
it.copy(
showError = true
)
}
return@launch return@launch
} }
@ -54,7 +50,7 @@ class HelpViewModel @Inject constructor(
intent.action = Intent.ACTION_WEB_SEARCH intent.action = Intent.ACTION_WEB_SEARCH
intent.putExtra( intent.putExtra(
SearchManager.QUERY, SearchManager.QUERY,
"${_state.value.textFieldValue.trim()} filetype:txt OR filetype:pdf" "${event.page.trim()} filetype:txt OR filetype:pdf"
) )
intent.launchActivity(event.context as ComponentActivity) { intent.launchActivity(event.context as ComponentActivity) {
@ -62,12 +58,6 @@ class HelpViewModel @Inject constructor(
} }
} }
} }
is HelpEvent.OnUpdateState -> {
_state.update {
event.block(it)
}
}
} }
} }

View file

@ -341,7 +341,7 @@
<string name="help_desc_how_to_add_books_2">Огляд</string> <string name="help_desc_how_to_add_books_2">Огляд</string>
<string name="help_desc_how_to_add_books_3"> <string name="help_desc_how_to_add_books_3">
Якщо ви не бачите завантажені книги, спробуйте оновити список, потягнувши його вниз. Якщо ви не бачите завантажені книги, спробуйте оновити список, потягнувши його вниз.
Переконайтеся, що ваші книги має підтримуваний формат файлу. Переконайтеся, що ваші книги мають підтримуваний формат файлу.
Потім натисніть на книгу, щоб вибрати її, або утримуйте, щоб показати її місцезнаходження. Потім натисніть на книгу, щоб вибрати її, або утримуйте, щоб показати її місцезнаходження.
Після того, як ви вибрали всі потрібні книги, натисніть на іконку з галочкою у верхньому правому куті, Після того, як ви вибрали всі потрібні книги, натисніть на іконку з галочкою у верхньому правому куті,
зачекайте поки всі книги завантажаться, і натисніть «Додати». зачекайте поки всі книги завантажаться, і натисніть «Додати».
@ -435,6 +435,47 @@
Щоб показати підказку, ви можете затиснути кнопку-іконку. Щоб показати підказку, ви можете затиснути кнопку-іконку.
</string> </string>
<string name="help_title_how_to_use_double_click_translation">
Як використовувати переклад подвійним кліком?
</string>
<string name="help_desc_how_to_use_double_click_translation_1">
Спочатку перейдіть в налаштування Читача(див: Як мені налаштувати Читач?),
потім увімкніть відповідне налаштування. Після цього,
почніть читати книгу(див: Як мені читати книгу?).
Тепер якщо ви двічі клацните на бажаний параграф,
відкриється зовнішній перекладач з текстом параграфу.
</string>
<string name="help_title_how_to_create_color_presets">
Як створити та редагувати пресети кольорів?
</string>
<string name="help_desc_how_to_create_color_presets_1">
Перейдіть в налаштування Зовнішнього Вигляду(див: Як мені налаштувати Читач?).
Ви можете редагувати всі налаштування пресету кольорів
у віконці під «Пресет Кольорів» в підкатегорії «Кольори».
Щоб створити новий пресет кольорів, натисніть на кнопку-іконку «Додати».
Є багато шляхів редагування пресета кольорів:
натиснувши на текстове поле, ви можете змінити назву пресету кольорів;
рухаючи повзунки, ви можете змінити кольори пресета кольорів;
натиснувши на кнопку-іконку «Перетасувати» ви можете перетасувати всі кольори.
Якщо ви хочете видалити пресет кольорів, натисніть на кнопку-іконку «Видалити».
</string>
<string name="help_title_how_to_use_color_presets">
Як використовувати пресети кольорів?
</string>
<string name="help_desc_how_to_use_color_presets_1">
Перейдіть в налаштування Зовнішнього Вигляду(див: Як мені налаштувати Читач?).
Ви можете вибрати який пресет кольорів використовувати в налаштуванні «Пресет Кольорів».
Натисніть на бажаний пресет кольорів, щоб вибрати його, це також змінить ваші кольори в Читачі.
Якщо ви хочете змінити порядок пресета кольорів,
виберіть його та затисніть кнопку-іконку «Тримач»,
після цього перемістіть його до бажаного місця.
Ви можете швидко змінювати пресети кольорів увімкнувши відповідне
налаштування в підкатегорії «Кольори» налаштувань Зовнішнього Вигляду,
та потім провівши вліво або вправо в Читачі, щоб швидко змінити пресет кольорів.
</string>
<!-- Start --> <!-- Start -->
<string name="start_welcome">Вітаємо в Історія Книги!</string> <string name="start_welcome">Вітаємо в Історія Книги!</string>

View file

@ -451,6 +451,45 @@
To show tooltip you can hold on an icon-button. To show tooltip you can hold on an icon-button.
</string> </string>
<string name="help_title_how_to_use_double_click_translation">
How do I use double click translation?
</string>
<string name="help_desc_how_to_use_double_click_translation_1">
Firstly, go to the Reader settings(see: How do I customize the Reader?),
then turn on corresponding setting. After that,
start reading the book(see: How do I read a book?).
Now if you double click on desired paragraph,
external translator will be opened with paragraph\'s text.
</string>
<string name="help_title_how_to_create_color_presets">
How do I create and modify color presets?
</string>
<string name="help_desc_how_to_create_color_presets_1">
Go to the Appearance settings(see: How do I customize the Reader?).
You can modify all color preset\'s settings in the box under «Color Preset» in «Colors» subcategory.
To create a new color preset, click the «Add» icon-button.
There are multiple ways to modify a color preset:
by clicking the text field you can change the name of the color preset,
by moving sliders you can change colors of the color preset,
by clicking the «Shuffle» icon-button you can shuffle all colors.
If you want to delete color preset, click the «Delete» icon-button.
</string>
<string name="help_title_how_to_use_color_presets">
How do I use color presets?
</string>
<string name="help_desc_how_to_use_color_presets_1">
Go to the Appearance settings(see: How do I customize the Reader?).
You can choose which color preset to use in «Color Preset» setting.
Click the desired color preset to select it, this will also change your colors in Reader.
If you want to reorder color preset, select it and hold «Handle» icon-button,
then move it to the desired position.
You can fast change color presets by enabling corresponding setting
in Appearance setting\'s «Colors» subcategory, then swiping left or right in Reader,
to fast change color preset.
</string>
<!-- Start --> <!-- Start -->
<string name="start_welcome">Welcome to Book\'s Story!</string> <string name="start_welcome">Welcome to Book\'s Story!</string>