diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 79a6d4a8a..aad6c7291 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -2070,6 +2070,13 @@ class Account( relays = groupRelays, ) + // The MLS commit has already been applied to the local group state — + // surface the new member list in the chatroom now so observers (e.g. + // MarmotGroupInfoScreen) update without waiting for our own commit to + // loop back through the relay. + val chatroom = marmotGroupList.getOrCreateGroup(nostrGroupId) + manager.syncMetadataTo(nostrGroupId, chatroom) + Log.d("MarmotDbg") { "addMarmotGroupMember: built commit kind=${commitEvent.signedEvent.kind} id=${commitEvent.signedEvent.id.take(8)}… " + "welcomeDelivery=${if (welcomeDelivery != null) "present(giftWrapId=${welcomeDelivery.giftWrapEvent.id.take(8)}…)" else "null"}" @@ -2270,6 +2277,8 @@ class Account( if (!isWriteable()) return val outbound = manager.removeMember(nostrGroupId, targetLeafIndex) + val chatroom = marmotGroupList.getOrCreateGroup(nostrGroupId) + manager.syncMetadataTo(nostrGroupId, chatroom) client.publish(outbound.signedEvent, groupRelays) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt index 1979c6076..706e10f64 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt @@ -58,7 +58,6 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.marmot.GroupMemberInfo import com.vitorpamplona.amethyst.ui.navigation.navs.INav @@ -85,19 +84,13 @@ fun MarmotGroupInfoScreen( val groupDescription by chatroom.description.collectAsStateWithLifecycle() val adminPubkeys by chatroom.adminPubkeys.collectAsStateWithLifecycle() val groupRelays by chatroom.relays.collectAsStateWithLifecycle() - var members by remember { mutableStateOf(emptyList()) } + val members by chatroom.members.collectAsStateWithLifecycle() var showLeaveDialog by remember { mutableStateOf(false) } var isLeaving by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() val myPubkey = accountViewModel.account.signer.pubKey val context = LocalContext.current - LifecycleResumeEffect(nostrGroupId) { - members = accountViewModel.marmotGroupMembers(nostrGroupId) - chatroom.memberCount.value = members.size - onPauseOrDispose {} - } - Scaffold( topBar = { TopAppBar( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/RemoveMemberScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/RemoveMemberScreen.kt index f6b7b56da..9afb0ebb0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/RemoveMemberScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/RemoveMemberScreen.kt @@ -44,7 +44,6 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -55,6 +54,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.marmot.GroupMemberInfo import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.UserPicture @@ -71,17 +71,17 @@ fun RemoveMemberScreen( accountViewModel: AccountViewModel, nav: INav, ) { - var members by remember { mutableStateOf(emptyList()) } + val chatroom = + remember(nostrGroupId) { + accountViewModel.account.marmotGroupList.getOrCreateGroup(nostrGroupId) + } + val members by chatroom.members.collectAsStateWithLifecycle() var memberToRemove by remember { mutableStateOf(null) } var isRemoving by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() val myPubkey = accountViewModel.account.signer.pubKey val context = LocalContext.current - LaunchedEffect(nostrGroupId) { - members = accountViewModel.marmotGroupMembers(nostrGroupId) - } - Scaffold( topBar = { TopAppBar( @@ -155,7 +155,6 @@ fun RemoveMemberScreen( scope.launch(Dispatchers.IO) { try { accountViewModel.removeMarmotGroupMember(nostrGroupId, member.leafIndex) - members = accountViewModel.marmotGroupMembers(nostrGroupId) isRemoving = false launch(Dispatchers.Main) { Toast diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/marmot/MarmotManager.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/marmot/MarmotManager.kt index d56abe2c0..6592db1b5 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/marmot/MarmotManager.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/marmot/MarmotManager.kt @@ -437,7 +437,9 @@ class MarmotManager( chatroom.adminPubkeys.value = metadata.adminPubkeys chatroom.relays.value = metadata.relays } - chatroom.memberCount.value = memberCount(nostrGroupId) + val members = memberPubkeys(nostrGroupId) + chatroom.members.value = members + chatroom.memberCount.value = members.size } } diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/marmotGroups/MarmotGroupChatroom.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/marmotGroups/MarmotGroupChatroom.kt index 54b7f102e..bf9ec65a0 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/marmotGroups/MarmotGroupChatroom.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/marmotGroups/MarmotGroupChatroom.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.commons.model.marmotGroups import androidx.compose.runtime.Stable +import com.vitorpamplona.amethyst.commons.marmot.GroupMemberInfo import com.vitorpamplona.amethyst.commons.model.Channel.Companion.DefaultFeedOrder import com.vitorpamplona.amethyst.commons.model.ListChange import com.vitorpamplona.amethyst.commons.model.Note @@ -46,6 +47,7 @@ class MarmotGroupChatroom( var adminPubkeys = MutableStateFlow>(emptyList()) var relays = MutableStateFlow>(emptyList()) var memberCount = MutableStateFlow(0) + var members = MutableStateFlow>(emptyList()) var newestMessage: Note? = null val unreadCount = MutableStateFlow(0)