diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/handler/AdminStateSync.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/handler/AdminStateSync.kt index 7898c82a20..3fbb906170 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/handler/AdminStateSync.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/handler/AdminStateSync.kt @@ -2,12 +2,17 @@ package org.thoughtcrime.securesms.groups.handler import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.launch +import network.loki.messenger.libsession_util.util.GroupInfo +import network.loki.messenger.libsession_util.util.GroupMember import org.session.libsession.utilities.ConfigFactoryProtocol import org.session.libsession.utilities.ConfigUpdateNotification import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.getGroup +import org.session.libsignal.utilities.AccountId +import java.util.EnumSet import javax.inject.Inject import javax.inject.Singleton @@ -30,25 +35,48 @@ class AdminStateSync @Inject constructor( job = GlobalScope.launch { configFactory.configUpdateNotifications - .filterIsInstance() - .collect { update -> + .filter { it is ConfigUpdateNotification.UserConfigsMerged || it == ConfigUpdateNotification.UserConfigsModified } + .collect { val localNumber = preferences.getLocalNumber() ?: return@collect - val isAdmin = configFactory.getGroup(update.groupId)?.hasAdminKey() == true - - if (isAdmin) { - // If the UserGroupConfig says we are admin, we'll set the group member - // config's promotion status to "accepted" mark ourselves admin regardless. - configFactory.withMutableGroupConfigs(update.groupId) { groupConfigs -> - groupConfigs.groupMembers.get(localNumber)?.let { me -> - me.setPromotionAccepted() - groupConfigs.groupMembers.set(me) + + // Go through evey user groups and if we are admin of any of the groups, + // make sure we mark any pending group promotion status as "accepted" + + val allAdminGroups = configFactory.withUserConfigs { configs -> + configs.userGroups.all() + .asSequence() + .mapNotNull { + if ((it as? GroupInfo.ClosedGroupInfo)?.hasAdminKey() == true) { + it.groupAccountId + } else { + null + } + } + } + + val groupToMarkAccepted = allAdminGroups + .filter { groupId -> isMemberPromotionPending(groupId, localNumber) } + + for (groupId in groupToMarkAccepted) { + configFactory.withMutableGroupConfigs(groupId) { groupConfigs -> + groupConfigs.groupMembers.get(localNumber)?.let { member -> + member.setPromotionAccepted() + groupConfigs.groupMembers.set(member) } } - } else { - // You can't really change the group config if you are not admin so the reverse - // logic doesn't need to be done. } } } } + + private fun isMemberPromotionPending(groupId: AccountId, localNumber: String): Boolean { + return configFactory.withGroupConfigs(groupId) { groupConfigs -> + val status = groupConfigs.groupMembers.get(localNumber)?.status + status != null && status in EnumSet.of( + GroupMember.Status.PROMOTION_SENT, + GroupMember.Status.PROMOTION_FAILED, + GroupMember.Status.PROMOTION_NOT_SENT + ) + } + } } \ No newline at end of file