diff --git a/commonsUI/src/commonMain/composeResources/values/strings.xml b/commonsUI/src/commonMain/composeResources/values/strings.xml index 1003a3ee26..d83cb04e80 100644 --- a/commonsUI/src/commonMain/composeResources/values/strings.xml +++ b/commonsUI/src/commonMain/composeResources/values/strings.xml @@ -3642,6 +3642,8 @@ %1$d members Ban + Ban member? + They can no longer post, and their messages are hidden from everyone. Other apps may remove the community from their list. They can still read new messages until you also remove them from the community. You can unban them later. Make admin Remove admin Could not update this member's roles. diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMembersScreen.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMembersScreen.kt index 8df45dbba3..0ee288bd3b 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMembersScreen.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMembersScreen.kt @@ -63,6 +63,8 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.back import com.vitorpamplona.amethyst.commons.resources.cancel import com.vitorpamplona.amethyst.commons.resources.concord_members_ban +import com.vitorpamplona.amethyst.commons.resources.concord_members_ban_message +import com.vitorpamplona.amethyst.commons.resources.concord_members_ban_title import com.vitorpamplona.amethyst.commons.resources.concord_members_empty import com.vitorpamplona.amethyst.commons.resources.concord_members_make_admin import com.vitorpamplona.amethyst.commons.resources.concord_members_remove @@ -92,6 +94,7 @@ import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.quartz.concord.cord04Roles.ConcordPermissions import com.vitorpamplona.quartz.nip01Core.core.HexKey import kotlinx.coroutines.flow.MutableStateFlow +import org.jetbrains.compose.resources.StringResource import com.vitorpamplona.amethyst.commons.icons.symbols.Icon as SymbolIcon /** @@ -289,9 +292,28 @@ private fun ConcordMemberRow( ) } + // A ban is reversible here, but not for the banned member: clients such as Armada drop the + // community from a banned member's list on sight, so a mis-tap still costs them the community. + var confirmBan by remember { mutableStateOf(false) } + if (confirmBan) { + ConcordConfirmMemberActionDialog( + title = Res.string.concord_members_ban_title, + message = Res.string.concord_members_ban_message, + confirm = Res.string.concord_members_ban, + onConfirm = { + accountViewModel.setConcordBan(communityId, entry.pubkey, ban = true) + confirmBan = false + }, + onDismiss = { confirmBan = false }, + ) + } + var confirmRemove by remember { mutableStateOf(false) } if (confirmRemove) { - ConcordRemoveMemberDialog( + ConcordConfirmMemberActionDialog( + title = Res.string.concord_members_remove_title, + message = Res.string.concord_members_remove_message, + confirm = Res.string.concord_members_remove_confirm, onConfirm = { accountViewModel.removeConcordMember(communityId, entry.pubkey) confirmRemove = false @@ -357,7 +379,8 @@ private fun ConcordMemberRow( DropdownMenuItem( text = { Text(stringRes(if (isBanned) Res.string.concord_members_unban else Res.string.concord_members_ban)) }, onClick = { - accountViewModel.setConcordBan(communityId, entry.pubkey, ban = !isBanned) + // Unbanning restores access, so only a ban asks first. + if (isBanned) accountViewModel.setConcordBan(communityId, entry.pubkey, ban = false) else confirmBan = true expanded = false }, ) @@ -471,17 +494,20 @@ private fun ConcordRolesDialog( /** Confirms a hard removal — spells out that it rotates the community key (CORD-06). */ @Composable -private fun ConcordRemoveMemberDialog( +private fun ConcordConfirmMemberActionDialog( + title: StringResource, + message: StringResource, + confirm: StringResource, onConfirm: () -> Unit, onDismiss: () -> Unit, ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text(stringRes(Res.string.concord_members_remove_title)) }, - text = { Text(stringRes(Res.string.concord_members_remove_message)) }, + title = { Text(stringRes(title)) }, + text = { Text(stringRes(message)) }, confirmButton = { TextButton(onClick = onConfirm) { - Text(stringRes(Res.string.concord_members_remove_confirm), color = MaterialTheme.colorScheme.error) + Text(stringRes(confirm), color = MaterialTheme.colorScheme.error) } }, dismissButton = {