🚀 Help screen UI improvement + New transition

* Improved UI
* Removed help tip (How to find books)
* Improved animations
* Removed unused string resources
* New transition

Part of: #60
This commit is contained in:
Acclorite 2024-08-31 14:32:43 +03:00
parent 169b939523
commit 7c925427b5
14 changed files with 75 additions and 353 deletions

View file

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

View file

@ -26,7 +26,6 @@ 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.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 {
@ -167,16 +166,6 @@ private fun provideCredits() = listOf(
) )
private fun provideHelpTips() = listOf( private fun provideHelpTips() = 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( HelpTip(
title = R.string.help_title_how_to_add_books, title = R.string.help_title_how_to_add_books,
description = { onNavigate, fromStart -> description = { onNavigate, fromStart ->

View file

@ -1,13 +1,11 @@
package ua.acclorite.book_story.presentation.screens.help package ua.acclorite.book_story.presentation.screens.help
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
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.imePadding
import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -47,7 +45,6 @@ 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.HelpItem 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.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
import ua.acclorite.book_story.presentation.screens.start.data.StartEvent import ua.acclorite.book_story.presentation.screens.start.data.StartEvent
@ -70,7 +67,6 @@ fun HelpScreenRoot(screen: Screen.Help) {
HelpScreen( HelpScreen(
state = state, state = state,
onNavigate = { navigator.it() }, onNavigate = { navigator.it() },
onEvent = helpViewModel::onEvent,
onMainEvent = mainViewModel::onEvent, onMainEvent = mainViewModel::onEvent,
onBrowseEvent = browseViewModel::onEvent, onBrowseEvent = browseViewModel::onEvent,
onStartEvent = startViewModel::onEvent onStartEvent = startViewModel::onEvent
@ -84,7 +80,6 @@ fun HelpScreenRoot(screen: Screen.Help) {
private fun HelpScreen( private fun HelpScreen(
state: State<HelpState>, state: State<HelpState>,
onNavigate: OnNavigate, onNavigate: OnNavigate,
onEvent: (HelpEvent) -> Unit,
onMainEvent: (MainEvent) -> Unit, onMainEvent: (MainEvent) -> Unit,
onBrowseEvent: (BrowseEvent) -> Unit, onBrowseEvent: (BrowseEvent) -> Unit,
onStartEvent: (StartEvent) -> Unit onStartEvent: (StartEvent) -> Unit
@ -158,17 +153,11 @@ private fun HelpScreen(
CustomLazyColumn( CustomLazyColumn(
Modifier Modifier
.fillMaxSize() .fillMaxSize()
.padding(paddingValues) .padding(paddingValues),
.imePadding(), state = scrollState.second
state = scrollState.second,
contentPadding = PaddingValues(horizontal = 18.dp)
) { ) {
item { item {
Spacer( Spacer(modifier = Modifier.height(16.dp))
modifier = Modifier
.animateItem()
.height(16.dp)
)
} }
item { item {
@ -176,28 +165,19 @@ private fun HelpScreen(
} }
item { item {
Spacer( Spacer(modifier = Modifier.height(8.dp))
modifier = Modifier
.animateItem()
.height(16.dp)
)
} }
customItems(Constants.HELP_TIPS, key = { it.title }) { helpTip -> customItems(Constants.HELP_TIPS, key = { it.title }) { helpTip ->
HelpItem( HelpItem(
helpTip = helpTip, helpTip = helpTip,
onNavigate = onNavigate, onNavigate = onNavigate,
fromStart = state.value.fromStart, fromStart = state.value.fromStart
onHelpEvent = onEvent
) )
} }
item { item {
Spacer( Spacer(modifier = Modifier.height(48.dp))
modifier = Modifier
.animateItem()
.height(48.dp)
)
} }
} }
} }

View file

@ -4,8 +4,8 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
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.lazy.LazyItemScope
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
@ -20,7 +20,7 @@ import androidx.compose.ui.text.AnnotatedString
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.presentation.components.CustomTooltip import ua.acclorite.book_story.presentation.components.CustomTooltip
import ua.acclorite.book_story.presentation.ui.SlidingTransition import ua.acclorite.book_story.presentation.ui.ExpandingTransition
/** /**
* Help Clickable Note. * Help Clickable Note.
@ -29,10 +29,10 @@ import ua.acclorite.book_story.presentation.ui.SlidingTransition
* @param text [AnnotatedString]. * @param text [AnnotatedString].
*/ */
@Composable @Composable
fun LazyItemScope.HelpClickableNote(text: AnnotatedString) { fun HelpClickableNote(text: AnnotatedString) {
val showNote = rememberSaveable { mutableStateOf(true) } val showNote = rememberSaveable { mutableStateOf(true) }
Column(Modifier.animateItem()) { Column(Modifier.padding(horizontal = 18.dp)) {
CustomTooltip(text = stringResource(R.string.note_content_desc)) { CustomTooltip(text = stringResource(R.string.note_content_desc)) {
Icon( Icon(
imageVector = Icons.Outlined.Info, imageVector = Icons.Outlined.Info,
@ -46,7 +46,7 @@ fun LazyItemScope.HelpClickableNote(text: AnnotatedString) {
) )
} }
SlidingTransition(visible = showNote.value) { ExpandingTransition(visible = showNote.value) {
Column { Column {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
@ -59,9 +59,3 @@ fun LazyItemScope.HelpClickableNote(text: AnnotatedString) {
} }
} }
} }

View file

@ -1,7 +1,9 @@
package ua.acclorite.book_story.presentation.screens.help.components package ua.acclorite.book_story.presentation.screens.help.components
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
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.Row import androidx.compose.foundation.layout.Row
@ -11,18 +13,18 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding 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.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.HorizontalDivider
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.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable 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.clip
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.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
@ -30,8 +32,7 @@ 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.model.HelpTip
import ua.acclorite.book_story.domain.util.OnNavigate 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.ExpandingTransition
import ua.acclorite.book_story.presentation.ui.SlidingTransition
/** /**
* Help Item. * Help Item.
@ -40,29 +41,44 @@ import ua.acclorite.book_story.presentation.ui.SlidingTransition
* @param helpTip [HelpTip] to be shown. * @param helpTip [HelpTip] to be shown.
* @param onNavigate Navigator callback. * @param onNavigate Navigator callback.
* @param fromStart Whether user came from Start screen. * @param fromStart Whether user came from Start screen.
* @param onHelpEvent [HelpEvent] callback.
*/ */
@Composable @Composable
fun LazyItemScope.HelpItem( fun HelpItem(
helpTip: HelpTip, helpTip: HelpTip,
onNavigate: OnNavigate, onNavigate: OnNavigate,
fromStart: Boolean, fromStart: Boolean
onHelpEvent: (HelpEvent) -> Unit
) { ) {
val showDescription = rememberSaveable { val showDescription = rememberSaveable {
mutableStateOf(false) mutableStateOf(false)
} }
val animatedArrowRotation by animateFloatAsState(
val animatedArrowRotation = animateFloatAsState(
targetValue = if (showDescription.value) 0f else -180f, targetValue = if (showDescription.value) 0f else -180f,
animationSpec = tween(300), animationSpec = tween(400)
label = stringResource(id = R.string.arrow_anim_content_desc) )
val animatedBackgroundColor = animateColorAsState(
targetValue = if (showDescription.value) {
MaterialTheme.colorScheme.surfaceContainer
} else MaterialTheme.colorScheme.surfaceContainerLow,
animationSpec = tween(400)
)
val animatedArrowContainerColor = animateColorAsState(
targetValue = if (showDescription.value) {
MaterialTheme.colorScheme.surfaceContainerHigh
} else MaterialTheme.colorScheme.surfaceContainer,
animationSpec = tween(400)
) )
Column( Column(
Modifier Modifier
.animateItem()
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 8.dp) .clip(MaterialTheme.shapes.large)
.padding(horizontal = 8.dp, vertical = 4.dp)
.background(
animatedBackgroundColor.value,
MaterialTheme.shapes.large
)
.padding(vertical = 16.dp, horizontal = 18.dp)
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -83,17 +99,25 @@ fun LazyItemScope.HelpItem(
imageVector = Icons.Outlined.ArrowDropUp, imageVector = Icons.Outlined.ArrowDropUp,
tint = MaterialTheme.colorScheme.onSurfaceVariant, tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier modifier = Modifier
.clip(MaterialTheme.shapes.medium)
.background(
animatedArrowContainerColor.value,
MaterialTheme.shapes.medium
)
.padding(8.dp)
.size(24.dp) .size(24.dp)
.rotate(animatedArrowRotation), .rotate(animatedArrowRotation.value),
contentDescription = stringResource(id = R.string.arrow_content_desc) contentDescription = stringResource(id = R.string.arrow_content_desc)
) )
} }
SlidingTransition( ExpandingTransition(
visible = showDescription.value visible = showDescription.value
) { ) {
Column(Modifier.fillMaxWidth()) { Column(Modifier.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(8.dp))
HorizontalDivider()
Spacer(modifier = Modifier.height(8.dp))
Text( Text(
text = buildAnnotatedString { text = buildAnnotatedString {
helpTip.description.invoke( helpTip.description.invoke(
@ -106,10 +130,6 @@ fun LazyItemScope.HelpItem(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
) )
helpTip.customContent.invoke(
this,
onHelpEvent
)
} }
} }
} }

View file

@ -1,153 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.components.content
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.data.showToast
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 = {
context.getString(R.string.error_no_browser)
.showToast(context = context, longToast = false)
}
)
)
}
) {
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 = {
context.getString(R.string.error_no_browser)
.showToast(context = context, longToast = false)
}
)
)
}
),
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 = {
context.getString(R.string.error_no_browser)
.showToast(context = context, longToast = false)
}
)
)
}
)
},
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,20 +0,0 @@
package ua.acclorite.book_story.presentation.screens.help.data
import android.content.Context
import androidx.compose.runtime.Immutable
@Immutable
sealed class HelpEvent {
data class OnSearchInWeb(
val page: String,
val context: Context,
val error: () -> Unit,
val noAppsFound: () -> Unit
) : HelpEvent()
data class OnNavigateToBrowserPage(
val page: String,
val context: Context,
val noAppsFound: () -> Unit
) : HelpEvent()
}

View file

@ -1,9 +1,5 @@
package ua.acclorite.book_story.presentation.screens.help.data package ua.acclorite.book_story.presentation.screens.help.data
import android.app.SearchManager
import android.content.Intent
import android.net.Uri
import androidx.activity.ComponentActivity
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
@ -12,7 +8,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ua.acclorite.book_story.presentation.data.Screen import ua.acclorite.book_story.presentation.data.Screen
import ua.acclorite.book_story.presentation.data.launchActivity
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@ -23,44 +18,6 @@ class HelpViewModel @Inject constructor(
private val _state = MutableStateFlow(HelpState()) private val _state = MutableStateFlow(HelpState())
val state = _state.asStateFlow() val state = _state.asStateFlow()
fun onEvent(event: HelpEvent) {
when (event) {
is HelpEvent.OnNavigateToBrowserPage -> {
viewModelScope.launch {
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse(event.page)
)
intent.launchActivity(event.context as ComponentActivity) {
event.noAppsFound()
}
}
}
is HelpEvent.OnSearchInWeb -> {
viewModelScope.launch {
if (event.page.isBlank()) {
event.error()
return@launch
}
val intent = Intent()
intent.action = Intent.ACTION_WEB_SEARCH
intent.putExtra(
SearchManager.QUERY,
"${event.page.trim()} filetype:txt OR filetype:pdf"
)
intent.launchActivity(event.context as ComponentActivity) {
event.noAppsFound()
}
}
}
}
}
fun init(screen: Screen.Help) { fun init(screen: Screen.Help) {
viewModelScope.launch { viewModelScope.launch {
_state.update { _state.update {
@ -71,11 +28,3 @@ class HelpViewModel @Inject constructor(
} }
} }
} }

View file

@ -4,9 +4,11 @@ import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.EaseInOut import androidx.compose.animation.core.EaseInOut
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleIn
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutHorizontally
@ -78,6 +80,23 @@ fun SlidingTransition(
) )
} }
@Composable
fun ExpandingTransition(
visible: Boolean,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
CustomAnimatedVisibility(
visible = visible,
modifier = modifier,
enter = expandVertically(tween(400)) +
fadeIn(tween(400)),
exit = shrinkVertically(tween(350)) +
fadeOut(tween(200)),
content = content
)
}
@Composable @Composable
fun FadeTransitionPreservingSpace( fun FadeTransitionPreservingSpace(
visible: Boolean, visible: Boolean,

View file

@ -138,11 +138,6 @@
<string name="report_bug_option">Fehler melden</string> <string name="report_bug_option">Fehler melden</string>
<string name="help_clickable_note_3">kann angeklickt werden. Du kannst diese Notiz auch ausblenden, indem du auf das Symbol klickst, probier es aus!</string> <string name="help_clickable_note_3">kann angeklickt werden. Du kannst diese Notiz auch ausblenden, indem du auf das Symbol klickst, probier es aus!</string>
<string name="help_clickable_note_action">Ich bin anklickbar!</string> <string name="help_clickable_note_action">Ich bin anklickbar!</string>
<string name="help_title_how_to_find_books">Wie finde und lade ich Bücher herunter?</string>
<string name="help_desc_how_to_find_books">Sie können versuchen, die gewünschten Bücher über die bereitgestellten Websites zu finden, oder Sie können das Textfeld verwenden, um online nach Büchern zu suchen.</string>
<string name="help_field_placeholder">Name des Buches</string>
<string name="help_field_support">Nützliche Websites mit Büchern:</string>
<string name="help_field_error">Der Name des Buches darf nicht leer sein</string>
<string name="help_title_how_to_add_books">Wie füge ich Bücher zur Bibliothek hinzu?</string> <string name="help_title_how_to_add_books">Wie füge ich Bücher zur Bibliothek hinzu?</string>
<string name="help_desc_how_to_add_books_1">Gehen Sie zum</string> <string name="help_desc_how_to_add_books_1">Gehen Sie zum</string>
<string name="help_desc_how_to_add_books_2">Durchsuchen</string> <string name="help_desc_how_to_add_books_2">Durchsuchen</string>
@ -284,7 +279,6 @@
<string name="history_content_desc">Leseverlauf</string> <string name="history_content_desc">Leseverlauf</string>
<string name="browse_content_desc">Bücher hinzufügen</string> <string name="browse_content_desc">Bücher hinzufügen</string>
<string name="arrow_content_desc">Pfeil</string> <string name="arrow_content_desc">Pfeil</string>
<string name="arrow_anim_content_desc">Pfeilanimation</string>
<string name="required_content_desc">Vorausgesetzt</string> <string name="required_content_desc">Vorausgesetzt</string>
<string name="reset_start_content_desc">Startanleitung zurücksetzen</string> <string name="reset_start_content_desc">Startanleitung zurücksetzen</string>
<string name="exit_editing_content_desc">Bearbeitungsmodus beenden</string> <string name="exit_editing_content_desc">Bearbeitungsmodus beenden</string>

View file

@ -188,10 +188,6 @@
<string name="slava_ukraini">¡Gloria a Ucrania!</string> <string name="slava_ukraini">¡Gloria a Ucrania!</string>
<string name="credits_design">Diseño</string> <string name="credits_design">Diseño</string>
<string name="help_clickable_note_action">¡Puedo hacer clic!</string> <string name="help_clickable_note_action">¡Puedo hacer clic!</string>
<string name="help_title_how_to_find_books">¿Cómo encuentro y descargo libros?</string>
<string name="help_field_placeholder">Nombre del libro</string>
<string name="help_field_support">Páginas útiles con libros:</string>
<string name="help_field_error">El nombre del libro no debe estar vacío</string>
<string name="help_desc_how_to_add_books_1">Ir a la</string> <string name="help_desc_how_to_add_books_1">Ir a la</string>
<string name="help_desc_how_to_add_books_4">Biblioteca</string> <string name="help_desc_how_to_add_books_4">Biblioteca</string>
<string name="help_title_how_to_customize_app">¿Cómo personalizo la aplicación?</string> <string name="help_title_how_to_customize_app">¿Cómo personalizo la aplicación?</string>
@ -221,7 +217,6 @@
<string name="credits_updates">Gestión de nuevas actualizaciones</string> <string name="credits_updates">Gestión de nuevas actualizaciones</string>
<string name="help_clickable_note_3">se puede hacer clic. También puedes ocultar esta nota haciendo clic en el icono, ¡pruébalo!</string> <string name="help_clickable_note_3">se puede hacer clic. También puedes ocultar esta nota haciendo clic en el icono, ¡pruébalo!</string>
<string name="help_clickable_note_2">en este texto resaltado</string> <string name="help_clickable_note_2">en este texto resaltado</string>
<string name="help_desc_how_to_find_books">Puedes intentar encontrar los libros que desees utilizando las páginas de la nota proporcionada o puedes utilizar el campo de texto para buscar los libros en Internet.</string>
<string name="help_title_how_to_add_books">¿Cómo añado libros a la biblioteca?</string> <string name="help_title_how_to_add_books">¿Cómo añado libros a la biblioteca?</string>
<string name="help_desc_how_to_add_books_3">Si no ves los libros descargados intenta actualizar la lista tirando de ella hacia abajo. Asegúrate de que tus libros tienen un formato de archivo compatible. A continuación, haz clic en el libro para seleccionarlo o manténlo presionado para ver su ubicación. Cuando hayas seleccionado todos los libros que quieres, haz clic en el icono de la marca de verificación en la esquina superior derecha, espera a que se carguen todos los libros y haz clic en \"Añadir\". Ahora deberías ver todos los libros que ha añadido en la sección</string> <string name="help_desc_how_to_add_books_3">Si no ves los libros descargados intenta actualizar la lista tirando de ella hacia abajo. Asegúrate de que tus libros tienen un formato de archivo compatible. A continuación, haz clic en el libro para seleccionarlo o manténlo presionado para ver su ubicación. Cuando hayas seleccionado todos los libros que quieres, haz clic en el icono de la marca de verificación en la esquina superior derecha, espera a que se carguen todos los libros y haz clic en \"Añadir\". Ahora deberías ver todos los libros que ha añadido en la sección</string>
<string name="help_title_how_to_edit_book">¿Cómo se edita un libro?</string> <string name="help_title_how_to_edit_book">¿Cómo se edita un libro?</string>
@ -274,7 +269,6 @@
<string name="delete_history_element_content_desc">Eliminar elemento del historial</string> <string name="delete_history_element_content_desc">Eliminar elemento del historial</string>
<string name="library_content_desc">Tu biblioteca</string> <string name="library_content_desc">Tu biblioteca</string>
<string name="arrow_content_desc">Flecha</string> <string name="arrow_content_desc">Flecha</string>
<string name="arrow_anim_content_desc">Animación de flecha</string>
<string name="required_content_desc">Necesario</string> <string name="required_content_desc">Necesario</string>
<string name="exit_editing_content_desc">Salir del modo edición</string> <string name="exit_editing_content_desc">Salir del modo edición</string>
<string name="open_in_web_content_desc">Abrir en la web</string> <string name="open_in_web_content_desc">Abrir en la web</string>

View file

@ -303,14 +303,6 @@
Ayrıca ikona tıklayarak bu notu gizleyebilirsiniz, deneyin! Ayrıca ikona tıklayarak bu notu gizleyebilirsiniz, deneyin!
</string> </string>
<string name="help_clickable_note_action">Ben tıklanabiliyorum!</string> <string name="help_clickable_note_action">Ben tıklanabiliyorum!</string>
<string name="help_title_how_to_find_books">Kitapları nasıl bulup indirebilirim?</string>
<string name="help_desc_how_to_find_books">
İstediğiniz kitapları verilen nottaki sitelerden bulmayı deneyebilir
veya kitapları çevrimiçi aramak için metin alanını kullanabilirsiniz.
</string>
<string name="help_field_placeholder">Kitabın adı</string>
<string name="help_field_support">Kitap içeren faydalı siteler:</string>
<string name="help_field_error">Kitap adı boş olmamalı</string>
<string name="help_title_how_to_add_books">Kitapları Kütüphane\'ye nasıl eklerim?</string> <string name="help_title_how_to_add_books">Kitapları Kütüphane\'ye nasıl eklerim?</string>
<string name="help_desc_how_to_add_books_1">Şuraya gidin:</string> <string name="help_desc_how_to_add_books_1">Şuraya gidin:</string>
<string name="help_desc_how_to_add_books_2">Göz At</string> <string name="help_desc_how_to_add_books_2">Göz At</string>
@ -490,7 +482,6 @@
<string name="history_content_desc">Okuma geçmişi</string> <string name="history_content_desc">Okuma geçmişi</string>
<string name="browse_content_desc">Kitap ekle</string> <string name="browse_content_desc">Kitap ekle</string>
<string name="arrow_content_desc">Ok</string> <string name="arrow_content_desc">Ok</string>
<string name="arrow_anim_content_desc">Ok animasyonu</string>
<string name="required_content_desc">Gerekli</string> <string name="required_content_desc">Gerekli</string>
<string name="reset_start_content_desc">Başlangıç kılavuzunu sıfırla</string> <string name="reset_start_content_desc">Başlangıç kılavuzunu sıfırla</string>
<string name="exit_editing_content_desc">Düzenleme modundan çık</string> <string name="exit_editing_content_desc">Düzenleme modundan çık</string>

View file

@ -1,9 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools"> <resources>
<!-- Book sources -->
<string-array name="book_sites" tools:ignore="InconsistentArrays">
<item>Архів Анни|https://uk.annas-archive.org</item>
<item>Укрліб|https://www.ukrlib.com.ua</item>
</string-array>
<!-- Notifications --> <!-- Notifications -->
<string name="updates_notification_channel">Нові оновлення</string> <string name="updates_notification_channel">Нові оновлення</string>
@ -383,15 +378,6 @@
</string> </string>
<string name="help_clickable_note_action">На мене можна натиснути!</string> <string name="help_clickable_note_action">На мене можна натиснути!</string>
<string name="help_title_how_to_find_books">Як мені знайти та завантажити книги?</string>
<string name="help_desc_how_to_find_books">
Ви можете спробувати знайти бажані книги використовуючи сайти з наведеної примітки
або ви можете використати текстове поле, щоб шукати книги в інтернеті.
</string>
<string name="help_field_placeholder">Назва книги</string>
<string name="help_field_support">Корисні сайти з книгами:</string>
<string name="help_field_error">Назва книги не має бути порожньою</string>
<string name="help_title_how_to_add_books">Як мені додати книги в Бібліотеку?</string> <string name="help_title_how_to_add_books">Як мені додати книги в Бібліотеку?</string>
<string name="help_desc_how_to_add_books_1">Перейдіть в</string> <string name="help_desc_how_to_add_books_1">Перейдіть в</string>
<string name="help_desc_how_to_add_books_2">Огляд</string> <string name="help_desc_how_to_add_books_2">Огляд</string>
@ -594,7 +580,6 @@
<string name="history_content_desc">Історія читання</string> <string name="history_content_desc">Історія читання</string>
<string name="browse_content_desc">Додавайте книги</string> <string name="browse_content_desc">Додавайте книги</string>
<string name="arrow_content_desc">Стрілка</string> <string name="arrow_content_desc">Стрілка</string>
<string name="arrow_anim_content_desc">Анімація стрілки</string>
<string name="required_content_desc">Необхідно</string> <string name="required_content_desc">Необхідно</string>
<string name="reset_start_content_desc">Скинути початковий посібник</string> <string name="reset_start_content_desc">Скинути початковий посібник</string>
<string name="exit_editing_content_desc">Вийти з режиму редагування</string> <string name="exit_editing_content_desc">Вийти з режиму редагування</string>

View file

@ -1,15 +1,8 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="InconsistentArrays"> <resources>
<!-- Basic Strings --> <!-- Basic Strings -->
<string name="app_version" translatable="false">1.2.0</string> <string name="app_version" translatable="false">1.2.0</string>
<string name="app_name" translatable="false">Book\'s Story</string> <string name="app_name" translatable="false">Book\'s Story</string>
<!-- Book sources -->
<string-array name="book_sites">
<item>Anna\'s Archive|https://www.annas-archive.org</item>
<item>Project Gutenberg|https://www.gutenberg.org</item>
<item>Standard Ebooks|https://www.standardebooks.org</item>
</string-array>
<!-- About sites --> <!-- About sites -->
<string name="download_latest_release_page" translatable="false"> <string name="download_latest_release_page" translatable="false">
https://www.github.com/Acclorite/book-story/releases/latest/download/book-story.apk https://www.github.com/Acclorite/book-story/releases/latest/download/book-story.apk
@ -402,15 +395,6 @@
</string> </string>
<string name="help_clickable_note_action">I\'m clickable!</string> <string name="help_clickable_note_action">I\'m clickable!</string>
<string name="help_title_how_to_find_books">How do I find and download books?</string>
<string name="help_desc_how_to_find_books">
You can try to find desired books using sites from provided note
or you can use text field to search for books online.
</string>
<string name="help_field_placeholder">Book\'s name</string>
<string name="help_field_support">Useful sites with books:</string>
<string name="help_field_error">Book\'s name should not be empty</string>
<string name="help_title_how_to_add_books">How do I add books to the Library?</string> <string name="help_title_how_to_add_books">How do I add books to the Library?</string>
<string name="help_desc_how_to_add_books_1">Go to the</string> <string name="help_desc_how_to_add_books_1">Go to the</string>
<string name="help_desc_how_to_add_books_2">Browse</string> <string name="help_desc_how_to_add_books_2">Browse</string>
@ -612,7 +596,6 @@
<string name="history_content_desc">Reading history</string> <string name="history_content_desc">Reading history</string>
<string name="browse_content_desc">Add books</string> <string name="browse_content_desc">Add books</string>
<string name="arrow_content_desc">Arrow</string> <string name="arrow_content_desc">Arrow</string>
<string name="arrow_anim_content_desc">Arrow animation</string>
<string name="required_content_desc">Required</string> <string name="required_content_desc">Required</string>
<string name="reset_start_content_desc">Reset start guide</string> <string name="reset_start_content_desc">Reset start guide</string>
<string name="exit_editing_content_desc">Exit editing mode</string> <string name="exit_editing_content_desc">Exit editing mode</string>