mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 08:09:12 +01:00
Add send and receive support for group member labels.
This commit is contained in:
committed by
Greyson Parrelli
parent
ce46c44b5d
commit
0a572153f0
@@ -21,6 +21,7 @@ import org.signal.core.util.exists
|
||||
import org.signal.core.util.isAbsent
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.optionalString
|
||||
import org.signal.core.util.orNull
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.readToMap
|
||||
import org.signal.core.util.readToSingleInt
|
||||
@@ -54,6 +55,7 @@ import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.groups.GroupId.Push
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabel
|
||||
import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor
|
||||
import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -1271,6 +1273,17 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) :
|
||||
.sortedBy { it.toString() }
|
||||
.toList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the member label for a specific member in the group, or null if the member is not found.
|
||||
*/
|
||||
fun memberLabel(aci: ACI): MemberLabel? {
|
||||
return decryptedGroup
|
||||
.members
|
||||
.findMemberByAci(aci)
|
||||
.orNull()
|
||||
?.let { member -> MemberLabel(member.labelEmoji, member.labelString) }
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(BadGroupIdException::class)
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import org.signal.core.models.ServiceId;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.zkgroup.VerificationFailedException;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
@@ -22,7 +23,6 @@ import org.thoughtcrime.securesms.groups.v2.processing.GroupUpdateResult;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
|
||||
import org.signal.core.models.ServiceId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
@@ -233,6 +233,19 @@ public final class GroupManager {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static void updateMemberLabel(@NonNull Context context, @NonNull GroupId.V2 groupId, @NonNull String labelString, @NonNull String labelEmoji)
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException, GroupChangeBusyException
|
||||
{
|
||||
if (!groupId.isV2()) {
|
||||
throw new GroupChangeFailedException("Not gv2");
|
||||
}
|
||||
|
||||
try (GroupManagerV2.GroupEditor editor = new GroupManagerV2(context).edit(groupId)) {
|
||||
editor.updateMemberLabel(labelString, labelEmoji);
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static void revokeInvites(@NonNull Context context,
|
||||
@NonNull ServiceId authServiceId,
|
||||
|
||||
@@ -358,6 +358,14 @@ final class GroupManagerV2 {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@NonNull
|
||||
GroupManager.GroupActionResult updateMemberLabel(@NonNull String labelString, @NonNull String labelEmoji)
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
return commitChangeWithConflictResolution(selfAci, groupOperations.createChangeMemberLabel(selfAci, labelString, labelEmoji));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@NonNull GroupManager.GroupActionResult revokeInvites(@NonNull ServiceId authServiceId, @NonNull Collection<UuidCiphertext> uuidCipherTexts, boolean sendToMembers)
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.groups.memberlabel
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.models.ServiceId
|
||||
import org.signal.core.util.orNull
|
||||
import org.thoughtcrime.securesms.database.GroupTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.groups.GroupManager
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
|
||||
/**
|
||||
* Handles the retrieval and modification of group member labels.
|
||||
*/
|
||||
class MemberLabelRepository(
|
||||
private val groupId: GroupId.V2,
|
||||
private val context: Context = AppDependencies.application,
|
||||
private val groupsTable: GroupTable = SignalDatabase.groups
|
||||
) {
|
||||
/**
|
||||
* Gets the member label for a specific recipient in the group.
|
||||
*/
|
||||
suspend fun getLabel(recipientId: RecipientId): MemberLabel? = withContext(Dispatchers.IO) {
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
val aci = recipient.serviceId.orNull() as? ServiceId.ACI ?: return@withContext null
|
||||
val groupRecord = groupsTable.getGroup(groupId).orNull() ?: return@withContext null
|
||||
|
||||
return@withContext groupRecord.requireV2GroupProperties().memberLabel(aci)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the group member label for the current user.
|
||||
*/
|
||||
suspend fun setLabel(label: MemberLabel): Unit = withContext(Dispatchers.IO) {
|
||||
GroupManager.updateMemberLabel(context, groupId, label.text, label.emoji ?: "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the group member label for the current user.
|
||||
*/
|
||||
suspend fun removeLabel(): Unit = withContext(Dispatchers.IO) {
|
||||
GroupManager.updateMemberLabel(context, groupId, "", "")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A member's custom label within a group.
|
||||
*/
|
||||
data class MemberLabel(
|
||||
val emoji: String?,
|
||||
val text: String
|
||||
)
|
||||
Reference in New Issue
Block a user