Refreshing new Channels when showing them up on screen.

This commit is contained in:
Vitor Pamplona 2023-01-27 19:28:48 -03:00
parent a29a0a614b
commit ae82c690ea
5 changed files with 118 additions and 1 deletions

View File

@ -8,6 +8,7 @@ import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
import com.vitorpamplona.amethyst.service.NostrNotificationDataSource
import com.vitorpamplona.amethyst.service.NostrSingleChannelDataSource
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource
import com.vitorpamplona.amethyst.service.NostrThreadDataSource
@ -48,6 +49,7 @@ object ServiceManager {
NostrHomeDataSource.start()
NostrNotificationDataSource.start()
NostrSingleEventDataSource.start()
NostrSingleChannelDataSource.start()
NostrSingleUserDataSource.start()
NostrThreadDataSource.start()
NostrChatroomListDataSource.start()
@ -68,6 +70,7 @@ object ServiceManager {
NostrGlobalDataSource.stop()
NostrNotificationDataSource.stop()
NostrSingleChannelDataSource.stop()
NostrSingleEventDataSource.stop()
NostrSingleUserDataSource.stop()
NostrThreadDataSource.stop()

View File

@ -1,6 +1,7 @@
package com.vitorpamplona.amethyst.model
import androidx.lifecycle.LiveData
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
import com.vitorpamplona.amethyst.ui.note.toShortenHex
import java.util.concurrent.ConcurrentHashMap
@ -52,6 +53,16 @@ class ChannelLiveData(val channel: Channel): LiveData<ChannelState>(ChannelState
fun refresh() {
postValue(ChannelState(channel))
}
override fun onActive() {
super.onActive()
NostrSingleEventDataSource.add(channel.idHex)
}
override fun onInactive() {
super.onInactive()
NostrSingleEventDataSource.remove(channel.idHex)
}
}
class ChannelState(val channel: Channel)

View File

@ -0,0 +1,73 @@
package com.vitorpamplona.amethyst.service
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
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.ReactionEvent
import com.vitorpamplona.amethyst.service.model.RepostEvent
import java.util.Collections
import nostr.postr.JsonFilter
import nostr.postr.events.TextNoteEvent
object NostrSingleChannelDataSource: NostrDataSource<Note>("SingleChannelFeed") {
private var channelsToWatch = setOf<String>()
private fun createRepliesAndReactionsFilter(): JsonFilter? {
val reactionsToWatch = channelsToWatch.map { it }
if (reactionsToWatch.isEmpty()) {
return null
}
// downloads all the reactions to a given event.
return JsonFilter(
kinds = listOf(ChannelMetadataEvent.kind),
tags = mapOf("e" to reactionsToWatch)
)
}
fun createLoadEventsIfNotLoadedFilter(): JsonFilter? {
val directEventsToLoad = channelsToWatch
.map { LocalCache.getOrCreateChannel(it) }
.filter { it.notes.isEmpty() }
val interestedEvents = (directEventsToLoad).map { it.idHex }.toSet()
if (interestedEvents.isEmpty()) {
return null
}
// downloads linked events to this event.
return JsonFilter(
kinds = listOf(ChannelCreateEvent.kind),
ids = interestedEvents.toList()
)
}
val repliesAndReactionsChannel = requestNewChannel()
val loadEventsChannel = requestNewChannel()
override fun feed(): List<Note> {
return emptyList()
}
override fun updateChannelFilters() {
val reactions = createRepliesAndReactionsFilter()
val missing = createLoadEventsIfNotLoadedFilter()
repliesAndReactionsChannel.filter = listOfNotNull(reactions).ifEmpty { null }
loadEventsChannel.filter = listOfNotNull(missing).ifEmpty { null }
}
fun add(eventId: String) {
channelsToWatch = channelsToWatch.plus(eventId)
invalidateFilters()
}
fun remove(eventId: String) {
channelsToWatch = channelsToWatch.minus(eventId)
invalidateFilters()
}
}

View File

@ -155,6 +155,33 @@ fun NoteCompose(
)
}
}
// boosted picture
val baseChannel = note.channel
if (note.event is ChannelMessageEvent && baseChannel != null) {
val channelState by baseChannel.live.observeAsState()
val channel = channelState?.channel
if (channel != null) {
Box(
Modifier
.width(30.dp)
.height(30.dp)
.align(Alignment.BottomEnd)) {
AsyncImage(
model = channel.profilePicture(),
placeholder = null,
contentDescription = "Group Picture",
modifier = Modifier
.width(30.dp)
.height(30.dp)
.clip(shape = CircleShape)
.background(MaterialTheme.colors.background)
.border(2.dp, MaterialTheme.colors.background, CircleShape)
)
}
}
}
}
}

View File

@ -91,11 +91,14 @@ fun ReplyInformationChannel(replyTo: MutableList<Note>?, mentions: List<User>?,
@Composable
fun ReplyInformationChannel(replyTo: MutableList<Note>?,
mentions: List<User>?,
channel: Channel,
baseChannel: Channel,
prefix: String = "",
onUserTagClick: (User) -> Unit,
onChannelTagClick: (Channel) -> Unit
) {
val channelState by baseChannel.live.observeAsState()
val channel = channelState?.channel ?: return
FlowRow() {
Text(
"in channel ",