Merge branch 'main' into main

This commit is contained in:
greenart7c3
2024-03-25 17:34:22 -03:00
committed by GitHub
13 changed files with 95 additions and 64 deletions
@@ -972,8 +972,6 @@ class NoteLiveSet(u: Note) {
val relays = innerRelays.map { it } val relays = innerRelays.map { it }
val zaps = innerZaps.map { it } val zaps = innerZaps.map { it }
val authorChanges = innerMetadata.map { it.note.author }.distinctUntilChanged()
val hasEvent = innerMetadata.map { it.note.event != null }.distinctUntilChanged() val hasEvent = innerMetadata.map { it.note.event != null }.distinctUntilChanged()
val hasReactions = val hasReactions =
@@ -1011,7 +1009,6 @@ class NoteLiveSet(u: Note) {
reports.hasObservers() || reports.hasObservers() ||
relays.hasObservers() || relays.hasObservers() ||
zaps.hasObservers() || zaps.hasObservers() ||
authorChanges.hasObservers() ||
hasEvent.hasObservers() || hasEvent.hasObservers() ||
hasReactions.hasObservers() || hasReactions.hasObservers() ||
replyCount.hasObservers() || replyCount.hasObservers() ||
@@ -853,9 +853,7 @@ fun Gallery(
@Composable @Composable
fun DisplayAuthorBanner(note: Note) { fun DisplayAuthorBanner(note: Note) {
val authorState by note.live().authorChanges.observeAsState(note.author) WatchAuthor(note) {
BannerImage(it, Modifier.fillMaxSize().clip(QuoteBorder))
authorState?.let { author ->
BannerImage(author, Modifier.fillMaxSize().clip(QuoteBorder))
} }
} }
@@ -84,13 +84,16 @@ fun ChatroomHeaderCompose(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
if (baseNote.event != null) {
ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav)
} else {
val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null) val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null)
if (hasEvent) { if (hasEvent) {
ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav) ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav)
} else { } else {
BlankNote() BlankNote()
} }
}
} }
@Composable @Composable
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.note
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@@ -142,11 +143,6 @@ fun HashCheckFailedIcon(iconSize: Dp) {
) )
} }
@Composable
fun LikedIcon(iconSize: Dp) {
LikedIcon(modifier = remember(iconSize) { Modifier.size(iconSize) })
}
@Composable @Composable
fun LikedIcon(modifier: Modifier) { fun LikedIcon(modifier: Modifier) {
Icon( Icon(
@@ -206,6 +202,18 @@ fun ZappedIcon(modifier: Modifier) {
ZapIcon(modifier = modifier, BitcoinOrange) ZapIcon(modifier = modifier, BitcoinOrange)
} }
@Preview
@Composable
fun ReactionRowIconPreview() {
Row(verticalAlignment = Alignment.CenterVertically) {
CommentIcon(Size20Modifier, Color.Unspecified)
RepostedIcon(Size20Modifier)
LikeIcon(Size20Modifier, Color.Unspecified)
ZapIcon(Size20Modifier)
ZappedIcon(Size20Modifier)
}
}
@Composable @Composable
fun ZapIcon( fun ZapIcon(
modifier: Modifier, modifier: Modifier,
@@ -20,7 +20,6 @@
*/ */
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -76,8 +75,8 @@ import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifier import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifier
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifierSmaller import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifierSmaller
import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size18dp
import com.vitorpamplona.amethyst.ui.theme.Size19dp import com.vitorpamplona.amethyst.ui.theme.Size19dp
import com.vitorpamplona.amethyst.ui.theme.Size20dp
import com.vitorpamplona.amethyst.ui.theme.Size25dp import com.vitorpamplona.amethyst.ui.theme.Size25dp
import com.vitorpamplona.amethyst.ui.theme.Size35Modifier import com.vitorpamplona.amethyst.ui.theme.Size35Modifier
import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.Size35dp
@@ -223,7 +222,7 @@ fun RenderLikeGallery(
) )
} else { } else {
when (val shortReaction = reactionType) { when (val shortReaction = reactionType) {
"+" -> LikedIcon(modifier.size(Size18dp)) "+" -> LikedIcon(modifier.size(Size19dp))
"-" -> Text(text = "\uD83D\uDC4E", modifier = modifier) "-" -> Text(text = "\uD83D\uDC4E", modifier = modifier)
else -> Text(text = shortReaction, modifier = modifier) else -> Text(text = shortReaction, modifier = modifier)
} }
@@ -268,7 +267,7 @@ fun RenderBoostGallery(
modifier = NotificationIconModifierSmaller, modifier = NotificationIconModifierSmaller,
) { ) {
RepostedIcon( RepostedIcon(
modifier = remember { Modifier.size(Size19dp).align(Alignment.TopEnd) }, modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
) )
} }
@@ -289,7 +288,7 @@ fun RenderBoostGallery(
modifier = NotificationIconModifierSmaller, modifier = NotificationIconModifierSmaller,
) { ) {
RepostedIcon( RepostedIcon(
modifier = remember { Modifier.size(Size19dp).align(Alignment.TopEnd) }, modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
) )
} }
@@ -494,15 +493,13 @@ private fun BoxedAuthor(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
Box(modifier = Size35Modifier.clickable(onClick = { nav(authorRouteFor(note)) })) { Box(modifier = Size35Modifier.clickable(onClick = { nav(authorRouteFor(note)) })) {
WatchNoteAuthor(note) { targetAuthor -> WatchAuthorWithBlank(note, Size35Modifier) { author ->
Crossfade(targetState = targetAuthor, modifier = Size35Modifier) { author ->
WatchUserMetadataAndFollowsAndRenderUserProfilePictureOrDefaultAuthor( WatchUserMetadataAndFollowsAndRenderUserProfilePictureOrDefaultAuthor(
author, author,
accountViewModel, accountViewModel,
) )
} }
} }
}
} }
@Composable @Composable
@@ -546,16 +543,6 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture(
} }
} }
@Composable
private fun WatchNoteAuthor(
baseNote: Note,
onContent: @Composable (User?) -> Unit,
) {
val author by baseNote.live().authorChanges.observeAsState(baseNote.author)
onContent(author)
}
@Composable @Composable
private fun WatchUserMetadata( private fun WatchUserMetadata(
author: User, author: User,
@@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.ui.note.LoadStatuses
import com.vitorpamplona.amethyst.ui.note.NIP05CheckingIcon import com.vitorpamplona.amethyst.ui.note.NIP05CheckingIcon
import com.vitorpamplona.amethyst.ui.note.NIP05FailedVerification import com.vitorpamplona.amethyst.ui.note.NIP05FailedVerification
import com.vitorpamplona.amethyst.ui.note.NIP05VerifiedIcon import com.vitorpamplona.amethyst.ui.note.NIP05VerifiedIcon
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize
@@ -116,9 +117,9 @@ fun ObserveDisplayNip05Status(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
val author by baseNote.live().authorChanges.observeAsState() WatchAuthor(baseNote = baseNote) {
ObserveDisplayNip05Status(it, columnModifier, accountViewModel, nav)
author?.let { ObserveDisplayNip05Status(it, columnModifier, accountViewModel, nav) } }
} }
@Composable @Composable
@@ -99,7 +99,6 @@ import coil.request.CachePolicy
import coil.request.ImageRequest import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.zap
import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.ZapPaymentHandler
import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.components.GenericLoadable
@@ -111,13 +110,13 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DarkerGreen import com.vitorpamplona.amethyst.ui.theme.DarkerGreen
import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
import com.vitorpamplona.amethyst.ui.theme.Height24dpModifier import com.vitorpamplona.amethyst.ui.theme.Height24dpModifier
import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp
import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders
import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton
import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeight import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeight
import com.vitorpamplona.amethyst.ui.theme.ReactionRowZapraiserSize import com.vitorpamplona.amethyst.ui.theme.ReactionRowZapraiserSize
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
import com.vitorpamplona.amethyst.ui.theme.Size0dp import com.vitorpamplona.amethyst.ui.theme.Size0dp
import com.vitorpamplona.amethyst.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.ui.theme.Size16Modifier
import com.vitorpamplona.amethyst.ui.theme.Size17Modifier import com.vitorpamplona.amethyst.ui.theme.Size17Modifier
@@ -229,7 +228,11 @@ private fun GenericInnerReactionRow(
five: @Composable () -> Unit, five: @Composable () -> Unit,
six: @Composable () -> Unit, six: @Composable () -> Unit,
) { ) {
Row(verticalAlignment = CenterVertically, modifier = ReactionRowHeight) { Row(
verticalAlignment = CenterVertically,
horizontalArrangement = RowColSpacing,
modifier = ReactionRowHeight,
) {
val fullWeight = remember { Modifier.weight(1f) } val fullWeight = remember { Modifier.weight(1f) }
if (showReactionDetail) { if (showReactionDetail) {
@@ -241,11 +244,11 @@ private fun GenericInnerReactionRow(
} }
} }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { two() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { two() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { three() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { three() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { four() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { four() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { five() } Row(verticalAlignment = CenterVertically, modifier = fullWeight) { five() }
@@ -670,7 +673,6 @@ fun TextCount(
text = showCount(count), text = showCount(count),
fontSize = Font14SP, fontSize = Font14SP,
color = textColor, color = textColor,
modifier = HalfStartPadding,
maxLines = 1, maxLines = 1,
) )
} }
@@ -21,7 +21,6 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@@ -77,9 +76,7 @@ fun NoteAuthorPicture(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: ((User) -> Unit)? = null, onClick: ((User) -> Unit)? = null,
) { ) {
val author by baseNote.live().authorChanges.observeAsState(baseNote.author) WatchAuthorWithBlank(baseNote) {
Crossfade(targetState = author, label = "NoteAuthorPicture") {
if (it == null) { if (it == null) {
DisplayBlankAuthor(size, modifier) DisplayBlankAuthor(size, modifier)
} else { } else {
@@ -52,10 +52,43 @@ fun NoteUsernameDisplay(
showPlayButton: Boolean = true, showPlayButton: Boolean = true,
textColor: Color = Color.Unspecified, textColor: Color = Color.Unspecified,
) { ) {
val authorState by baseNote.live().authorChanges.observeAsState(baseNote.author) WatchAuthor(baseNote) {
UsernameDisplay(it, weight, showPlayButton, textColor = textColor)
}
}
Crossfade(targetState = authorState, modifier = weight, label = "NoteUsernameDisplay") { @Composable
it?.let { UsernameDisplay(it, weight, showPlayButton, textColor = textColor) } fun WatchAuthor(
baseNote: Note,
inner: @Composable (User) -> Unit,
) {
val noteAuthor = baseNote.author
if (noteAuthor != null) {
inner(noteAuthor)
} else {
val authorState by baseNote.live().metadata.observeAsState()
authorState?.note?.author?.let {
inner(it)
}
}
}
@Composable
fun WatchAuthorWithBlank(
baseNote: Note,
modifier: Modifier = Modifier,
inner: @Composable (User?) -> Unit,
) {
val noteAuthor = baseNote.author
if (noteAuthor != null) {
inner(noteAuthor)
} else {
val authorState by baseNote.live().metadata.observeAsState()
Crossfade(targetState = authorState?.note?.author, modifier = modifier, label = "WatchAuthorWithBlank") { newAuthor ->
inner(newAuthor)
}
} }
} }
@@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader
@@ -47,14 +48,12 @@ fun DefaultImageHeader(
note: Note, note: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
val authorState by note.live().authorChanges.observeAsState(note.author) WatchAuthor(baseNote = note) {
authorState?.let { author ->
Box { Box {
BannerImage(author) BannerImage(it)
Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) { Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) {
BaseUserPicture(author, Size55dp, accountViewModel, Modifier) BaseUserPicture(it, Size55dp, accountViewModel, Modifier)
} }
} }
} }
@@ -99,6 +99,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size39Modifier
import com.vitorpamplona.amethyst.ui.theme.Size40Modifier import com.vitorpamplona.amethyst.ui.theme.Size40Modifier
import com.vitorpamplona.amethyst.ui.theme.Size40dp import com.vitorpamplona.amethyst.ui.theme.Size40dp
import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.VideoReactionColumnPadding
import com.vitorpamplona.amethyst.ui.theme.onBackgroundColorFilter import com.vitorpamplona.amethyst.ui.theme.onBackgroundColorFilter
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.FileHeaderEvent import com.vitorpamplona.quartz.events.FileHeaderEvent
@@ -462,7 +463,7 @@ fun ReactionsColumn(
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(bottom = 75.dp, end = 10.dp), modifier = VideoReactionColumnPadding,
) { ) {
ReplyReaction( ReplyReaction(
baseNote = baseNote, baseNote = baseNote,
@@ -495,7 +496,7 @@ fun ReactionsColumn(
nav = nav, nav = nav,
iconSize = Size40dp, iconSize = Size40dp,
heartSizeModifier = Size35Modifier, heartSizeModifier = Size35Modifier,
28.sp, iconFontSize = 28.sp,
) )
ZapReaction( ZapReaction(
baseNote = baseNote, baseNote = baseNote,
@@ -21,6 +21,7 @@
package com.vitorpamplona.amethyst.ui.theme package com.vitorpamplona.amethyst.ui.theme
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -102,6 +103,8 @@ val HalfPadding = Modifier.padding(5.dp)
val StdPadding = Modifier.padding(10.dp) val StdPadding = Modifier.padding(10.dp)
val BigPadding = Modifier.padding(15.dp) val BigPadding = Modifier.padding(15.dp)
val RowColSpacing = Arrangement.spacedBy(3.dp)
val HalfHorzPadding = Modifier.padding(horizontal = 5.dp) val HalfHorzPadding = Modifier.padding(horizontal = 5.dp)
val HalfVertPadding = Modifier.padding(vertical = 5.dp) val HalfVertPadding = Modifier.padding(vertical = 5.dp)
@@ -137,6 +140,8 @@ val ReactionRowExpandButton = Modifier.width(65.dp).padding(start = 31.dp)
val WidthAuthorPictureModifier = Modifier.width(55.dp) val WidthAuthorPictureModifier = Modifier.width(55.dp)
val WidthAuthorPictureModifierWithPadding = Modifier.width(65.dp) val WidthAuthorPictureModifierWithPadding = Modifier.width(65.dp)
val VideoReactionColumnPadding = Modifier.padding(bottom = 75.dp)
val DividerThickness = 0.25.dp val DividerThickness = 0.25.dp
val ReactionRowHeight = Modifier.height(24.dp).padding(start = 10.dp) val ReactionRowHeight = Modifier.height(24.dp).padding(start = 10.dp)
@@ -224,4 +229,4 @@ val liveStreamTag =
.padding(horizontal = Size5dp) .padding(horizontal = Size5dp)
val chatAuthorImage = Modifier.size(20.dp).clip(shape = CircleShape) val chatAuthorImage = Modifier.size(20.dp).clip(shape = CircleShape)
val AuthorInfoVideoFeed = Modifier.width(75.dp) val AuthorInfoVideoFeed = Modifier.width(75.dp).padding(end = 15.dp)
+1 -1
View File
@@ -12,7 +12,7 @@ benchmarkJunit4 = "1.2.3"
biometricKtx = "1.2.0-alpha05" biometricKtx = "1.2.0-alpha05"
blurhash = "1.0.0" blurhash = "1.0.0"
coil = "2.6.0" coil = "2.6.0"
composeBom = "2024.02.02" composeBom = "2024.03.00"
coreKtx = "1.12.0" coreKtx = "1.12.0"
espressoCore = "3.5.1" espressoCore = "3.5.1"
firebaseBom = "32.7.4" firebaseBom = "32.7.4"