diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 8c487d1d4..d2fc850df 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -243,10 +243,12 @@ class Account( fun joinChannel(idHex: String) { followingChannels.add(idHex) + invalidateData() } fun leaveChannel(idHex: String) { followingChannels.remove(idHex) + invalidateData() } fun hideUser(pubkeyHex: String) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index adb9ecdce..6226c323f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -45,7 +45,7 @@ class Note(val idHex: String) { this.mentions = mentions this.replyTo = replyTo - invalidateData() + invalidateData(live) } fun formattedDateTime(timestamp: Long): String { @@ -77,22 +77,22 @@ class Note(val idHex: String) { fun addReply(note: Note) { if (replies.add(note)) - invalidateData() + invalidateData(liveReplies) } fun addBoost(note: Note) { if (boosts.add(note)) - invalidateData() + invalidateData(liveBoosts) } fun addReaction(note: Note) { if (reactions.add(note)) - invalidateData() + invalidateData(liveReactions) } fun addReport(note: Note) { if (reports.add(note)) - invalidateData() + invalidateData(liveReports) } fun isReactedBy(user: User): Boolean { @@ -110,10 +110,15 @@ class Note(val idHex: String) { // Observers line up here. val live: NoteLiveData = NoteLiveData(this) + val liveReactions: NoteLiveData = NoteLiveData(this) + val liveBoosts: NoteLiveData = NoteLiveData(this) + val liveReplies: NoteLiveData = NoteLiveData(this) + val liveReports: NoteLiveData = NoteLiveData(this) + // Refreshes observers in batches. var handlerWaiting = false @Synchronized - fun invalidateData() { + fun invalidateData(live: NoteLiveData) { if (handlerWaiting) return handlerWaiting = true diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableNoteTag.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableNoteTag.kt index 6b2bf6a0e..3d0c48636 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableNoteTag.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableNoteTag.kt @@ -14,13 +14,12 @@ import com.vitorpamplona.amethyst.ui.note.toShortenHex @Composable fun ClickableNoteTag( - note: Note, + baesNote: Note, navController: NavController ) { - val innerNoteState by note.live.observeAsState() ClickableText( - text = AnnotatedString("@${innerNoteState?.note?.id?.toNote()?.toShortenHex()} "), - onClick = { navController.navigate("Note/${innerNoteState?.note?.idHex}") }, + text = AnnotatedString("@${baesNote.id.toNote().toShortenHex()} "), + onClick = { navController.navigate("Note/${baesNote.idHex}") }, style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary) ) } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 2e2bfeff5..16c610379 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -186,7 +186,7 @@ fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Bool RichTextViewer(eventContent, note.event?.tags, navController) if (note.event !is ChannelMessageEvent) { - ReactionsRowState(note, accountViewModel) + ReactionsRow(note, accountViewModel) } Divider( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 7a66383ad..9bec3b8c8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -1,6 +1,5 @@ package com.vitorpamplona.amethyst.ui.note -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -21,6 +20,7 @@ import androidx.compose.material.icons.outlined.Visibility import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -44,7 +44,19 @@ import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable -fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewModel) { +fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) { + val accountState by accountViewModel.accountLiveData.observeAsState() + val account = accountState?.account ?: return + + val reactionsState by baseNote.liveReactions.observeAsState() + val reactedNote = reactionsState?.note + + val boostsState by baseNote.liveBoosts.observeAsState() + val boostedNote = boostsState?.note + + val repliesState by baseNote.liveReplies.observeAsState() + val replies = repliesState?.note?.replies ?: emptySet() + val grayTint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) var popupExpanded by remember { mutableStateOf(false) } @@ -65,7 +77,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode ) { IconButton( modifier = Modifier.then(Modifier.size(24.dp)), - onClick = { if (account.isWriteable()) wantsToReplyTo = note } + onClick = { if (account.isWriteable()) wantsToReplyTo = baseNote } ) { Icon( painter = painterResource(R.drawable.ic_comment), @@ -76,7 +88,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode } Text( - " ${showCount(note.replies?.size)}", + " ${showCount(replies.size)}", fontSize = 14.sp, color = grayTint, modifier = Modifier.weight(1f) @@ -84,9 +96,9 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode IconButton( modifier = Modifier.then(Modifier.size(24.dp)), - onClick = { if (account.isWriteable()) accountViewModel.boost(note) } + onClick = { if (account.isWriteable()) accountViewModel.boost(baseNote) } ) { - if (note.isBoostedBy(account.userProfile())) { + if (boostedNote?.isBoostedBy(account.userProfile()) == true) { Icon( painter = painterResource(R.drawable.ic_retweeted), null, @@ -104,7 +116,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode } Text( - " ${showCount(note.boosts?.size)}", + " ${showCount(boostedNote?.boosts?.size)}", fontSize = 14.sp, color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), modifier = Modifier.weight(1f) @@ -112,9 +124,9 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode IconButton( modifier = Modifier.then(Modifier.size(24.dp)), - onClick = { if (account.isWriteable()) accountViewModel.reactTo(note) } + onClick = { if (account.isWriteable()) accountViewModel.reactTo(baseNote) } ) { - if (note.isReactedBy(account.userProfile())) { + if (reactedNote?.isReactedBy(account.userProfile()) == true) { Icon( painter = painterResource(R.drawable.ic_liked), null, @@ -132,7 +144,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode } Text( - " ${showCount(note.reactions?.size)}", + " ${showCount(reactedNote?.reactions?.size)}", fontSize = 14.sp, color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), modifier = Modifier.weight(1f) @@ -154,7 +166,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode Row(modifier = Modifier.weight(1f)) { AsyncImage( model = ImageRequest.Builder(LocalContext.current) - .data("https://counter.amethyst.social/${note.idHex}.svg?label=+&color=00000000") + .data("https://counter.amethyst.social/${baseNote.idHex}.svg?label=+&color=00000000") .crossfade(true) .diskCachePolicy(CachePolicy.DISABLED) .memoryCachePolicy(CachePolicy.ENABLED) @@ -179,7 +191,7 @@ fun ReactionsRow(note: Note, account: Account, accountViewModel: AccountViewMode } } - NoteDropDownMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel) + NoteDropDownMenu(baseNote, popupExpanded, { popupExpanded = false }, accountViewModel) } fun showCount(size: Int?): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRowState.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRowState.kt deleted file mode 100644 index c93f4b07b..000000000 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRowState.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.vitorpamplona.amethyst.ui.note - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState -import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel - -@Composable -fun ReactionsRowState(baseNote: Note, accountViewModel: AccountViewModel) { - val accountState by accountViewModel.accountLiveData.observeAsState() - val account = accountState?.account - - val noteState by baseNote.live.observeAsState() - val note = noteState?.note - - if (account == null || note == null) return - - ReactionsRow(note, account, accountViewModel) -} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index 11f4fa418..08b4a5928 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -40,7 +40,7 @@ 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.NoteCompose -import com.vitorpamplona.amethyst.ui.note.ReactionsRowState +import com.vitorpamplona.amethyst.ui.note.ReactionsRow import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.timeAgoLong import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -205,7 +205,7 @@ fun NoteMaster(baseNote: Note, accountViewModel: AccountViewModel, navController if (eventContent != null) RichTextViewer(eventContent, note.event?.tags, navController) - ReactionsRowState(note, accountViewModel) + ReactionsRow(note, accountViewModel) Divider( modifier = Modifier.padding(top = 10.dp),