mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-17 23:47:02 +05:30
Merge #140
140: Use a livelier loading animation r=msfjarvis a=msfjarvis bors r+ Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
commit
6b53f132d5
4 changed files with 124 additions and 43 deletions
|
@ -1,41 +0,0 @@
|
||||||
package dev.msfjarvis.lobsters.ui.posts
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import dev.msfjarvis.lobsters.R
|
|
||||||
import dev.msfjarvis.lobsters.util.IconResource
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun EmptyList(saved: Boolean) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
if (saved) {
|
|
||||||
IconResource(
|
|
||||||
R.drawable.ic_favorite_border_24px,
|
|
||||||
tint = Color(0xFFD97373),
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
contentDescription = stringResource(R.string.add_to_saved_posts),
|
|
||||||
)
|
|
||||||
Text(stringResource(R.string.no_saved_posts))
|
|
||||||
} else {
|
|
||||||
IconResource(
|
|
||||||
R.drawable.ic_sync_problem_24px,
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
contentDescription = stringResource(R.string.remove_from_saved_posts),
|
|
||||||
)
|
|
||||||
Text(stringResource(R.string.loading))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,11 @@ fun HottestPosts(
|
||||||
val urlLauncher = LocalUrlLauncher.current
|
val urlLauncher = LocalUrlLauncher.current
|
||||||
|
|
||||||
if (posts.loadState.refresh == LoadState.Loading) {
|
if (posts.loadState.refresh == LoadState.Loading) {
|
||||||
EmptyList(saved = false)
|
LazyColumn {
|
||||||
|
items(15) {
|
||||||
|
LoadingLobstersItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
package dev.msfjarvis.lobsters.ui.posts
|
package dev.msfjarvis.lobsters.ui.posts
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import dev.msfjarvis.lobsters.R
|
||||||
import dev.msfjarvis.lobsters.data.local.SavedPost
|
import dev.msfjarvis.lobsters.data.local.SavedPost
|
||||||
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
|
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
|
||||||
|
import dev.msfjarvis.lobsters.util.IconResource
|
||||||
import dev.msfjarvis.lobsters.util.asZonedDateTime
|
import dev.msfjarvis.lobsters.util.asZonedDateTime
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@ -21,7 +32,19 @@ fun SavedPosts(
|
||||||
val urlLauncher = LocalUrlLauncher.current
|
val urlLauncher = LocalUrlLauncher.current
|
||||||
|
|
||||||
if (posts.isEmpty()) {
|
if (posts.isEmpty()) {
|
||||||
EmptyList(saved = true)
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
IconResource(
|
||||||
|
R.drawable.ic_favorite_border_24px,
|
||||||
|
tint = Color(0xFFD97373),
|
||||||
|
modifier = Modifier.padding(16.dp),
|
||||||
|
contentDescription = stringResource(R.string.add_to_saved_posts),
|
||||||
|
)
|
||||||
|
Text(stringResource(R.string.no_saved_posts))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package dev.msfjarvis.lobsters.ui.posts
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.keyframes
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.absoluteOffset
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredHeight
|
||||||
|
import androidx.compose.foundation.layout.requiredSize
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LoadingLobstersItem() {
|
||||||
|
val infiniteTransition = rememberInfiniteTransition()
|
||||||
|
val alpha by infiniteTransition.animateFloat(
|
||||||
|
initialValue = 0.2f,
|
||||||
|
targetValue = 1f,
|
||||||
|
animationSpec = infiniteRepeatable(
|
||||||
|
animation = keyframes {
|
||||||
|
durationMillis = 1000
|
||||||
|
0.7f at 500
|
||||||
|
},
|
||||||
|
repeatMode = RepeatMode.Reverse
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val color = Color.LightGray.copy(alpha = alpha)
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.height(70.dp),
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.padding(start = 12.dp, end = 12.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.SpaceEvenly,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(12.dp)
|
||||||
|
.background(color)
|
||||||
|
.padding(8.dp),
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||||
|
modifier = Modifier
|
||||||
|
.absoluteOffset(y = 12.dp),
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(30.dp)
|
||||||
|
.background(color = color, shape = CircleShape),
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredHeight(12.dp)
|
||||||
|
.requiredWidth(40.dp)
|
||||||
|
.absoluteOffset(x = 12.dp)
|
||||||
|
.background(color),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun ShimmerListPreview() {
|
||||||
|
LazyColumn {
|
||||||
|
items(10) {
|
||||||
|
LoadingLobstersItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue