Moving Picture and Display Name Observables to leaf UI nodes.

This commit is contained in:
Vitor Pamplona
2023-01-31 22:12:24 -03:00
parent 94a4bfc2f3
commit 814fb1845f
9 changed files with 175 additions and 133 deletions
@@ -76,21 +76,14 @@ fun BoostSetCompose(likeSetCard: BoostSetCard, isInnerNote: Boolean = false, rou
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) { Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
FlowRow() { FlowRow() {
likeSetCard.boostEvents.forEach { likeSetCard.boostEvents.forEach {
val cardNoteState by it.live.observeAsState() NoteAuthorPicture(
val cardNote = cardNoteState?.note note = it,
if (cardNote?.author != null) {
val userState by cardNote.author!!.live.observeAsState()
UserPicture(
user = userState?.user,
navController = navController, navController = navController,
userAccount = account.userProfile(), userAccount = account.userProfile(),
size = 35.dp size = 35.dp
) )
} }
} }
}
NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController) NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController)
} }
@@ -134,7 +134,7 @@ fun ChatroomCompose(baseNote: Note, accountViewModel: AccountViewModel, navContr
false false
ChannelName( ChannelName(
channelPicture = { UserPicture(user = user, userAccount = accountUser, size = 55.dp) }, channelPicture = { UserPicture(user, accountUser, size = 55.dp) },
channelTitle = { UsernameDisplay(user, it) }, channelTitle = { UsernameDisplay(user, it) },
channelLastTime = noteEvent?.createdAt, channelLastTime = noteEvent?.createdAt,
channelLastContent = accountViewModel.decrypt(note), channelLastContent = accountViewModel.decrypt(note),
@@ -76,21 +76,14 @@ fun LikeSetCompose(likeSetCard: LikeSetCard, modifier: Modifier = Modifier, isIn
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) { Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
FlowRow() { FlowRow() {
likeSetCard.likeEvents.forEach { likeSetCard.likeEvents.forEach {
val cardNoteState by it.live.observeAsState() NoteAuthorPicture(
val cardNote = cardNoteState?.note note = it,
if (cardNote?.author != null) {
val userState by cardNote.author!!.live.observeAsState()
UserPicture(
user = userState?.user,
navController = navController, navController = navController,
userAccount = account.userProfile(), userAccount = account.userProfile(),
size = 35.dp size = 35.dp
) )
} }
} }
}
NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController) NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController)
} }
@@ -95,9 +95,6 @@ fun NoteCompose(
onLongClick = { popupExpanded = true }, onLongClick = { popupExpanded = true },
), isInnerNote) ), isInnerNote)
} else { } else {
val authorState by note.author?.live!!.observeAsState()
val author = authorState?.user ?: return // if it has event, it should have an author
val isNew = routeForLastRead?.run { val isNew = routeForLastRead?.run {
val lastTime = NotificationCache.load(this, context) val lastTime = NotificationCache.load(this, context)
@@ -145,22 +142,22 @@ fun NoteCompose(
Box(modifier = Modifier Box(modifier = Modifier
.width(55.dp) .width(55.dp)
.padding(0.dp)) { .padding(0.dp)) {
UserPicture(author, navController, account.userProfile(), 55.dp)
// boosted picture NoteAuthorPicture(note, navController, account.userProfile(), 55.dp)
val boostedPosts = note.replyTo
if (note.event is RepostEvent && boostedPosts != null && boostedPosts.isNotEmpty()) { if (note.event is RepostEvent) {
val boostedAuthor = boostedPosts[0].author note.replyTo?.lastOrNull()?.let {
Box( Box(
Modifier Modifier
.width(30.dp) .width(30.dp)
.height(30.dp) .height(30.dp)
.align(Alignment.BottomEnd)) { .align(Alignment.BottomEnd)) {
UserPicture(boostedAuthor, navController, account.userProfile(), 35.dp, NoteAuthorPicture(it, navController, account.userProfile(), 35.dp,
pictureModifier = Modifier.border(2.dp, MaterialTheme.colors.background, CircleShape) pictureModifier = Modifier.border(2.dp, MaterialTheme.colors.background, CircleShape)
) )
} }
} }
}
// boosted picture // boosted picture
val baseChannel = note.channel val baseChannel = note.channel
@@ -197,8 +194,7 @@ fun NoteCompose(
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) { Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null) NoteUsernameDisplay(note, Modifier.weight(1f))
UsernameDisplay(author, Modifier.weight(1f))
if (note.event !is RepostEvent) { if (note.event !is RepostEvent) {
Text( Text(
@@ -274,40 +270,42 @@ fun NoteCompose(
} }
} }
@Composable @Composable
fun UserPicture( fun NoteAuthorPicture(
user: User?, note: Note,
navController: NavController, navController: NavController,
userAccount: User, userAccount: User,
size: Dp, size: Dp,
pictureModifier: Modifier = Modifier pictureModifier: Modifier = Modifier
) { ) {
UserPicture(user, userAccount, size, pictureModifier) { NoteAuthorPicture(note, userAccount, size, pictureModifier) {
user?.let {
navController.navigate("User/${it.pubkeyHex}") navController.navigate("User/${it.pubkeyHex}")
} }
} }
}
@Composable @Composable
fun UserPicture( fun NoteAuthorPicture(
user: User?, baseNote: Note,
userAccount: User, baseUserAccount: User,
size: Dp, size: Dp,
pictureModifier: Modifier = Modifier, pictureModifier: Modifier = Modifier,
onClick: (() -> Unit)? = null onClick: ((User) -> Unit)? = null
) { ) {
val accountState by userAccount.live.observeAsState() val noteState by baseNote.live.observeAsState()
val accountUser = accountState?.user ?: return val note = noteState?.note ?: return
val author = note.author
Box( Box(
Modifier Modifier
.width(size) .width(size)
.height(size)) { .height(size)) {
if (user == null) { if (author == null) {
AsyncImage( AsyncImage(
model = "https://robohash.org/ohno.png", model = "https://robohash.org/ohno.png",
contentDescription = "Profile Image", contentDescription = "Unknown Author",
placeholder = rememberAsyncImagePainter("https://robohash.org/ohno.png"), placeholder = rememberAsyncImagePainter("https://robohash.org/ohno.png"),
modifier = pictureModifier modifier = pictureModifier
.fillMaxSize(1f) .fillMaxSize(1f)
@@ -315,27 +313,61 @@ fun UserPicture(
.background(MaterialTheme.colors.background) .background(MaterialTheme.colors.background)
) )
} else { } else {
val userState by user.live.observeAsState() UserPicture(author, baseUserAccount, size, pictureModifier, onClick)
val userLive = userState?.user ?: return }
}
}
@Composable
fun UserPicture(
user: User,
navController: NavController,
userAccount: User,
size: Dp,
pictureModifier: Modifier = Modifier
) {
UserPicture(user, userAccount, size, pictureModifier) {
navController.navigate("User/${it.pubkeyHex}")
}
}
@Composable
fun UserPicture(
baseUser: User,
baseUserAccount: User,
size: Dp,
pictureModifier: Modifier = Modifier,
onClick: ((User) -> Unit)? = null
) {
val accountState by baseUserAccount.live.observeAsState()
val accountUser = accountState?.user ?: return
val userState by baseUser.live.observeAsState()
val user = userState?.user ?: return
Box(
Modifier
.width(size)
.height(size)) {
AsyncImage( AsyncImage(
model = userLive.profilePicture(), model = user.profilePicture(),
contentDescription = "Profile Image", contentDescription = "Profile Image",
placeholder = rememberAsyncImagePainter("https://robohash.org/${userLive.pubkeyHex}.png"), placeholder = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
modifier = pictureModifier modifier = pictureModifier
.fillMaxSize(1f) .fillMaxSize(1f)
.clip(shape = CircleShape) .clip(shape = CircleShape)
.background(MaterialTheme.colors.background) .background(MaterialTheme.colors.background)
.run { .run {
if (onClick != null) if (onClick != null)
this.clickable(onClick = onClick) this.clickable(onClick = { onClick(user) } )
else else
this this
} }
) )
if (accountUser.isFollowing(userLive) || userLive == accountUser) { if (accountUser.isFollowing(user) || user == accountUser) {
Box( Box(
Modifier Modifier
.width(size.div(3.5f)) .width(size.div(3.5f))
@@ -362,7 +394,7 @@ fun UserPicture(
) )
} }
} }
}
} }
} }
@@ -52,11 +52,11 @@ fun UserCompose(baseUser: User, accountViewModel: AccountViewModel, navControlle
top = 10.dp) top = 10.dp)
) { ) {
UserPicture(user, navController, account.userProfile(), 55.dp) UserPicture(baseUser, navController, account.userProfile(), 55.dp)
Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) { Column(modifier = Modifier.padding(start = 10.dp).weight(1f)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
UsernameDisplay(user) UsernameDisplay(baseUser)
} }
Text( Text(
@@ -3,13 +3,32 @@ package com.vitorpamplona.amethyst.ui.note
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
@Composable @Composable
fun UsernameDisplay(user: User, weight: Modifier = Modifier) { fun NoteUsernameDisplay(baseNote: Note, weight: Modifier = Modifier) {
val noteState by baseNote.live.observeAsState()
val note = noteState?.note ?: return
val author = note.author
if (author != null) {
UsernameDisplay(author, weight)
}
}
@Composable
fun UsernameDisplay(baseUser: User, weight: Modifier = Modifier) {
val userState by baseUser.live.observeAsState()
val user = userState?.user ?: return
if (user.bestUsername() != null || user.bestDisplayName() != null) { if (user.bestUsername() != null || user.bestDisplayName() != null) {
if (user.bestDisplayName().isNullOrBlank()) { if (user.bestDisplayName().isNullOrBlank()) {
Text( Text(
@@ -41,7 +41,9 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.components.RichTextViewer import com.vitorpamplona.amethyst.ui.components.RichTextViewer
import com.vitorpamplona.amethyst.ui.note.BlankNote import com.vitorpamplona.amethyst.ui.note.BlankNote
import com.vitorpamplona.amethyst.ui.note.HiddenNote import com.vitorpamplona.amethyst.ui.note.HiddenNote
import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ReactionsRow import com.vitorpamplona.amethyst.ui.note.ReactionsRow
import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.UserPicture
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
@@ -185,12 +187,16 @@ fun NoteMaster(baseNote: Note, accountViewModel: AccountViewModel, navController
} }
}) })
) { ) {
UserPicture(user = author, navController, userAccount = account.userProfile(), size = 55.dp) NoteAuthorPicture(
note = baseNote,
navController = navController,
userAccount = account.userProfile(),
size = 55.dp
)
Column(modifier = Modifier.padding(start = 10.dp)) { Column(modifier = Modifier.padding(start = 10.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null) NoteUsernameDisplay(baseNote)
UsernameDisplay(author)
} }
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
@@ -139,8 +139,7 @@ fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navContro
Column(modifier = Modifier.padding(start = 10.dp)) { Column(modifier = Modifier.padding(start = 10.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null) UsernameDisplay(baseUser)
UsernameDisplay(author)
} }
} }
} }
@@ -234,7 +234,7 @@ fun UserLine(
.weight(1f) .weight(1f)
) { ) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
UsernameDisplay(user) UsernameDisplay(baseUser)
} }
Text( Text(