AboutScreen: Added loading indicator to "Check For Updates".

This commit is contained in:
acclorite 2024-08-08 14:43:38 +03:00
parent 69a72c59fc
commit a86163360d
5 changed files with 116 additions and 34 deletions

View file

@ -144,8 +144,10 @@ private fun AboutScreen(
)
append("\n")
append(stringResource(id = R.string.app_version_option_desc_2))
}
},
showLoading = state.value.updateLoading
) {
if (!state.value.alreadyCheckedForUpdates) {
onEvent(
AboutEvent.OnCheckForUpdates(
context = context,
@ -165,6 +167,13 @@ private fun AboutScreen(
}
)
)
} else {
Toast.makeText(
context,
context.getString(R.string.no_updates),
Toast.LENGTH_LONG
).show()
}
}
}

View file

@ -1,22 +1,38 @@
package ua.acclorite.book_story.presentation.screens.about.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ua.acclorite.book_story.presentation.ui.FadeTransitionPreservingSpace
/**
* About screen item.
* About Screen Item.
* Clickable item, that has title, description and loading state.
*
* @param modifier [Modifier].
* @param title Title of the item.
* @param description Description of the item.
* @param verticalPadding Vertical item padding.
* @param showLoading Whether loading indicator is shown.
* @param isOnClickEnabled Whether this item is clickable.
* @param onClick OnClick callback.
*/
@Composable
fun AboutItem(
@ -24,18 +40,20 @@ fun AboutItem(
title: String,
description: AnnotatedString?,
verticalPadding: Dp = 12.dp,
showLoading: Boolean = false,
isOnClickEnabled: Boolean = true,
onClick: () -> Unit = {}
) {
Column(
Row(
modifier
.fillMaxWidth()
.clickable(enabled = isOnClickEnabled) {
onClick()
}
.padding(horizontal = 18.dp, vertical = verticalPadding),
verticalArrangement = Arrangement.Center
verticalAlignment = Alignment.CenterVertically
) {
Column(Modifier.weight(1f)) {
Text(
title,
style = MaterialTheme.typography.bodyLarge,
@ -51,4 +69,16 @@ fun AboutItem(
)
}
}
FadeTransitionPreservingSpace(visible = showLoading) {
Row {
Spacer(modifier = Modifier.width(18.dp))
CircularProgressIndicator(
color = MaterialTheme.colorScheme.onSurface,
strokeCap = StrokeCap.Round,
modifier = Modifier.size(28.dp)
)
}
}
}
}

View file

@ -6,5 +6,7 @@ import ua.acclorite.book_story.data.remote.dto.LatestReleaseInfo
@Immutable
data class AboutState(
val showUpdateDialog: Boolean = false,
val alreadyCheckedForUpdates: Boolean = false,
val updateLoading: Boolean = false,
val updateInfo: LatestReleaseInfo? = null
)

View file

@ -40,9 +40,19 @@ class AboutViewModel @Inject constructor(
is AboutEvent.OnCheckForUpdates -> {
viewModelScope.launch {
_state.update {
it.copy(
updateLoading = true
)
}
val result = checkForUpdates.execute(false)
if (result == null) {
_state.update {
it.copy(
updateLoading = false
)
}
event.error()
return@launch
}
@ -52,12 +62,19 @@ class AboutViewModel @Inject constructor(
if (version == currentVersion) {
event.noUpdatesFound()
_state.update {
it.copy(
updateLoading = false,
alreadyCheckedForUpdates = true
)
}
return@launch
}
_state.update {
it.copy(
showUpdateDialog = true,
updateLoading = false,
updateInfo = result
)
}

View file

@ -1,5 +1,8 @@
package ua.acclorite.book_story.presentation.ui
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.EaseInOut
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@ -8,8 +11,11 @@ import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
@ -87,3 +93,21 @@ fun SlidingTransition(
content = content
)
}
@Composable
fun FadeTransitionPreservingSpace(
visible: Boolean,
modifier: Modifier = Modifier,
animationSpec: AnimationSpec<Float> = tween(durationMillis = 300, easing = EaseInOut),
content: @Composable () -> Unit
) {
val alpha by animateFloatAsState(
if (visible) 1f else 0f,
label = "",
animationSpec = animationSpec
)
Box(modifier = modifier.alpha(alpha)) {
content.invoke()
}
}