From d869c766267ac9187ad72dabbca7cab93cf82c40 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Wed, 15 Jan 2025 13:52:19 +1100 Subject: [PATCH] Delete a group directly if it's already destroyed (#876) --- .../v2/menus/ConversationMenuHelper.kt | 2 +- .../securesms/groups/GroupManagerV2Impl.kt | 106 +++++++++--------- .../messaging/groups/GroupManagerV2.kt | 5 +- 3 files changed, 56 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 39388393f3..81bb10a10c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -414,7 +414,7 @@ object ConversationMenuHelper { doLeave = { try { channel.send(GroupLeavingStatus.Leaving) - groupManager.leaveGroup(accountId, true) + groupManager.leaveGroup(accountId) channel.send(GroupLeavingStatus.Left) } catch (e: Exception) { channel.send(GroupLeavingStatus.Error) diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt index 81d483d821..d3939a9518 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManagerV2Impl.kt @@ -414,71 +414,73 @@ class GroupManagerV2Impl @Inject constructor( } } - override suspend fun leaveGroup(groupId: AccountId, deleteOnLeave: Boolean) = withContext(dispatcher + SupervisorJob()) { + override suspend fun leaveGroup(groupId: AccountId) = withContext(dispatcher + SupervisorJob()) { val group = configFactory.getGroup(groupId) - // Only send the left/left notification group message when we are not kicked and we are not the only admin (only admin has a special treatment) - val weAreTheOnlyAdmin = configFactory.withGroupConfigs(groupId) { config -> - val allMembers = config.groupMembers.all() - allMembers.count { it.admin } == 1 && - allMembers.first { it.admin }.accountIdString() == storage.getUserPublicKey() - } - - if (group != null && !group.kicked && !weAreTheOnlyAdmin) { - val destination = Destination.ClosedGroup(groupId.hexString) - val sendMessageTasks = mutableListOf>() - - // Always send a "XXX left" message to the group if we can - sendMessageTasks += async { - MessageSender.send( - GroupUpdated( - GroupUpdateMessage.newBuilder() - .setMemberLeftNotificationMessage(DataMessage.GroupUpdateMemberLeftNotificationMessage.getDefaultInstance()) - .build() - ), - destination, - isSyncMessage = false - ).await() + if (group?.destroyed != true) { + // Only send the left/left notification group message when we are not kicked and we are not the only admin (only admin has a special treatment) + val weAreTheOnlyAdmin = configFactory.withGroupConfigs(groupId) { config -> + val allMembers = config.groupMembers.all() + allMembers.count { it.admin } == 1 && + allMembers.first { it.admin } + .accountIdString() == storage.getUserPublicKey() } + if (group != null && !group.kicked && !weAreTheOnlyAdmin) { + val destination = Destination.ClosedGroup(groupId.hexString) + val sendMessageTasks = mutableListOf>() + + // Always send a "XXX left" message to the group if we can + sendMessageTasks += async { + MessageSender.send( + GroupUpdated( + GroupUpdateMessage.newBuilder() + .setMemberLeftNotificationMessage(DataMessage.GroupUpdateMemberLeftNotificationMessage.getDefaultInstance()) + .build() + ), + destination, + isSyncMessage = false + ).await() + } - // If we are not the only admin, send a left message for other admin to handle the member removal - sendMessageTasks += async { - MessageSender.send( - GroupUpdated( - GroupUpdateMessage.newBuilder() - .setMemberLeftMessage(DataMessage.GroupUpdateMemberLeftMessage.getDefaultInstance()) - .build() - ), - destination, - isSyncMessage = false - ).await() - } - sendMessageTasks.awaitAll() - } + // If we are not the only admin, send a left message for other admin to handle the member removal + sendMessageTasks += async { + MessageSender.send( + GroupUpdated( + GroupUpdateMessage.newBuilder() + .setMemberLeftMessage(DataMessage.GroupUpdateMemberLeftMessage.getDefaultInstance()) + .build() + ), + destination, + isSyncMessage = false + ).await() + } - // If we are the only admin, leaving this group will destroy the group - if (weAreTheOnlyAdmin) { - configFactory.withMutableGroupConfigs(groupId) { configs -> - configs.groupInfo.destroyGroup() + sendMessageTasks.awaitAll() } - // Must wait until the config is pushed, otherwise if we go through the rest - // of the code it will destroy the conversation, destroying the necessary configs - // along the way, we won't be able to push the "destroyed" state anymore. - configFactory.waitUntilGroupConfigsPushed(groupId) + // If we are the only admin, leaving this group will destroy the group + if (weAreTheOnlyAdmin) { + configFactory.withMutableGroupConfigs(groupId) { configs -> + configs.groupInfo.destroyGroup() + } + + // Must wait until the config is pushed, otherwise if we go through the rest + // of the code it will destroy the conversation, destroying the necessary configs + // along the way, we won't be able to push the "destroyed" state anymore. + configFactory.waitUntilGroupConfigsPushed(groupId) + } } pollerFactory.pollerFor(groupId)?.stop() - if (deleteOnLeave) { - storage.getThreadId(Address.fromSerialized(groupId.hexString)) - ?.let(storage::deleteConversation) - configFactory.removeGroup(groupId) - lokiAPIDatabase.clearLastMessageHashes(groupId.hexString) - lokiAPIDatabase.clearReceivedMessageHashValues(groupId.hexString) - } + // Delete conversation and group configs + storage.getThreadId(Address.fromSerialized(groupId.hexString)) + ?.let(storage::deleteConversation) + configFactory.removeGroup(groupId) + lokiAPIDatabase.clearLastMessageHashes(groupId.hexString) + lokiAPIDatabase.clearReceivedMessageHashValues(groupId.hexString) } override suspend fun promoteMember( diff --git a/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt b/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt index 64c7e48e6e..27295a9306 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/groups/GroupManagerV2.kt @@ -43,10 +43,7 @@ interface GroupManagerV2 { ) suspend fun handleMemberLeftMessage(memberId: AccountId, group: AccountId) - - suspend fun leaveGroup(groupId: - AccountId, deleteOnLeave: Boolean) - + suspend fun leaveGroup(groupId: AccountId) suspend fun promoteMember(group: AccountId, members: List) suspend fun handleInvitation(