diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index d21aa85b2..a69c79e44 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -849,7 +849,7 @@ object LocalCache { note.loadEvent(event, author, replyTo) - Log.d("CM", "New Chat Note (${note.author?.toBestDisplayName()} ${note.event?.content()} ${formattedDateTime(event.createdAt)}") + // Log.d("CM", "New Chat Note (${note.author?.toBestDisplayName()} ${note.event?.content()} ${formattedDateTime(event.createdAt)}") // Counts the replies replyTo.forEach { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt index 8a21bf43b..4a907f3fc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/CommunityFeedFilter.kt @@ -20,13 +20,21 @@ class CommunityFeedFilter(val note: AddressableNote, val account: Account) : Add } private fun innerApplyFilter(collection: Collection): Set { - return collection + val myUnapprovedPosts = collection.asSequence() + .filter { it.author?.pubkeyHex == account.userProfile().pubkeyHex } // made by the logged in user + .filter { it.event?.isTaggedAddressableNote(note.idHex) == true } // for this community + .filter { it.isNewThread() } // check if it is a new thread + .toSet() + + val approvedPosts = collection .asSequence() .filter { it.event is CommunityPostApprovalEvent } // Only Approvals .filter { it.event?.isTaggedAddressableNote(note.idHex) == true } // Of the given community .mapNotNull { it.replyTo }.flatten() // get approved posts .filter { it.isNewThread() } // check if it is a new thread .toSet() + + return myUnapprovedPosts + approvedPosts } override fun sort(collection: Set): List { 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 7926fa444..ae7af7e12 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 @@ -88,6 +88,7 @@ import coil.compose.AsyncImage import coil.compose.AsyncImagePainter import coil.request.SuccessResult import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note @@ -104,6 +105,7 @@ import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent import com.vitorpamplona.amethyst.service.model.CommunityDefinitionEvent +import com.vitorpamplona.amethyst.service.model.CommunityPostApprovalEvent import com.vitorpamplona.amethyst.service.model.FileHeaderEvent import com.vitorpamplona.amethyst.service.model.FileStorageHeaderEvent import com.vitorpamplona.amethyst.service.model.GenericRepostEvent @@ -497,7 +499,8 @@ fun CommunityHeader( model = it, contentDescription = stringResource(R.string.profile_image), contentScale = ContentScale.Crop, - modifier = Modifier.padding(start = 10.dp) + modifier = Modifier + .padding(start = 10.dp) .width(Size35dp) .height(Size35dp) .clip(shape = CircleShape) @@ -708,7 +711,8 @@ fun InnerNoteWithReactions( Row( modifier = remember { - Modifier.fillMaxWidth() + Modifier + .fillMaxWidth() .padding( start = if (!isBoostedNote) 12.dp else 0.dp, end = if (!isBoostedNote) 12.dp else 0.dp, @@ -914,6 +918,17 @@ private fun RenderNoteRow( ) } + is CommunityPostApprovalEvent -> { + RenderPostApproval( + baseNote, + makeItShort, + canPreview, + backgroundColor, + accountViewModel, + nav + ) + } + else -> { RenderTextEvent( baseNote, @@ -1644,6 +1659,76 @@ fun RenderRepost( } } +@Composable +fun RenderPostApproval( + note: Note, + makeItShort: Boolean, + canPreview: Boolean, + backgroundColor: MutableState, + accountViewModel: AccountViewModel, + nav: (String) -> Unit +) { + if (note.replyTo.isNullOrEmpty()) return + + val noteEvent = note.event as? CommunityPostApprovalEvent ?: return + + Column(Modifier.fillMaxWidth()) { + noteEvent.communities().forEach { + LoadAddressableNote(it) { + it?.let { + NoteCompose( + it, + parentBackgroundColor = backgroundColor, + accountViewModel = accountViewModel, + nav = nav + ) + } + } + } + + Text( + text = stringResource(id = R.string.community_approved_posts), + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .fillMaxWidth() + .padding(5.dp), + textAlign = TextAlign.Center + ) + + note.replyTo?.forEach { + NoteCompose( + it, + modifier = MaterialTheme.colors.replyModifier, + unPackReply = false, + makeItShort = true, + isQuotedNote = true, + parentBackgroundColor = backgroundColor, + accountViewModel = accountViewModel, + nav = nav + ) + } + } +} + +@Composable +fun LoadAddressableNote(aTag: ATag, content: @Composable (AddressableNote?) -> Unit) { + var note by remember(aTag) { + mutableStateOf(LocalCache.getAddressableNoteIfExists(aTag.toTag())) + } + + if (note == null) { + LaunchedEffect(key1 = aTag) { + launch(Dispatchers.IO) { + note = LocalCache.getOrCreateAddressableNote(aTag) + } + } + } + + content(note) +} + @Composable private fun RenderPinListEvent( baseNote: Note, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6cd56098a..ae17f0e2d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -476,4 +476,5 @@ Live Communities Chat Groups + Approved Posts