- Moves zaps from a Map<Request,Response> to a List<CustomClass> to avoid recompositions due to the use of the unstable Pair object
- Creates the class ZapAmountCommentNotification to be used instead of the unstable Triple class.
This commit is contained in:
@@ -22,6 +22,7 @@ import androidx.compose.material.Text
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Bolt
|
import androidx.compose.material.icons.filled.Bolt
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
@@ -47,10 +48,12 @@ import com.vitorpamplona.amethyst.R
|
|||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
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.model.UserMetadata
|
||||||
import com.vitorpamplona.amethyst.service.model.LnZapEvent
|
import com.vitorpamplona.amethyst.service.model.LnZapEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent
|
import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent
|
||||||
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.CombinedZap
|
||||||
import com.vitorpamplona.amethyst.ui.screen.MultiSetCard
|
import com.vitorpamplona.amethyst.ui.screen.MultiSetCard
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.showAmountAxis
|
||||||
@@ -58,7 +61,6 @@ import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
|
||||||
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
import com.vitorpamplona.amethyst.ui.theme.overPictureBackground
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.ImmutableMap
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -92,48 +94,32 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val columnModifier = Modifier
|
val columnModifier = remember(backgroundColor.value) {
|
||||||
.drawBehind {
|
Modifier
|
||||||
drawRect(backgroundColor.value)
|
.drawBehind {
|
||||||
}
|
drawRect(backgroundColor.value)
|
||||||
.padding(
|
}
|
||||||
start = 12.dp,
|
.padding(
|
||||||
end = 12.dp,
|
start = 12.dp,
|
||||||
top = 10.dp
|
end = 12.dp,
|
||||||
)
|
top = 10.dp
|
||||||
.combinedClickable(
|
)
|
||||||
onClick = {
|
.combinedClickable(
|
||||||
scope.launch {
|
onClick = {
|
||||||
routeFor(baseNote, accountViewModel.userProfile())?.let { nav(it) }
|
scope.launch {
|
||||||
}
|
routeFor(baseNote, accountViewModel.userProfile())?.let { nav(it) }
|
||||||
},
|
}
|
||||||
onLongClick = { popupExpanded = true }
|
},
|
||||||
)
|
onLongClick = { popupExpanded = true }
|
||||||
.fillMaxWidth()
|
)
|
||||||
|
.fillMaxWidth()
|
||||||
val zapEvents by remember { derivedStateOf { multiSetCard.zapEvents } }
|
}
|
||||||
val boostEvents by remember { derivedStateOf { multiSetCard.boostEvents } }
|
|
||||||
val likeEvents by remember { derivedStateOf { multiSetCard.likeEvents } }
|
|
||||||
|
|
||||||
val hasZapEvents by remember { derivedStateOf { multiSetCard.zapEvents.isNotEmpty() } }
|
|
||||||
val hasBoostEvents by remember { derivedStateOf { multiSetCard.boostEvents.isNotEmpty() } }
|
|
||||||
val hasLikeEvents by remember { derivedStateOf { multiSetCard.likeEvents.isNotEmpty() } }
|
|
||||||
|
|
||||||
Column(modifier = columnModifier) {
|
Column(modifier = columnModifier) {
|
||||||
if (hasZapEvents) {
|
Galeries(multiSetCard, backgroundColor, nav, accountViewModel)
|
||||||
RenderZapGallery(zapEvents, backgroundColor, nav, accountViewModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBoostEvents) {
|
Row(remember { Modifier.fillMaxWidth() }) {
|
||||||
RenderBoostGallery(boostEvents, backgroundColor, nav, accountViewModel)
|
Spacer(modifier = remember { Modifier.width(65.dp) })
|
||||||
}
|
|
||||||
|
|
||||||
if (hasLikeEvents) {
|
|
||||||
RenderLikeGallery(likeEvents, backgroundColor, nav, accountViewModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(Modifier.fillMaxWidth()) {
|
|
||||||
Spacer(modifier = Modifier.width(65.dp))
|
|
||||||
|
|
||||||
NoteCompose(
|
NoteCompose(
|
||||||
baseNote = baseNote,
|
baseNote = baseNote,
|
||||||
@@ -150,6 +136,34 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Galeries(
|
||||||
|
multiSetCard: MultiSetCard,
|
||||||
|
backgroundColor: MutableState<Color>,
|
||||||
|
nav: (String) -> Unit,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val zapEvents by remember { derivedStateOf { multiSetCard.zapEvents } }
|
||||||
|
val boostEvents by remember { derivedStateOf { multiSetCard.boostEvents } }
|
||||||
|
val likeEvents by remember { derivedStateOf { multiSetCard.likeEvents } }
|
||||||
|
|
||||||
|
val hasZapEvents by remember { derivedStateOf { multiSetCard.zapEvents.isNotEmpty() } }
|
||||||
|
val hasBoostEvents by remember { derivedStateOf { multiSetCard.boostEvents.isNotEmpty() } }
|
||||||
|
val hasLikeEvents by remember { derivedStateOf { multiSetCard.likeEvents.isNotEmpty() } }
|
||||||
|
|
||||||
|
if (hasZapEvents) {
|
||||||
|
RenderZapGallery(zapEvents, backgroundColor, nav, accountViewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasBoostEvents) {
|
||||||
|
RenderBoostGallery(boostEvents, backgroundColor, nav, accountViewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasLikeEvents) {
|
||||||
|
RenderLikeGallery(likeEvents, backgroundColor, nav, accountViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderLikeGallery(
|
fun RenderLikeGallery(
|
||||||
likeEvents: ImmutableList<Note>,
|
likeEvents: ImmutableList<Note>,
|
||||||
@@ -157,7 +171,7 @@ fun RenderLikeGallery(
|
|||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
Row(Modifier.fillMaxWidth()) {
|
Row(remember { Modifier.fillMaxWidth() }) {
|
||||||
Box(
|
Box(
|
||||||
modifier = remember {
|
modifier = remember {
|
||||||
Modifier
|
Modifier
|
||||||
@@ -183,12 +197,12 @@ fun RenderLikeGallery(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderZapGallery(
|
fun RenderZapGallery(
|
||||||
zapEvents: ImmutableMap<Note, Note?>,
|
zapEvents: ImmutableList<CombinedZap>,
|
||||||
backgroundColor: MutableState<Color>,
|
backgroundColor: MutableState<Color>,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
Row(Modifier.fillMaxWidth()) {
|
Row(remember { Modifier.fillMaxWidth() }) {
|
||||||
Box(
|
Box(
|
||||||
modifier = remember {
|
modifier = remember {
|
||||||
Modifier
|
Modifier
|
||||||
@@ -250,7 +264,7 @@ fun RenderBoostGallery(
|
|||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AuthorGalleryZaps(
|
fun AuthorGalleryZaps(
|
||||||
authorNotes: ImmutableMap<Note, Note?>,
|
authorNotes: ImmutableList<CombinedZap>,
|
||||||
backgroundColor: MutableState<Color>,
|
backgroundColor: MutableState<Color>,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
@@ -258,12 +272,19 @@ fun AuthorGalleryZaps(
|
|||||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||||
FlowRow() {
|
FlowRow() {
|
||||||
authorNotes.forEach {
|
authorNotes.forEach {
|
||||||
AuthorPictureAndComment(it.key, it.value, backgroundColor, nav, accountViewModel)
|
AuthorPictureAndComment(it.request, it.response, backgroundColor, nav, accountViewModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class ZapAmountCommentNotification(
|
||||||
|
val user: User?,
|
||||||
|
val comment: String?,
|
||||||
|
val amount: String?
|
||||||
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AuthorPictureAndComment(
|
private fun AuthorPictureAndComment(
|
||||||
zapRequest: Note,
|
zapRequest: Note,
|
||||||
@@ -272,7 +293,15 @@ private fun AuthorPictureAndComment(
|
|||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
var content by remember { mutableStateOf<Triple<User?, String?, String?>>(Triple(zapRequest.author, null, null)) }
|
var content by remember {
|
||||||
|
mutableStateOf(
|
||||||
|
ZapAmountCommentNotification(
|
||||||
|
user = zapRequest.author,
|
||||||
|
comment = null,
|
||||||
|
amount = null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = zapRequest.idHex, key2 = zapEvent?.idHex) {
|
LaunchedEffect(key1 = zapRequest.idHex, key2 = zapEvent?.idHex) {
|
||||||
launch(Dispatchers.Default) {
|
launch(Dispatchers.Default) {
|
||||||
@@ -281,32 +310,34 @@ private fun AuthorPictureAndComment(
|
|||||||
val amount = (zapEvent?.event as? LnZapEvent)?.amount
|
val amount = (zapEvent?.event as? LnZapEvent)?.amount
|
||||||
if (decryptedContent != null) {
|
if (decryptedContent != null) {
|
||||||
val newAuthor = LocalCache.getOrCreateUser(decryptedContent.pubKey)
|
val newAuthor = LocalCache.getOrCreateUser(decryptedContent.pubKey)
|
||||||
content = Triple(newAuthor, decryptedContent.content.ifBlank { null }, showAmountAxis(amount))
|
content = ZapAmountCommentNotification(newAuthor, decryptedContent.content.ifBlank { null }, showAmountAxis(amount))
|
||||||
} else {
|
} else {
|
||||||
if (!zapRequest.event?.content().isNullOrBlank() || amount != null) {
|
if (!zapRequest.event?.content().isNullOrBlank() || amount != null) {
|
||||||
content = Triple(zapRequest.author, zapRequest.event?.content()?.ifBlank { null }, showAmountAxis(amount))
|
content = ZapAmountCommentNotification(zapRequest.author, zapRequest.event?.content()?.ifBlank { null }, showAmountAxis(amount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content.first?.let {
|
content.let {
|
||||||
val route by remember {
|
val route by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
"User/${it.pubkeyHex}"
|
"User/${it.user?.pubkeyHex}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthorPictureAndComment(
|
it.user?.let { user ->
|
||||||
author = it,
|
AuthorPictureAndComment(
|
||||||
comment = content.second,
|
author = user,
|
||||||
amount = content.third,
|
comment = it.comment,
|
||||||
route = route,
|
amount = it.amount,
|
||||||
backgroundColor = backgroundColor,
|
route = route,
|
||||||
nav = nav,
|
backgroundColor = backgroundColor,
|
||||||
accountViewModel = accountViewModel
|
nav = nav,
|
||||||
)
|
accountViewModel = accountViewModel
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,12 +372,19 @@ private fun AuthorPictureAndComment(
|
|||||||
)
|
)
|
||||||
|
|
||||||
amount?.let {
|
amount?.let {
|
||||||
Box(modifier = Modifier.fillMaxSize().clip(shape = CircleShape), contentAlignment = Alignment.BottomCenter) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(shape = CircleShape),
|
||||||
|
contentAlignment = Alignment.BottomCenter
|
||||||
|
) {
|
||||||
val backgroundColor = MaterialTheme.colors.overPictureBackground
|
val backgroundColor = MaterialTheme.colors.overPictureBackground
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = remember {
|
||||||
.fillMaxWidth()
|
Modifier
|
||||||
.drawBehind { drawRect(backgroundColor) },
|
.fillMaxWidth()
|
||||||
|
.drawBehind { drawRect(backgroundColor) }
|
||||||
|
},
|
||||||
contentAlignment = Alignment.BottomCenter
|
contentAlignment = Alignment.BottomCenter
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
@@ -424,17 +462,20 @@ fun FastNoteAuthorPicture(
|
|||||||
pictureModifier: Modifier = Modifier,
|
pictureModifier: Modifier = Modifier,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
val userState by author.live().metadata.observeAsState()
|
var profilePicture by remember {
|
||||||
val profilePicture by remember(userState) {
|
mutableStateOf(author.info?.picture)
|
||||||
derivedStateOf {
|
|
||||||
userState?.user?.profilePicture()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val authorPubKey = remember {
|
val authorPubKey = remember {
|
||||||
author.pubkeyHex
|
author.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WatchUserMetadata(author) {
|
||||||
|
if (it.picture != profilePicture) {
|
||||||
|
profilePicture = it.picture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UserPicture(
|
UserPicture(
|
||||||
userHex = authorPubKey,
|
userHex = authorPubKey,
|
||||||
userPicture = profilePicture,
|
userPicture = profilePicture,
|
||||||
@@ -443,3 +484,15 @@ fun FastNoteAuthorPicture(
|
|||||||
accountViewModel = accountViewModel
|
accountViewModel = accountViewModel
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WatchUserMetadata(userBase: User, onMetadataChanges: (UserMetadata) -> Unit) {
|
||||||
|
val userState by userBase.live().metadata.observeAsState()
|
||||||
|
LaunchedEffect(key1 = userState) {
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
userState?.user?.info?.let {
|
||||||
|
onMetadataChanges(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ 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.actions.NewPostView
|
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.CombinedZap
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableMap
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -188,7 +188,7 @@ private fun ReactionDetailGallery(
|
|||||||
if (hasReactions) {
|
if (hasReactions) {
|
||||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.padding(start = 10.dp, top = 5.dp)) {
|
Row(verticalAlignment = CenterVertically, modifier = Modifier.padding(start = 10.dp, top = 5.dp)) {
|
||||||
Column() {
|
Column() {
|
||||||
val zapEvents by remember(zapsState) { derivedStateOf { baseNote.zaps.toImmutableMap() } }
|
val zapEvents by remember(zapsState) { derivedStateOf { baseNote.zaps.mapNotNull { it.value?.let { zapEvent -> CombinedZap(it.key, zapEvent) } }.toImmutableList() } }
|
||||||
val boostEvents by remember(boostsState) { derivedStateOf { baseNote.boosts.toImmutableList() } }
|
val boostEvents by remember(boostsState) { derivedStateOf { baseNote.boosts.toImmutableList() } }
|
||||||
val likeEvents by remember(reactionsState) { derivedStateOf { baseNote.reactions.toImmutableList() } }
|
val likeEvents by remember(reactionsState) { derivedStateOf { baseNote.reactions.toImmutableList() } }
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import androidx.compose.runtime.Stable
|
|||||||
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 kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.ImmutableMap
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
abstract class Card() {
|
abstract class Card() {
|
||||||
@@ -33,8 +32,8 @@ class NoteCard(val note: Note) : Card() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class ZapUserSetCard(val user: User, val zapEvents: ImmutableMap<Note, Note>) : Card() {
|
class ZapUserSetCard(val user: User, val zapEvents: ImmutableList<CombinedZap>) : Card() {
|
||||||
val createdAt = zapEvents.maxOf { it.value.createdAt() ?: 0 }
|
val createdAt = zapEvents.maxOf { it.createdAt() ?: 0 }
|
||||||
override fun createdAt(): Long {
|
override fun createdAt(): Long {
|
||||||
return createdAt
|
return createdAt
|
||||||
}
|
}
|
||||||
@@ -42,15 +41,15 @@ class ZapUserSetCard(val user: User, val zapEvents: ImmutableMap<Note, Note>) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
class MultiSetCard(val note: Note, val boostEvents: ImmutableList<Note>, val likeEvents: ImmutableList<Note>, val zapEvents: ImmutableMap<Note, Note>) : Card() {
|
class MultiSetCard(val note: Note, val boostEvents: ImmutableList<Note>, val likeEvents: ImmutableList<Note>, val zapEvents: ImmutableList<CombinedZap>) : Card() {
|
||||||
val maxCreatedAt = maxOf(
|
val maxCreatedAt = maxOf(
|
||||||
zapEvents.maxOfOrNull { it.value.createdAt() ?: 0 } ?: 0,
|
zapEvents.maxOfOrNull { it.createdAt() ?: 0 } ?: 0,
|
||||||
likeEvents.maxOfOrNull { it.createdAt() ?: 0 } ?: 0,
|
likeEvents.maxOfOrNull { it.createdAt() ?: 0 } ?: 0,
|
||||||
boostEvents.maxOfOrNull { it.createdAt() ?: 0 } ?: 0
|
boostEvents.maxOfOrNull { it.createdAt() ?: 0 } ?: 0
|
||||||
)
|
)
|
||||||
|
|
||||||
val minCreatedAt = minOf(
|
val minCreatedAt = minOf(
|
||||||
zapEvents.minOfOrNull { it.value.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE,
|
zapEvents.minOfOrNull { it.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE,
|
||||||
likeEvents.minOfOrNull { it.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE,
|
likeEvents.minOfOrNull { it.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE,
|
||||||
boostEvents.minOfOrNull { it.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE
|
boostEvents.minOfOrNull { it.createdAt() ?: Long.MAX_VALUE } ?: Long.MAX_VALUE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -25,7 +26,6 @@ import com.vitorpamplona.amethyst.ui.dal.FeedFilter
|
|||||||
import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableMap
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -132,8 +132,8 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// val reactionCards = reactionsPerEvent.map { LikeSetCard(it.key, it.value) }
|
// val reactionCards = reactionsPerEvent.map { LikeSetCard(it.key, it.value) }
|
||||||
val zapsPerUser = mutableMapOf<User, MutableMap<Note, Note>>()
|
val zapsPerUser = mutableMapOf<User, MutableList<CombinedZap>>()
|
||||||
val zapsPerEvent = mutableMapOf<Note, MutableMap<Note, Note>>()
|
val zapsPerEvent = mutableMapOf<Note, MutableList<CombinedZap>>()
|
||||||
notes
|
notes
|
||||||
.filter { it.event is LnZapEvent }
|
.filter { it.event is LnZapEvent }
|
||||||
.forEach { zapEvent ->
|
.forEach { zapEvent ->
|
||||||
@@ -143,27 +143,23 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
|
|||||||
if (zapRequest != null) {
|
if (zapRequest != null) {
|
||||||
// var newZapRequestEvent = LocalCache.checkPrivateZap(zapRequest.event as Event)
|
// var newZapRequestEvent = LocalCache.checkPrivateZap(zapRequest.event as Event)
|
||||||
// zapRequest.event = newZapRequestEvent
|
// zapRequest.event = newZapRequestEvent
|
||||||
zapsPerEvent.getOrPut(zappedPost, { mutableMapOf() }).put(zapRequest, zapEvent)
|
zapsPerEvent.getOrPut(zappedPost, { mutableListOf() }).add(CombinedZap(zapRequest, zapEvent))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val event = (zapEvent.event as LnZapEvent)
|
val event = (zapEvent.event as LnZapEvent)
|
||||||
val author = event.zappedAuthor().mapNotNull {
|
val author = event.zappedAuthor().firstNotNullOfOrNull {
|
||||||
LocalCache.checkGetOrCreateUser(
|
LocalCache.users[it] // don't create user if it doesn't exist
|
||||||
it
|
}
|
||||||
)
|
|
||||||
}.firstOrNull()
|
|
||||||
if (author != null) {
|
if (author != null) {
|
||||||
val zapRequest = author.zaps.filter { it.value == zapEvent }.keys.firstOrNull()
|
val zapRequest = author.zaps.filter { it.value == zapEvent }.keys.firstOrNull()
|
||||||
if (zapRequest != null) {
|
if (zapRequest != null) {
|
||||||
zapsPerUser.getOrPut(author, { mutableMapOf() })
|
zapsPerUser.getOrPut(author, { mutableListOf() })
|
||||||
.put(zapRequest, zapEvent)
|
.add(CombinedZap(zapRequest, zapEvent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// val zapCards = zapsPerEvent.map { ZapSetCard(it.key, it.value) }
|
|
||||||
|
|
||||||
val boostsPerEvent = mutableMapOf<Note, MutableList<Note>>()
|
val boostsPerEvent = mutableMapOf<Note, MutableList<Note>>()
|
||||||
notes
|
notes
|
||||||
.filter { it.event is RepostEvent }
|
.filter { it.event is RepostEvent }
|
||||||
@@ -178,9 +174,9 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
|
|||||||
val multiCards = allBaseNotes.map { baseNote ->
|
val multiCards = allBaseNotes.map { baseNote ->
|
||||||
val boostsInCard = boostsPerEvent[baseNote] ?: emptyList()
|
val boostsInCard = boostsPerEvent[baseNote] ?: emptyList()
|
||||||
val reactionsInCard = reactionsPerEvent[baseNote] ?: emptyList()
|
val reactionsInCard = reactionsPerEvent[baseNote] ?: emptyList()
|
||||||
val zapsInCard = zapsPerEvent[baseNote] ?: emptyMap()
|
val zapsInCard = zapsPerEvent[baseNote] ?: emptyList()
|
||||||
|
|
||||||
val singleList = (boostsInCard + zapsInCard.values + reactionsInCard)
|
val singleList = (boostsInCard + zapsInCard.map { it.response } + reactionsInCard)
|
||||||
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
||||||
.reversed()
|
.reversed()
|
||||||
|
|
||||||
@@ -189,7 +185,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
|
|||||||
baseNote,
|
baseNote,
|
||||||
boostsInCard.filter { it in chunk }.toImmutableList(),
|
boostsInCard.filter { it in chunk }.toImmutableList(),
|
||||||
reactionsInCard.filter { it in chunk }.toImmutableList(),
|
reactionsInCard.filter { it in chunk }.toImmutableList(),
|
||||||
zapsInCard.filter { it.value in chunk }.toImmutableMap()
|
zapsInCard.filter { it.response in chunk }.toImmutableList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.flatten()
|
}.flatten()
|
||||||
@@ -197,7 +193,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
|
|||||||
val userZaps = zapsPerUser.map {
|
val userZaps = zapsPerUser.map {
|
||||||
ZapUserSetCard(
|
ZapUserSetCard(
|
||||||
it.key,
|
it.key,
|
||||||
it.value.toImmutableMap()
|
it.value.toImmutableList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,3 +342,9 @@ fun <T> equalImmutableLists(list1: ImmutableList<T>, list2: ImmutableList<T>): B
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class CombinedZap(val request: Note, val response: Note) {
|
||||||
|
fun createdAt() = response.createdAt()
|
||||||
|
fun idHex() = response.idHex
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user