mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-01 00:18:30 +02:00
Improves the design of the discovery cards for Live Activity and Chats.
This commit is contained in:
parent
77eb066362
commit
abef3d13f2
@ -0,0 +1,139 @@
|
||||
package com.vitorpamplona.amethyst.ui.layouts
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
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.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.note.LikeIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.TextCount
|
||||
import com.vitorpamplona.amethyst.ui.note.ZappedIcon
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size16Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparison
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun LeftPictureLayoutPreview() {
|
||||
ThemeComparison(
|
||||
onDark = { LeftPictureLayoutPreviewCard() },
|
||||
onLight = { LeftPictureLayoutPreviewCard() }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LeftPictureLayoutPreviewCard() {
|
||||
LeftPictureLayout(
|
||||
onImage = {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.github),
|
||||
contentDescription = stringResource(id = R.string.profile_banner),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clip(QuoteBorder)
|
||||
)
|
||||
},
|
||||
onTitleRow = {
|
||||
Text(
|
||||
text = "This is my title",
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
LikeIcon(
|
||||
iconSizeModifier = Size16Modifier,
|
||||
grayTint = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
TextCount(12, MaterialTheme.colorScheme.onSurface)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
ZappedIcon(Size20Modifier)
|
||||
TextCount(120, MaterialTheme.colorScheme.onSurface)
|
||||
},
|
||||
onDescription = {
|
||||
Text(
|
||||
"This is 3-line description, This is 3-line description, This is 3-line description, This is 3-line description",
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
},
|
||||
onBottomRow = {
|
||||
Text("This is my Moderator List")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LeftPictureLayout(
|
||||
onImage: @Composable () -> Unit,
|
||||
onTitleRow: @Composable RowScope.() -> Unit,
|
||||
onDescription: @Composable () -> Unit,
|
||||
onBottomRow: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
Row(Modifier.aspectRatio(ratio = 4f)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.25f)
|
||||
.aspectRatio(ratio = 1f)
|
||||
) {
|
||||
onImage()
|
||||
}
|
||||
|
||||
Spacer(modifier = DoubleHorzSpacer)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
onTitleRow()
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
) {
|
||||
onDescription()
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
onBottomRow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -32,7 +31,6 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.BottomStart
|
||||
import androidx.compose.ui.Alignment.Companion.TopEnd
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -54,6 +52,7 @@ import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.ParticipantListBuilder
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
import com.vitorpamplona.amethyst.ui.layouts.LeftPictureLayout
|
||||
import com.vitorpamplona.amethyst.ui.screen.equalImmutableLists
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader
|
||||
@ -64,7 +63,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.OfflineFlag
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ScheduledFlag
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
|
||||
@ -689,12 +687,8 @@ fun RenderCommunitiesThumb(baseNote: Note, accountViewModel: AccountViewModel, n
|
||||
)
|
||||
)
|
||||
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.3f)
|
||||
.aspectRatio(ratio = 1f)
|
||||
) {
|
||||
LeftPictureLayout(
|
||||
onImage = {
|
||||
card.cover?.let {
|
||||
Box(contentAlignment = BottomStart) {
|
||||
AsyncImage(
|
||||
@ -711,29 +705,22 @@ fun RenderCommunitiesThumb(baseNote: Note, accountViewModel: AccountViewModel, n
|
||||
DisplayAuthorBanner(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = DoubleHorzSpacer)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = card.name,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
LikeReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
ZapReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav = nav)
|
||||
}
|
||||
},
|
||||
onTitleRow = {
|
||||
Text(
|
||||
text = card.name,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
LikeReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
ZapReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav = nav)
|
||||
},
|
||||
onDescription = {
|
||||
card.description?.let {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Row() {
|
||||
@ -746,17 +733,16 @@ fun RenderCommunitiesThumb(baseNote: Note, accountViewModel: AccountViewModel, n
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
onBottomRow = {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
LoadModerators(card.moderators, baseNote, accountViewModel) { participantUsers ->
|
||||
if (participantUsers.isNotEmpty()) {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Row(modifier = Modifier.fillMaxWidth()) {
|
||||
Gallery(participantUsers, accountViewModel)
|
||||
}
|
||||
Gallery(participantUsers, accountViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -901,12 +887,8 @@ fun RenderChannelThumb(baseNote: Note, channel: Channel, accountViewModel: Accou
|
||||
}
|
||||
}
|
||||
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.3f)
|
||||
.aspectRatio(ratio = 1f)
|
||||
) {
|
||||
LeftPictureLayout(
|
||||
onImage = {
|
||||
cover?.let {
|
||||
Box(contentAlignment = BottomStart) {
|
||||
AsyncImage(
|
||||
@ -923,43 +905,33 @@ fun RenderChannelThumb(baseNote: Note, channel: Channel, accountViewModel: Accou
|
||||
DisplayAuthorBanner(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = DoubleHorzSpacer)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight()
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = name,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
LikeReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
ZapReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav = nav)
|
||||
}
|
||||
},
|
||||
onTitleRow = {
|
||||
Text(
|
||||
text = name,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
LikeReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
ZapReaction(baseNote = baseNote, grayTint = MaterialTheme.colorScheme.onSurface, accountViewModel = accountViewModel, nav = nav)
|
||||
},
|
||||
onDescription = {
|
||||
description?.let {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Row() {
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
|
||||
},
|
||||
onBottomRow = {
|
||||
if (participantUsers.isNotEmpty()) {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Row() {
|
||||
@ -967,7 +939,7 @@ fun RenderChannelThumb(baseNote: Note, channel: Channel, accountViewModel: Accou
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@ -980,7 +952,7 @@ fun Gallery(users: ImmutableList<User>, accountViewModel: AccountViewModel) {
|
||||
|
||||
if (users.size > 6) {
|
||||
Text(
|
||||
text = remember(users) { " + " + (showCount(users.size - 6)).toString() },
|
||||
text = remember(users) { " + " + (showCount(users.size - 6)) },
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
|
@ -594,7 +594,7 @@ val slideAnimation: ContentTransform =
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun TextCount(count: Int, textColor: Color) {
|
||||
fun TextCount(count: Int, textColor: Color) {
|
||||
Text(
|
||||
text = showCount(count),
|
||||
fontSize = Font14SP,
|
||||
|
@ -29,8 +29,13 @@ class LiveActivitiesEvent(
|
||||
|
||||
fun participants() = tags.filter { it.size > 1 && it[0] == "p" }.map { Participant(it[1], it.getOrNull(3)) }
|
||||
|
||||
fun hasHost() = tags.any { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }
|
||||
|
||||
fun host() = tags.firstOrNull { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }?.get(1)
|
||||
|
||||
fun hosts() = tags.filter { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }.map { it[1] }
|
||||
|
||||
|
||||
fun checkStatus(eventStatus: String?): String? {
|
||||
return if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) {
|
||||
STATUS_ENDED
|
||||
|
Loading…
x
Reference in New Issue
Block a user