fix: remove glitch in compact mode and add placeholders for users and communities; closes #47

This commit is contained in:
Diego Beraldin 2023-10-08 19:52:14 +02:00
parent 31981cd2e6
commit f4149a2041
17 changed files with 166 additions and 160 deletions

View File

@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
@ -25,6 +26,7 @@ actual fun CustomImage(
modifier: Modifier,
url: String,
autoload: Boolean,
loadButtonContent: @Composable (() -> Unit)?,
contentDescription: String?,
quality: FilterQuality,
contentScale: ContentScale,
@ -82,7 +84,15 @@ actual fun CustomImage(
shouldBeRendered = true
},
) {
Text(text = stringResource(MR.strings.button_load))
if (loadButtonContent != null) {
loadButtonContent?.invoke()
} else {
Text(
text = stringResource(MR.strings.button_load),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
}

View File

@ -14,6 +14,7 @@ expect fun CustomImage(
modifier: Modifier = Modifier,
url: String,
autoload: Boolean = true,
loadButtonContent: @Composable (() -> Unit)? = null,
contentDescription: String? = null,
quality: FilterQuality = FilterQuality.Medium,
contentScale: ContentScale = ContentScale.Fit,

View File

@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
import dev.icerock.moko.resources.compose.stringResource
import io.kamel.image.KamelImage
@ -25,6 +26,7 @@ actual fun CustomImage(
modifier: Modifier,
url: String,
autoload: Boolean,
loadButtonContent: @Composable (() -> Unit)?,
contentDescription: String?,
quality: FilterQuality,
contentScale: ContentScale,
@ -63,7 +65,15 @@ actual fun CustomImage(
shouldBeRendered = true
},
) {
Text(text = stringResource(MR.strings.button_load))
if (loadButtonContent != null) {
loadButtonContent?.invoke()
} else {
Text(
text = stringResource(MR.strings.button_load),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
}

View File

@ -296,6 +296,9 @@ class CommunityDetailScreen(
},
)
}
item {
Spacer(modifier = Modifier.height(Spacing.m))
}
if (uiState.posts.isEmpty() && uiState.loading) {
items(5) {
PostCardPlaceholder(

View File

@ -24,7 +24,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
fun CommunityAndCreatorInfo(
modifier: Modifier = Modifier,
autoLoadImages: Boolean = true,
small: Boolean = false,
community: CommunityModel? = null,
creator: UserModel? = null,
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
@ -36,14 +35,15 @@ fun CommunityAndCreatorInfo(
val creatorName = creator?.name.orEmpty()
val creatorAvatar = creator?.avatar.orEmpty()
val creatorHost = creator?.host.orEmpty()
val iconSize = if (small) 20.dp else 32.dp
val iconSize = 32.dp
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(Spacing.s)
) {
if (communityIcon.isNotEmpty() && autoLoadImages) {
if (communityIcon.isNotEmpty()) {
if (autoLoadImages) {
CustomImage(
modifier = Modifier
.onClick {
@ -59,7 +59,19 @@ fun CommunityAndCreatorInfo(
contentDescription = null,
contentScale = ContentScale.FillBounds,
)
} else if (creatorAvatar.isNotEmpty() && autoLoadImages) {
} else {
PlaceholderImage(
modifier = Modifier.onClick {
if (community != null) {
onOpenCommunity?.invoke(community)
}
},
size = 32.dp,
title = communityName,
)
}
} else if (creatorAvatar.isNotEmpty()) {
if (autoLoadImages) {
CustomImage(
modifier = Modifier
.onClick {
@ -75,6 +87,17 @@ fun CommunityAndCreatorInfo(
contentDescription = null,
contentScale = ContentScale.FillBounds,
)
} else {
PlaceholderImage(
modifier = Modifier.onClick {
if (creator != null) {
onOpenCreator?.invoke(creator)
}
},
size = iconSize,
title = creatorName,
)
}
}
Column(
modifier = Modifier.padding(vertical = Spacing.xxxs),

View File

@ -1,6 +1,5 @@
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
@ -125,20 +124,11 @@ fun CommunityHeader(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier.padding(Spacing.xxxs).size(avatarSize).background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(avatarSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = community.name.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
PlaceholderImage(
size = avatarSize,
title = community.name,
)
}
}
// textual data
Column(

View File

@ -1,8 +1,6 @@
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.padding
@ -50,21 +48,11 @@ fun CommunityItem(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier.padding(Spacing.xxxs).size(iconSize)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(iconSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = community.name.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
PlaceholderImage(
size = iconSize,
title = community.name,
)
}
}
Column(
modifier = Modifier.padding(start = Spacing.xs),
) {
@ -88,3 +76,5 @@ fun CommunityItem(
}
}
}

View File

@ -1,8 +1,6 @@
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.padding
@ -46,21 +44,11 @@ fun MultiCommunityItem(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier.padding(Spacing.xxxs).size(iconSize)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(iconSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = title.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
PlaceholderImage(
size = iconSize,
title = title,
)
}
}
Column(
modifier = Modifier.padding(start = Spacing.xs),
) {

View File

@ -0,0 +1,38 @@
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
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.unit.Dp
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
@Composable
fun PlaceholderImage(
modifier: Modifier = Modifier,
size: Dp,
title: String,
) {
Box(
modifier = modifier
.padding(Spacing.xxxs)
.size(size)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(size / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = title.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
)
}
}

View File

@ -10,6 +10,9 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Download
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
@ -146,7 +149,6 @@ private fun CompactPost(
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
) {
CommunityAndCreatorInfo(
small = true,
community = post.community,
creator = post.creator.takeIf { !hideAuthor },
onOpenCommunity = onOpenCommunity,
@ -163,6 +165,9 @@ private fun CompactPost(
maxHeight = Dp.Unspecified,
imageUrl = post.imageUrl,
autoLoadImages = autoLoadImages,
loadButtonContent = @Composable {
Icon(imageVector = Icons.Default.Download, contentDescription = null)
},
blurred = blurNsfw && post.nsfw,
onImageClick = onImageClick,
)

View File

@ -26,6 +26,7 @@ fun PostCardImage(
modifier: Modifier = Modifier,
imageUrl: String,
autoLoadImages: Boolean = true,
loadButtonContent: @Composable (() -> Unit)? = null,
minHeight: Dp = 200.dp,
maxHeight: Dp = Dp.Unspecified,
blurred: Boolean = false,
@ -41,6 +42,7 @@ fun PostCardImage(
},
url = imageUrl,
autoload = autoLoadImages,
loadButtonContent = loadButtonContent,
contentDescription = null,
contentScale = ContentScale.FillWidth,
onFailure = {

View File

@ -1,6 +1,5 @@
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
@ -133,25 +132,11 @@ fun UserHeader(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier
.padding(Spacing.xxxs)
.size(avatarSize)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(avatarSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = user.name.firstOrNull()?.toString()
.orEmpty()
.uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
PlaceholderImage(
size = avatarSize,
title = user.name,
)
}
}
// textual data
Column(

View File

@ -1,8 +1,6 @@
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.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@ -47,21 +45,11 @@ fun UserItem(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier.padding(Spacing.xxxs).size(iconSize)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(iconSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = name.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
PlaceholderImage(
size = iconSize,
title = name,
)
}
}
Text(
text = buildString {

View File

@ -64,6 +64,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycl
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityItem
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.MultiCommunityItem
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PlaceholderImage
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getModalDrawerViewModel
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
@ -255,20 +256,11 @@ private fun DrawerHeader(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier.padding(Spacing.xxxs).size(avatarSize).background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(avatarSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = user.name.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground,
PlaceholderImage(
size = avatarSize,
title = user.name,
)
}
}
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
@ -298,19 +290,10 @@ private fun DrawerHeader(
}
} else {
val anonymousTitle = stringResource(MR.strings.navigation_drawer_anonymous)
Box(
modifier = Modifier.padding(Spacing.xxxs).size(avatarSize).background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(avatarSize / 2),
),
contentAlignment = Alignment.Center,
) {
Text(
text = anonymousTitle.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
PlaceholderImage(
size = avatarSize,
title = anonymousTitle,
)
}
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.xxxs),
) {

View File

@ -241,6 +241,7 @@ class UserDetailScreen(
) {
UserHeader(
user = uiState.user,
autoLoadImages = uiState.autoLoadImages,
options = listOf(stringResource(MR.strings.community_detail_block)),
onOpenImage = { url ->
navigator?.push(ZoomableImageScreen(url))

View File

@ -1,8 +1,6 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
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.padding
@ -23,6 +21,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PlaceholderImage
import com.github.diegoberaldin.raccoonforlemmy.core.utils.DateTime
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
@ -71,27 +70,16 @@ internal fun ChatCard(
contentScale = ContentScale.FillBounds,
)
} else {
Box(
modifier = Modifier
.padding(Spacing.xxxs)
.size(iconSize)
.background(
color = MaterialTheme.colorScheme.primary,
shape = RoundedCornerShape(iconSize / 2),
).onClick {
PlaceholderImage(
modifier = Modifier.onClick {
if (user != null) {
onOpenUser?.invoke(user)
}
},
contentAlignment = Alignment.Center,
) {
Text(
text = creatorName.firstOrNull()?.toString().orEmpty().uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onPrimary,
size = iconSize,
title = creatorName,
)
}
}
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.xxs)

View File

@ -96,6 +96,7 @@ internal object ProfileLoggedScreen : Tab {
) {
UserHeader(
user = user,
autoLoadImages = uiState.autoLoadImages,
onOpenImage = { url ->
navigator?.push(ZoomableImageScreen(url))
},