feat(ui): add animated empty states

This commit is contained in:
2026-07-15 18:34:26 +02:00
parent 7cd125053c
commit 43db35e9a2
7 changed files with 51 additions and 11 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -49,6 +49,7 @@ import com.vnidrop.app.core.TransferStatus
import com.vnidrop.app.ui.components.AdaptiveDrawer
import com.vnidrop.app.ui.components.DestructiveButton
import com.vnidrop.app.ui.components.DestructiveQuietButton
import com.vnidrop.app.ui.components.EmptyStateAnimation
import com.vnidrop.app.ui.components.Field
import com.vnidrop.app.ui.components.PrimaryButton
import com.vnidrop.app.ui.components.ProgressRow
@@ -176,10 +177,11 @@ private fun ReceiveEmptyState(onOpen: () -> Unit) {
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Box(Modifier.size(68.dp).background(colors.brandLink.copy(alpha = 0.12f), RoundedCornerShape(20.dp)), contentAlignment = Alignment.Center) {
Icon(ReceiveIcons.Download, null, tint = colors.brandLink, modifier = Modifier.size(30.dp))
}
Text(stringResource(Res.string.receive_empty_title), modifier = Modifier.padding(top = 22.dp), style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
EmptyStateAnimation(
assetPath = "files/animations/receive_empty_state.json",
modifier = Modifier.size(168.dp),
)
Text(stringResource(Res.string.receive_empty_title), modifier = Modifier.padding(top = 12.dp), style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
Text(
stringResource(Res.string.receive_empty_body),
modifier = Modifier.padding(top = 8.dp).widthIn(max = 480.dp),

View File

@@ -37,6 +37,7 @@ import androidx.compose.ui.unit.dp
import com.vnidrop.app.core.CoreEventModel
import com.vnidrop.app.core.Transfer
import com.vnidrop.app.core.TransferStatus
import com.vnidrop.app.ui.components.EmptyStateAnimation
import com.vnidrop.app.ui.components.PillTone
import com.vnidrop.app.ui.components.PrimaryButton
import com.vnidrop.app.ui.components.ProgressRow
@@ -145,15 +146,13 @@ private fun SendEmptyState(onOpenComposer: () -> Unit) {
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Box(
modifier = Modifier.size(68.dp).clip(RoundedCornerShape(22.dp)).background(colors.brandLink.copy(alpha = 0.12f)),
contentAlignment = Alignment.Center,
) {
Icon(SendIcons.File, contentDescription = null, tint = colors.brandLink, modifier = Modifier.size(30.dp))
}
EmptyStateAnimation(
assetPath = "files/animations/send_empty_state.json",
modifier = Modifier.size(168.dp),
)
Text(
stringResource(Res.string.send_empty_title),
modifier = Modifier.padding(top = 22.dp),
modifier = Modifier.padding(top = 12.dp),
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,

View File

@@ -0,0 +1,34 @@
package com.vnidrop.app.ui.components
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import io.github.alexzhirkevich.compottie.Compottie
import io.github.alexzhirkevich.compottie.LottieCompositionSpec
import io.github.alexzhirkevich.compottie.rememberLottieComposition
import io.github.alexzhirkevich.compottie.rememberLottiePainter
import vnidrop.shared.generated.resources.Res
@Composable
internal fun EmptyStateAnimation(
assetPath: String,
modifier: Modifier = Modifier,
) {
val composition by rememberLottieComposition {
LottieCompositionSpec.JsonString(
Res.readBytes(assetPath).decodeToString(),
)
}
Image(
painter = rememberLottiePainter(
composition = composition,
iterations = Compottie.IterateForever,
),
contentDescription = null,
modifier = modifier,
contentScale = ContentScale.Fit,
)
}