mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 13:08:46 +01:00
enhancement: placeholder with shimmer effect
This commit is contained in:
parent
1bb8095cea
commit
2214fd1404
@ -6,6 +6,7 @@ import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
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
|
||||
@ -64,6 +65,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.CommunityInfoScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen
|
||||
@ -253,6 +255,15 @@ class CommunityDetailScreen(
|
||||
},
|
||||
)
|
||||
}
|
||||
if (uiState.posts.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
Column {
|
||||
PostCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -0,0 +1,76 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.shimmerEffect
|
||||
|
||||
@Composable
|
||||
fun CommentCardPlaceholder(
|
||||
hideAuthor: Boolean = false,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
if (!hideAuthor) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.size(20.dp)
|
||||
.clip(CircleShape)
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = Spacing.xxxs),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth(0.5f)
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(80.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.shimmerEffect
|
||||
|
||||
@Composable
|
||||
fun InboxCardPlaceholder(
|
||||
postLayout: PostLayout = PostLayout.Card,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.let {
|
||||
if (postLayout == PostLayout.Card) {
|
||||
it.padding(horizontal = Spacing.xs).background(
|
||||
color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp),
|
||||
shape = RoundedCornerShape(CornerSize.l),
|
||||
).padding(Spacing.s)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
},
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(vertical = Spacing.xxxs)
|
||||
.height(50.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ fun PostCard(
|
||||
hideAuthor: Boolean = false,
|
||||
postLayout: PostLayout = PostLayout.Card,
|
||||
withOverflowBlurred: Boolean = true,
|
||||
blurNsfw: Boolean,
|
||||
blurNsfw: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
@ -63,12 +63,10 @@ fun PostCard(
|
||||
Box(
|
||||
modifier = modifier.let {
|
||||
if (postLayout == PostLayout.Card) {
|
||||
it.padding(horizontal = Spacing.xs)
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp),
|
||||
shape = RoundedCornerShape(CornerSize.l),
|
||||
)
|
||||
.padding(Spacing.s)
|
||||
it.padding(horizontal = Spacing.xs).background(
|
||||
color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp),
|
||||
shape = RoundedCornerShape(CornerSize.l),
|
||||
).padding(Spacing.s)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
@ -146,9 +144,7 @@ private fun CompactPost(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xs)
|
||||
) {
|
||||
PostCardImage(
|
||||
modifier = Modifier
|
||||
.weight(0.2f)
|
||||
.clip(RoundedCornerShape(CornerSize.s)),
|
||||
modifier = Modifier.weight(0.2f).clip(RoundedCornerShape(CornerSize.s)),
|
||||
minHeight = Dp.Unspecified,
|
||||
maxHeight = Dp.Unspecified,
|
||||
imageUrl = post.imageUrl,
|
||||
@ -156,8 +152,7 @@ private fun CompactPost(
|
||||
onImageClick = onImageClick,
|
||||
)
|
||||
PostCardTitle(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = post.title
|
||||
modifier = Modifier.weight(1f), text = post.title
|
||||
)
|
||||
}
|
||||
PostCardFooter(
|
||||
@ -210,8 +205,7 @@ private fun ExtendedPost(
|
||||
modifier = Modifier.padding(
|
||||
vertical = Spacing.xs,
|
||||
horizontal = Spacing.xs,
|
||||
),
|
||||
text = post.title
|
||||
), text = post.title
|
||||
)
|
||||
|
||||
PostCardImage(
|
||||
@ -222,22 +216,18 @@ private fun ExtendedPost(
|
||||
)
|
||||
Box {
|
||||
PostCardBody(
|
||||
modifier = Modifier
|
||||
.let {
|
||||
if (withOverflowBlurred) {
|
||||
it.heightIn(max = 200.dp)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
modifier = Modifier.let {
|
||||
if (withOverflowBlurred) {
|
||||
it.heightIn(max = 200.dp)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
.padding(horizontal = Spacing.xs),
|
||||
}.padding(horizontal = Spacing.xs),
|
||||
text = post.text,
|
||||
)
|
||||
if (withOverflowBlurred) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(Spacing.xxl)
|
||||
.fillMaxWidth()
|
||||
modifier = Modifier.height(Spacing.xxl).fillMaxWidth()
|
||||
.align(Alignment.BottomCenter).background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
|
@ -0,0 +1,212 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
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.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.shimmerEffect
|
||||
|
||||
@Composable
|
||||
fun PostCardPlaceholder(
|
||||
postLayout: PostLayout = PostLayout.Card,
|
||||
) {
|
||||
when (postLayout) {
|
||||
PostLayout.Compact -> {
|
||||
Column(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.size(20.dp)
|
||||
.clip(CircleShape)
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = Spacing.xxxs),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth(0.5f)
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.Top,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xs)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(0.2f)
|
||||
.aspectRatio(1.33f)
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(40.dp)
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PostLayout.Card -> {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = Spacing.xs).background(
|
||||
color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp),
|
||||
shape = RoundedCornerShape(CornerSize.l),
|
||||
).padding(Spacing.s),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.clip(CircleShape)
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = Spacing.xxxs),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth(0.5f)
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(200.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PostLayout.Full -> {
|
||||
Column(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.s)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.clip(CircleShape)
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = Spacing.xxxs),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.height(20.dp)
|
||||
.fillMaxWidth(0.5f)
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(200.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.m))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
@ -68,6 +68,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
@ -328,6 +329,11 @@ class PostDetailScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uiState.comments.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
CommentCardPlaceholder()
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val fontScale by themeRepository.contentFontScale.collectAsState()
|
||||
|
@ -63,7 +63,9 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserHeader
|
||||
@ -242,6 +244,15 @@ class UserDetailScreen(
|
||||
}
|
||||
}
|
||||
if (uiState.section == UserDetailSection.Posts) {
|
||||
if (uiState.posts.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
Column {
|
||||
PostCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -379,6 +390,11 @@ class UserDetailScreen(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (uiState.comments.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
CommentCardPlaceholder()
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -1,11 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.utils
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
@ -23,15 +18,6 @@ import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun Modifier.onClick(onClick: () -> Unit): Modifier = composed {
|
||||
clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
onClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun String.toLanguageName() = when (this) {
|
||||
"es" -> stringResource(MR.strings.language_es)
|
||||
|
@ -0,0 +1,16 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.utils
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
|
||||
fun Modifier.onClick(onClick: () -> Unit): Modifier = composed {
|
||||
clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
onClick()
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.utils
|
||||
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.infiniteRepeatable
|
||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
|
||||
fun Modifier.shimmerEffect(
|
||||
duration: Int = 1000,
|
||||
colors: List<Color> = listOf(
|
||||
Color(0xFF333333),
|
||||
Color(0xFF999999),
|
||||
Color(0xFF333333),
|
||||
),
|
||||
): Modifier = composed {
|
||||
var size by remember {
|
||||
mutableStateOf(IntSize.Zero)
|
||||
}
|
||||
val transition = rememberInfiniteTransition()
|
||||
val startOffsetX by transition.animateFloat(
|
||||
initialValue = -2 * size.width.toFloat(),
|
||||
targetValue = 2 * size.width.toFloat(),
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(duration)
|
||||
)
|
||||
)
|
||||
|
||||
background(
|
||||
brush = Brush.linearGradient(
|
||||
colors = colors,
|
||||
start = Offset(startOffsetX, 0f),
|
||||
end = Offset(startOffsetX + size.width.toFloat(), size.height.toFloat())
|
||||
)
|
||||
).alpha(0.5f).onGloballyPositioned {
|
||||
size = it.size
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.home.postlist
|
||||
|
||||
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
|
||||
@ -48,6 +49,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen
|
||||
@ -151,6 +153,15 @@ class PostListScreen : Screen {
|
||||
LazyColumn(
|
||||
state = lazyListState,
|
||||
) {
|
||||
if (uiState.posts.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
Column {
|
||||
PostCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val fontScale by themeRepository.contentFontScale.collectAsState()
|
||||
|
@ -2,10 +2,8 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesViewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import org.koin.java.KoinJavaComponent.inject
|
||||
|
||||
actual fun getInboxViewModel(): InboxViewModel {
|
||||
|
@ -7,8 +7,8 @@ import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesViewModel
|
||||
import org.koin.dsl.module
|
||||
|
@ -2,8 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesViewModel
|
||||
|
||||
expect fun getInboxViewModel(): InboxViewModel
|
||||
|
@ -38,7 +38,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotific
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository
|
||||
|
@ -40,6 +40,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
@ -85,6 +86,13 @@ class InboxMentionsScreen : Tab {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
if (uiState.mentions.isEmpty() && uiState.loading) {
|
||||
items(3) {
|
||||
InboxCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.mentions) { idx, mention ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
@ -0,0 +1,54 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.shimmerEffect
|
||||
|
||||
@Composable
|
||||
internal fun ChatCardPlaceholder() {
|
||||
Row(
|
||||
modifier = Modifier.padding(Spacing.xs),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(46.dp)
|
||||
.clip(CircleShape)
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(50.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(28.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PrivateMessageModel
|
@ -1,4 +1,4 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@ -76,6 +76,11 @@ class InboxMessagesScreen : Tab {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
if (uiState.chats.isEmpty() && uiState.loading) {
|
||||
items(1) {
|
||||
ChatCardPlaceholder()
|
||||
}
|
||||
}
|
||||
items(uiState.chats) { chat ->
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val fontScale by themeRepository.contentFontScale.collectAsState()
|
@ -1,4 +1,4 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
@ -46,6 +46,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
@ -90,6 +91,13 @@ class InboxRepliesScreen : Tab {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
if (uiState.replies.isEmpty() && uiState.loading) {
|
||||
items(3) {
|
||||
InboxCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.replies) { idx, mention ->
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val fontScale by themeRepository.contentFontScale.collectAsState()
|
||||
|
@ -2,12 +2,10 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesViewModel
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
actual fun getInboxViewModel() = InboxScreenModelHelper.model
|
||||
|
||||
|
@ -35,7 +35,9 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
@ -126,6 +128,15 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
}
|
||||
if (uiState.section == ProfileLoggedSection.Posts) {
|
||||
if (uiState.posts.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
Column {
|
||||
PostCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
PostCard(
|
||||
modifier = Modifier.onClick {
|
||||
@ -210,6 +221,11 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (uiState.comments.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
CommentCardPlaceholder(hideAuthor = true)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
CommentCard(
|
||||
modifier = Modifier.onClick {
|
||||
|
@ -57,6 +57,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.Co
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
@ -233,6 +234,15 @@ class ExploreScreen : Screen {
|
||||
modifier = Modifier.padding(Spacing.xxs).pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn {
|
||||
if (uiState.results.isEmpty() && uiState.loading) {
|
||||
items(5) {
|
||||
Column {
|
||||
PostCardPlaceholder(
|
||||
postLayout = uiState.postLayout,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.results) { idx, result ->
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val fontScale by themeRepository.contentFontScale.collectAsState()
|
||||
|
Loading…
x
Reference in New Issue
Block a user