Use runBlocking in mapEventToSet(). Rework and simplify fetching in FollowSetFeedFilter. Make FollowSetActions dropdown menu more reliable.

This commit is contained in:
KotlinGeekDev
2025-08-10 02:21:18 +01:00
parent 653494e922
commit 2238f4a807
4 changed files with 33 additions and 36 deletions
@@ -23,31 +23,24 @@ package com.vitorpamplona.amethyst.ui.dal
import android.util.Log import android.util.Log
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.FollowSet import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.FollowSet
import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking
import kotlin.coroutines.cancellation.CancellationException
class FollowSetFeedFilter( class FollowSetFeedFilter(
val account: Account, val account: Account,
) : FeedFilter<FollowSet>() { ) : FeedFilter<FollowSet>() {
override fun feedKey(): String = account.userProfile().pubkeyHex override fun feedKey(): String = account.userProfile().pubkeyHex + "-followsets"
override fun feed(): List<FollowSet> { override fun feed(): List<FollowSet> =
val followSetCache = mutableListOf<FollowSet>() runBlocking(account.scope.coroutineContext) {
account.scope.launch { try {
val userFollowSets = account.userProfile().followSetNotes val fetchedSets = account.getFollowSetNotes()
if (userFollowSets.isEmpty()) { val followSets = fetchedSets.map { account.mapNoteToFollowSet(it) }
try { println("Updated follow set size for feed filter: ${followSets.size}")
account.getFollowSetNotes() followSets
} catch (e: Exception) { } catch (e: Exception) {
if (e is CancellationException) throw e // if (e is CancellationException) throw e
Log.e("HiddenAccountsFeedFilter", "Failed to load follow lists: ${e.message}") Log.e(this@FollowSetFeedFilter.javaClass.simpleName, "Failed to load follow lists: ${e.message}")
null throw e
}
}
userFollowSets.map { account.mapNoteToFollowSet(it) }.forEach {
followSetCache.add(it)
} }
} }
return followSetCache.toList()
}
} }
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Stable
import com.vitorpamplona.quartz.nip01Core.core.value import com.vitorpamplona.quartz.nip01Core.core.value
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
import kotlinx.coroutines.runBlocking
@Stable @Stable
data class FollowSet( data class FollowSet(
@@ -34,7 +35,7 @@ data class FollowSet(
val profileList: Set<String>, val profileList: Set<String>,
) : NostrList(listVisibility = visibility, content = profileList) { ) : NostrList(listVisibility = visibility, content = profileList) {
companion object { companion object {
suspend fun mapEventToSet( fun mapEventToSet(
event: PeopleListEvent, event: PeopleListEvent,
signer: NostrSigner, signer: NostrSigner,
): FollowSet { ): FollowSet {
@@ -44,8 +45,7 @@ data class FollowSet(
val listDescription = event.description() ?: "" val listDescription = event.description() ?: ""
val publicFollows = event.publicPeople().map { it.toTagArray() }.map { it.value() } val publicFollows = event.publicPeople().map { it.toTagArray() }.map { it.value() }
val privateFollows = val privateFollows =
event runBlocking { event.privatePeople(signer) }
.privatePeople(signer)
?.map { it.toTagArray() } ?.map { it.toTagArray() }
?.map { it.value() } ?: emptyList() ?.map { it.value() } ?: emptyList()
return if (publicFollows.isEmpty() && privateFollows.isNotEmpty()) { return if (publicFollows.isEmpty() && privateFollows.isNotEmpty()) {
@@ -49,9 +49,6 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@@ -67,23 +64,21 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
import kotlinx.coroutines.launch
import java.util.UUID import java.util.UUID
@Composable @Composable
fun FollowSetsActionMenu( fun FollowSetsActionMenu(
isMenuOpen: Boolean,
setMenuOpenState: () -> Unit,
userHex: String, userHex: String,
followLists: List<FollowSet>, followLists: List<FollowSet>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
addUser: (followListItemIndex: Int, list: FollowSet) -> Unit, addUser: (followListItemIndex: Int, list: FollowSet) -> Unit,
removeUser: (followListItemIndex: Int) -> Unit, removeUser: (followListItemIndex: Int) -> Unit,
) { ) {
val (isMenuOpen, setMenuValue) = remember { mutableStateOf(false) }
val uiScope = rememberCoroutineScope()
Column { Column {
TextButton( TextButton(
onClick = { setMenuValue(true) }, onClick = setMenuOpenState,
shape = ButtonBorder.copy(topStart = CornerSize(0f), bottomStart = CornerSize(0f)), shape = ButtonBorder.copy(topStart = CornerSize(0f), bottomStart = CornerSize(0f)),
colors = colors =
ButtonDefaults ButtonDefaults
@@ -118,11 +113,7 @@ fun FollowSetsActionMenu(
DropdownMenu( DropdownMenu(
expanded = isMenuOpen, expanded = isMenuOpen,
onDismissRequest = { onDismissRequest = setMenuOpenState,
uiScope.launch {
setMenuValue(false)
}
},
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
properties = PopupProperties(usePlatformDefaultWidth = true), properties = PopupProperties(usePlatformDefaultWidth = true),
) { ) {
@@ -25,13 +25,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.toMutableStateList import androidx.compose.runtime.toMutableStateList
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.observeAccountIsHiddenUser import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.observeAccountIsHiddenUser
import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.zaps.ShowUserButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.zaps.ShowUserButton
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable @Composable
fun ProfileActions( fun ProfileActions(
@@ -41,6 +45,8 @@ fun ProfileActions(
) { ) {
val tempFollowLists = remember { generateFollowLists().toMutableStateList() } val tempFollowLists = remember { generateFollowLists().toMutableStateList() }
val actualFollowLists by accountViewModel.followSetsFlow.collectAsState() val actualFollowLists by accountViewModel.followSetsFlow.collectAsState()
val (isMenuOpen, setMenuValue) = remember { mutableStateOf(false) }
val uiScope = rememberCoroutineScope()
val isMe by val isMe by
remember(accountViewModel) { derivedStateOf { accountViewModel.userProfile() == baseUser } } remember(accountViewModel) { derivedStateOf { accountViewModel.userProfile() == baseUser } }
@@ -57,6 +63,13 @@ fun ProfileActions(
} }
FollowSetsActionMenu( FollowSetsActionMenu(
isMenuOpen = isMenuOpen,
setMenuOpenState = {
uiScope.launch {
delay(100)
setMenuValue(!isMenuOpen)
}
},
userHex = baseUser.pubkeyHex, userHex = baseUser.pubkeyHex,
followLists = actualFollowLists, followLists = actualFollowLists,
addUser = { index, list -> addUser = { index, list ->