From 89bdc9dd58cf869039105827f12ee0444d9ceb1b Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 7 Jun 2023 17:16:48 -0400 Subject: [PATCH] Adds support for RelaySet event types. --- .../amethyst/model/LocalCache.kt | 20 ++- .../amethyst/service/NostrDataSource.kt | 2 +- .../amethyst/service/model/Event.kt | 1 + .../amethyst/service/model/RelaySetEvent.kt | 44 +++++ .../EventNotificationConsumer.kt | 2 +- .../ui/components/ExpandableRichTextViewer.kt | 2 +- .../ui/components/ZoomableContentView.kt | 3 +- .../ui/note/ChatroomMessageCompose.kt | 3 +- .../amethyst/ui/note/NoteCompose.kt | 158 ++++++++++++++++++ .../amethyst/ui/screen/ThreadFeedView.kt | 8 + .../ui/screen/loggedIn/ChatroomListScreen.kt | 9 +- .../ui/screen/loggedIn/ChatroomScreen.kt | 8 +- .../amethyst/ui/screen/loggedIn/HomeScreen.kt | 6 +- .../ui/screen/loggedIn/LoadRedirectScreen.kt | 3 +- .../ui/screen/loggedIn/SearchScreen.kt | 8 +- 15 files changed, 251 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt 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 bd673fb1e..b6497d70d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -300,6 +300,19 @@ object LocalCache { } } + private fun consume(event: RelaySetEvent) { + val note = getOrCreateAddressableNote(event.address()) + val author = getOrCreateUser(event.pubKey) + + if (note.event?.id() == event.id()) return + + if (event.createdAt > (note.createdAt() ?: 0)) { + note.loadEvent(event, author, emptyList()) + + refreshObservers(note) + } + } + private fun consume(event: AudioTrackEvent) { val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) @@ -1015,7 +1028,7 @@ object LocalCache { live.invalidateData(newNote) } - fun consume(event: Event, relay: Relay?) { + fun verifyAndConsume(event: Event, relay: Relay?) { checkNotInMainThread() if (!event.hasValidSignature()) { @@ -1050,7 +1063,7 @@ object LocalCache { is HighlightEvent -> consume(event, relay) is LnZapEvent -> { event.zapRequest?.let { - consume(it, relay) + verifyAndConsume(it, relay) } consume(event) } @@ -1064,10 +1077,11 @@ object LocalCache { is PeopleListEvent -> consume(event) is ReactionEvent -> consume(event) is RecommendRelayEvent -> consume(event) + is RelaySetEvent -> consume(event) is ReportEvent -> consume(event, relay) is RepostEvent -> { event.containedPost()?.let { - consume(it, relay) + verifyAndConsume(it, relay) } consume(event) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt index 9b65dd7cd..2bb25fa83 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt @@ -39,7 +39,7 @@ abstract class NostrDataSource(val debugName: String) { eventCounter = eventCounter + Pair(key, Counter(1)) } - LocalCache.consume(event, relay) + LocalCache.verifyAndConsume(event, relay) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt index c3681b737..3d891afed 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt @@ -258,6 +258,7 @@ open class Event( PrivateDmEvent.kind -> PrivateDmEvent(id, pubKey, createdAt, tags, content, sig) ReactionEvent.kind -> ReactionEvent(id, pubKey, createdAt, tags, content, sig) RecommendRelayEvent.kind -> RecommendRelayEvent(id, pubKey, createdAt, tags, content, sig, lenient) + RelaySetEvent.kind -> RelaySetEvent(id, pubKey, createdAt, tags, content, sig) ReportEvent.kind -> ReportEvent(id, pubKey, createdAt, tags, content, sig) RepostEvent.kind -> RepostEvent(id, pubKey, createdAt, tags, content, sig) TextNoteEvent.kind -> TextNoteEvent(id, pubKey, createdAt, tags, content, sig) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt new file mode 100644 index 000000000..2aa96885b --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/RelaySetEvent.kt @@ -0,0 +1,44 @@ +package com.vitorpamplona.amethyst.service.model + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.amethyst.model.HexKey +import com.vitorpamplona.amethyst.model.toHexKey +import nostr.postr.Utils +import java.util.Date + +@Immutable +class RelaySetEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: List>, + content: String, + sig: HexKey +) : Event(id, pubKey, createdAt, kind, tags, content, sig), AddressableEvent { + + override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: "" + override fun address() = ATag(kind, pubKey, dTag(), null) + + fun relays() = tags.filter { it.size > 1 && it[0] == "r" }.map { it[1] } + fun description() = tags.firstOrNull() { it.size > 1 && it[0] == "description" }?.get(1) + + companion object { + const val kind = 30022 + + fun create( + relays: List, + privateKey: ByteArray, + createdAt: Long = Date().time / 1000 + ): RelaySetEvent { + val tags = mutableListOf>() + relays.forEach { + tags.add(listOf("r", it)) + } + + val pubKey = Utils.pubkeyCreate(privateKey).toHexKey() + val id = generateId(pubKey, createdAt, kind, tags, "") + val sig = Utils.sign(id, privateKey) + return RelaySetEvent(id.toHexKey(), pubKey, createdAt, tags, "", sig.toHexKey()) + } + } +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index 368cc5f4e..fba241d83 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -23,7 +23,7 @@ class EventNotificationConsumer(private val applicationContext: Context) { val scope = CoroutineScope(Job() + Dispatchers.IO) scope.launch { // adds to database - LocalCache.consume(event, null) + LocalCache.verifyAndConsume(event, null) when (event) { is PrivateDmEvent -> notify(event) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt index 90cfc7a0d..aade217ac 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ExpandableRichTextViewer.kt @@ -97,7 +97,7 @@ fun ExpandableRichTextViewer( } @Composable -private fun ShowMoreButton(onClick: () -> Unit) { +public fun ShowMoreButton(onClick: () -> Unit) { Button( modifier = Modifier.padding(top = 10.dp), onClick = onClick, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 13d74cdb6..dfee43bbe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -372,10 +372,9 @@ private fun aspectRatio(dim: String?): Float? { @Composable private fun DisplayUrlWithLoadingSymbol(content: ZoomableContent) { var cnt by remember { mutableStateOf(null) } - val scope = rememberCoroutineScope() LaunchedEffect(Unit) { - scope.launch(Dispatchers.IO) { + launch(Dispatchers.IO) { delay(200) cnt = content } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index 4d387080d..5361b3f15 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -70,7 +70,6 @@ import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext val ChatBubbleShapeMe = RoundedCornerShape(15.dp, 15.dp, 3.dp, 15.dp) val ChatBubbleShapeThem = RoundedCornerShape(3.dp, 15.dp, 15.dp, 15.dp) @@ -348,7 +347,7 @@ fun ChatTimeAgo(time: Long) { var timeStr by remember { mutableStateOf("") } LaunchedEffect(key1 = time) { - withContext(Dispatchers.IO) { + launch(Dispatchers.IO) { timeStr = timeAgoShort(time, context = context) } } 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 da78213a5..808e048af 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 @@ -57,6 +57,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.TopEnd import androidx.compose.ui.Modifier @@ -109,10 +110,12 @@ import com.vitorpamplona.amethyst.service.model.PinListEvent import com.vitorpamplona.amethyst.service.model.PollNoteEvent import com.vitorpamplona.amethyst.service.model.PrivateDmEvent import com.vitorpamplona.amethyst.service.model.ReactionEvent +import com.vitorpamplona.amethyst.service.model.RelaySetEvent import com.vitorpamplona.amethyst.service.model.ReportEvent import com.vitorpamplona.amethyst.service.model.RepostEvent import com.vitorpamplona.amethyst.service.model.TextNoteEvent import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists +import com.vitorpamplona.amethyst.ui.actions.NewRelayListView import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.ClickableUrl import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji @@ -123,6 +126,7 @@ import com.vitorpamplona.amethyst.ui.components.ResizeImage import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.SensitivityWarning +import com.vitorpamplona.amethyst.ui.components.ShowMoreButton import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.components.VideoView import com.vitorpamplona.amethyst.ui.components.ZoomableContent @@ -510,6 +514,10 @@ fun NormalNote( RenderPeopleList(baseNote, backgroundColor, accountViewModel, nav) } + is RelaySetEvent -> { + RelaySetList(baseNote, backgroundColor, accountViewModel, nav) + } + is AudioTrackEvent -> { RenderAudioTrack(baseNote, accountViewModel, nav) } @@ -958,6 +966,23 @@ private fun RenderPrivateMessage( ) } +@Composable +fun RelaySetList( + baseNote: Note, + backgroundColor: Color, + accountViewModel: AccountViewModel, + nav: (String) -> Unit +) { + DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav) + + ReactionsRow(baseNote, accountViewModel, nav) + + Divider( + modifier = Modifier.padding(top = 10.dp), + thickness = 0.25.dp + ) +} + @Composable fun RenderPeopleList( baseNote: Note, @@ -975,6 +1000,139 @@ fun RenderPeopleList( ) } +@Composable +fun DisplayRelaySet( + baseNote: Note, + backgroundColor: Color, + accountViewModel: AccountViewModel, + nav: (String) -> Unit +) { + val noteEvent = baseNote.event as? RelaySetEvent ?: return + + val relays by remember { + mutableStateOf>( + noteEvent.relays().toImmutableList() + ) + } + + var expanded by remember { + mutableStateOf(false) + } + + val toMembersShow = if (expanded) { + relays + } else { + relays.take(3) + } + + val relayListName by remember { + derivedStateOf { + "#${noteEvent.dTag()}" + } + } + + val relayDescription by remember { + derivedStateOf { + noteEvent.description() + } + } + + Text( + text = relayListName, + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .fillMaxWidth() + .padding(5.dp), + textAlign = TextAlign.Center + ) + + relayDescription?.let { + Text( + text = it, + maxLines = 3, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .fillMaxWidth() + .padding(5.dp), + textAlign = TextAlign.Center, + color = Color.Gray + ) + } + + Box { + Column(modifier = Modifier.padding(top = 5.dp)) { + toMembersShow.forEach { relay -> + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = CenterVertically) { + Text( + relay.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/"), + fontWeight = FontWeight.Bold, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .padding(start = 10.dp, bottom = 5.dp) + .weight(1f) + ) + + Column(modifier = Modifier.padding(start = 10.dp)) { + RelayOptionsAction(relay, accountViewModel) + } + } + } + } + + if (relays.size > 3 && !expanded) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .background( + brush = Brush.verticalGradient( + colors = listOf( + backgroundColor.copy(alpha = 0f), + backgroundColor + ) + ) + ) + ) { + ShowMoreButton { + expanded = !expanded + } + } + } + } +} + +@Composable +private fun RelayOptionsAction( + relay: String, + accountViewModel: AccountViewModel +) { + val userStateRelayInfo by accountViewModel.account.userProfile().live().relayInfo.observeAsState() + val isCurrentlyOnTheUsersList by remember(userStateRelayInfo) { + derivedStateOf { + userStateRelayInfo?.user?.latestContactList?.relays()?.none { it.key == relay } == true + } + } + + var wantsToAddRelay by remember { + mutableStateOf("") + } + + if (wantsToAddRelay.isNotEmpty()) { + NewRelayListView({ wantsToAddRelay = "" }, accountViewModel, wantsToAddRelay) + } + + if (isCurrentlyOnTheUsersList) { + AddRelayButton { wantsToAddRelay = relay } + } else { + RemoveRelayButton { wantsToAddRelay = relay } + } +} + @OptIn(ExperimentalLayoutApi::class) @Composable fun DisplayPeopleList( 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 e74ef26a2..198b1c7ff 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 @@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent import com.vitorpamplona.amethyst.service.model.PeopleListEvent import com.vitorpamplona.amethyst.service.model.PinListEvent import com.vitorpamplona.amethyst.service.model.PollNoteEvent +import com.vitorpamplona.amethyst.service.model.RelaySetEvent import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists import com.vitorpamplona.amethyst.ui.actions.toImmutableListOfLists import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status @@ -374,6 +375,13 @@ fun NoteMaster( accountViewModel, nav ) + } else if (noteEvent is RelaySetEvent) { + DisplayRelaySet( + baseNote, + MaterialTheme.colors.background, + accountViewModel, + nav + ) } else if (noteEvent is AppDefinitionEvent) { RenderAppDefinition(baseNote, accountViewModel, nav) } else if (noteEvent is HighlightEvent) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt index bcd37c3ac..96f21adea 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt @@ -45,6 +45,7 @@ import com.vitorpamplona.amethyst.ui.screen.ChatroomListFeedView import com.vitorpamplona.amethyst.ui.screen.FeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListKnownFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @@ -150,9 +151,11 @@ fun ChatroomListScreen( @Composable fun WatchAccountForListScreen(knownFeedViewModel: NostrChatroomListKnownFeedViewModel, newFeedViewModel: NostrChatroomListNewFeedViewModel, accountViewModel: AccountViewModel) { LaunchedEffect(accountViewModel) { - NostrChatroomListDataSource.start() - knownFeedViewModel.invalidateData(true) - newFeedViewModel.invalidateData(true) + launch(Dispatchers.IO) { + NostrChatroomListDataSource.start() + knownFeedViewModel.invalidateData(true) + newFeedViewModel.invalidateData(true) + } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index 8fa3046de..e60c5d6e5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -51,7 +51,7 @@ fun ChatroomScreen( var userRoom by remember { mutableStateOf(null) } LaunchedEffect(userId) { - withContext(Dispatchers.IO) { + launch(Dispatchers.IO) { val newUser = LocalCache.checkGetOrCreateUser(userId) if (newUser != userRoom) { userRoom = newUser @@ -105,10 +105,10 @@ fun ChatroomScreen( val lifeCycleOwner = LocalLifecycleOwner.current LaunchedEffect(baseUser, accountViewModel) { - NostrChatroomDataSource.start() - feedViewModel.invalidateData() - launch(Dispatchers.IO) { + NostrChatroomDataSource.start() + feedViewModel.invalidateData() + newPostModel.imageUploadingError.collect { error -> withContext(Dispatchers.Main) { Toast.makeText(context, error, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt index ca3a2592e..a88bbf5f8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt @@ -138,17 +138,15 @@ fun WatchAccountForHomeScreen( accountViewModel: AccountViewModel ) { val accountState by accountViewModel.accountLiveData.observeAsState() - val account = remember(accountState) { accountState?.account } ?: return - val scope = rememberCoroutineScope() var firstTime by remember(accountViewModel) { mutableStateOf(true) } - LaunchedEffect(accountViewModel, account.defaultHomeFollowList) { + LaunchedEffect(accountViewModel, accountState?.account?.defaultHomeFollowList) { // Only invalidate when things change. Not in the first run if (firstTime) { firstTime = false } else { - scope.launch(Dispatchers.IO) { + launch(Dispatchers.IO) { NostrHomeDataSource.invalidateFilters() homeFeedViewModel.invalidateDataAndSendToTop(true) repliesFeedViewModel.invalidateDataAndSendToTop(true) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt index a1c6188d7..e357e1322 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/LoadRedirectScreen.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent import com.vitorpamplona.amethyst.service.model.PrivateDmEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext @Composable fun LoadRedirectScreen(eventId: String?, navController: NavController) { @@ -42,7 +41,7 @@ fun LoadRedirectScreen(eventId: String?, navController: NavController) { } LaunchedEffect(eventId) { - withContext(Dispatchers.IO) { + launch(Dispatchers.IO) { val newNoteBase = LocalCache.checkGetOrCreateNote(eventId) if (newNoteBase != noteBase) { noteBase = newNoteBase diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt index 8f49c9c28..46e8b25cd 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt @@ -145,9 +145,11 @@ fun SearchScreen( @Composable fun WatchAccountForSearchScreen(searchFeedViewModel: NostrGlobalFeedViewModel, accountViewModel: AccountViewModel) { LaunchedEffect(accountViewModel) { - NostrGlobalDataSource.resetFilters() - NostrSearchEventOrUserDataSource.start() - searchFeedViewModel.invalidateData(true) + launch(Dispatchers.IO) { + NostrGlobalDataSource.resetFilters() + NostrSearchEventOrUserDataSource.start() + searchFeedViewModel.invalidateData(true) + } } }