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

View File

@ -76,21 +76,14 @@ fun BoostSetCompose(likeSetCard: BoostSetCard, isInnerNote: Boolean = false, rou
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
FlowRow() {
likeSetCard.boostEvents.forEach {
val cardNoteState by it.live.observeAsState()
val cardNote = cardNoteState?.note
if (cardNote?.author != null) {
val userState by cardNote.author!!.live.observeAsState()
UserPicture(
user = userState?.user,
NoteAuthorPicture(
note = it,
navController = navController,
userAccount = account.userProfile(),
size = 35.dp
)
}
}
}
NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController)
}

View File

@ -134,7 +134,7 @@ fun ChatroomCompose(baseNote: Note, accountViewModel: AccountViewModel, navContr
false
ChannelName(
channelPicture = { UserPicture(user = user, userAccount = accountUser, size = 55.dp) },
channelPicture = { UserPicture(user, accountUser, size = 55.dp) },
channelTitle = { UsernameDisplay(user, it) },
channelLastTime = noteEvent?.createdAt,
channelLastContent = accountViewModel.decrypt(note),

View File

@ -76,21 +76,14 @@ fun LikeSetCompose(likeSetCard: LikeSetCard, modifier: Modifier = Modifier, isIn
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
FlowRow() {
likeSetCard.likeEvents.forEach {
val cardNoteState by it.live.observeAsState()
val cardNote = cardNoteState?.note
if (cardNote?.author != null) {
val userState by cardNote.author!!.live.observeAsState()
UserPicture(
user = userState?.user,
NoteAuthorPicture(
note = it,
navController = navController,
userAccount = account.userProfile(),
size = 35.dp
)
}
}
}
NoteCompose(note, null, Modifier.padding(top = 5.dp), true, accountViewModel, navController)
}

View File

@ -95,9 +95,6 @@ fun NoteCompose(
onLongClick = { popupExpanded = true },
), isInnerNote)
} 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 lastTime = NotificationCache.load(this, context)
@ -145,22 +142,22 @@ fun NoteCompose(
Box(modifier = Modifier
.width(55.dp)
.padding(0.dp)) {
UserPicture(author, navController, account.userProfile(), 55.dp)
// boosted picture
val boostedPosts = note.replyTo
if (note.event is RepostEvent && boostedPosts != null && boostedPosts.isNotEmpty()) {
val boostedAuthor = boostedPosts[0].author
NoteAuthorPicture(note, navController, account.userProfile(), 55.dp)
if (note.event is RepostEvent) {
note.replyTo?.lastOrNull()?.let {
Box(
Modifier
.width(30.dp)
.height(30.dp)
.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)
)
}
}
}
// boosted picture
val baseChannel = note.channel
@ -197,8 +194,7 @@ fun NoteCompose(
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null)
UsernameDisplay(author, Modifier.weight(1f))
NoteUsernameDisplay(note, Modifier.weight(1f))
if (note.event !is RepostEvent) {
Text(
@ -274,40 +270,42 @@ fun NoteCompose(
}
}
@Composable
fun UserPicture(
user: User?,
fun NoteAuthorPicture(
note: Note,
navController: NavController,
userAccount: User,
size: Dp,
pictureModifier: Modifier = Modifier
) {
UserPicture(user, userAccount, size, pictureModifier) {
user?.let {
NoteAuthorPicture(note, userAccount, size, pictureModifier) {
navController.navigate("User/${it.pubkeyHex}")
}
}
}
@Composable
fun UserPicture(
user: User?,
userAccount: User,
fun NoteAuthorPicture(
baseNote: Note,
baseUserAccount: User,
size: Dp,
pictureModifier: Modifier = Modifier,
onClick: (() -> Unit)? = null
onClick: ((User) -> Unit)? = null
) {
val accountState by userAccount.live.observeAsState()
val accountUser = accountState?.user ?: return
val noteState by baseNote.live.observeAsState()
val note = noteState?.note ?: return
val author = note.author
Box(
Modifier
.width(size)
.height(size)) {
if (user == null) {
if (author == null) {
AsyncImage(
model = "https://robohash.org/ohno.png",
contentDescription = "Profile Image",
contentDescription = "Unknown Author",
placeholder = rememberAsyncImagePainter("https://robohash.org/ohno.png"),
modifier = pictureModifier
.fillMaxSize(1f)
@ -315,27 +313,61 @@ fun UserPicture(
.background(MaterialTheme.colors.background)
)
} else {
val userState by user.live.observeAsState()
val userLive = userState?.user ?: return
UserPicture(author, baseUserAccount, size, pictureModifier, onClick)
}
}
}
@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(
model = userLive.profilePicture(),
model = user.profilePicture(),
contentDescription = "Profile Image",
placeholder = rememberAsyncImagePainter("https://robohash.org/${userLive.pubkeyHex}.png"),
placeholder = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
modifier = pictureModifier
.fillMaxSize(1f)
.clip(shape = CircleShape)
.background(MaterialTheme.colors.background)
.run {
if (onClick != null)
this.clickable(onClick = onClick)
this.clickable(onClick = { onClick(user) } )
else
this
}
)
if (accountUser.isFollowing(userLive) || userLive == accountUser) {
if (accountUser.isFollowing(user) || user == accountUser) {
Box(
Modifier
.width(size.div(3.5f))
@ -362,7 +394,7 @@ fun UserPicture(
)
}
}
}
}
}

View File

@ -52,11 +52,11 @@ fun UserCompose(baseUser: User, accountViewModel: AccountViewModel, navControlle
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)) {
Row(verticalAlignment = Alignment.CenterVertically) {
UsernameDisplay(user)
UsernameDisplay(baseUser)
}
Text(

View File

@ -3,13 +3,32 @@ package com.vitorpamplona.amethyst.ui.note
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
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.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
@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.bestDisplayName().isNullOrBlank()) {
Text(

View File

@ -41,7 +41,9 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.components.RichTextViewer
import com.vitorpamplona.amethyst.ui.note.BlankNote
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.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ReactionsRow
import com.vitorpamplona.amethyst.ui.note.UserPicture
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)) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null)
UsernameDisplay(author)
NoteUsernameDisplay(baseNote)
}
Row(verticalAlignment = Alignment.CenterVertically) {

View File

@ -139,8 +139,7 @@ fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navContro
Column(modifier = Modifier.padding(start = 10.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (author != null)
UsernameDisplay(author)
UsernameDisplay(baseUser)
}
}
}

View File

@ -234,7 +234,7 @@ fun UserLine(
.weight(1f)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
UsernameDisplay(user)
UsernameDisplay(baseUser)
}
Text(