mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-18 05:57:44 +00:00
refactor: turn inner wrapped group edit calls into synchronous calls to remove unnecessary nesting
This commit is contained in:
parent
f45a285141
commit
c8f1c862fb
@ -280,18 +280,15 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
ClosedGroupsProtocolV2.explicitLeave(this, groupPublicKey!!)
|
ClosedGroupsProtocolV2.explicitLeave(this, groupPublicKey!!)
|
||||||
} else {
|
} else {
|
||||||
task {
|
task {
|
||||||
val name =
|
if (hasNameChanged) {
|
||||||
if (hasNameChanged) ClosedGroupsProtocolV2.explicitNameChange(this@EditClosedGroupActivity,groupPublicKey!!,name)
|
ClosedGroupsProtocolV2.explicitNameChange(this@EditClosedGroupActivity, groupPublicKey!!, name)
|
||||||
else Promise.of(Unit)
|
}
|
||||||
name.get()
|
|
||||||
members.filterNot { it in originalMembers }.let { adds ->
|
members.filterNot { it in originalMembers }.let { adds ->
|
||||||
if (adds.isNotEmpty()) ClosedGroupsProtocolV2.explicitAddMembers(this@EditClosedGroupActivity, groupPublicKey!!, adds.map { it.address.serialize() })
|
if (adds.isNotEmpty()) ClosedGroupsProtocolV2.explicitAddMembers(this@EditClosedGroupActivity, groupPublicKey!!, adds.map { it.address.serialize() })
|
||||||
else Promise.of(Unit)
|
}
|
||||||
}.get()
|
|
||||||
originalMembers.filterNot { it in members }.let { removes ->
|
originalMembers.filterNot { it in members }.let { removes ->
|
||||||
if (removes.isNotEmpty()) ClosedGroupsProtocolV2.explicitRemoveMembers(this@EditClosedGroupActivity, groupPublicKey!!, removes.map { it.address.serialize() })
|
if (removes.isNotEmpty()) ClosedGroupsProtocolV2.explicitRemoveMembers(this@EditClosedGroupActivity, groupPublicKey!!, removes.map { it.address.serialize() })
|
||||||
else Promise.of(Unit)
|
}
|
||||||
}.get()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
promise.successUi {
|
promise.successUi {
|
||||||
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.loki.protocol
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.deferred
|
import nl.komponents.kovenant.deferred
|
||||||
@ -129,147 +130,115 @@ object ClosedGroupsProtocolV2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun explicitAddMembers(context: Context, groupPublicKey: String, membersToAdd: List<String>): Promise<Any, java.lang.Exception> {
|
fun explicitAddMembers(context: Context, groupPublicKey: String, membersToAdd: List<String>) {
|
||||||
return task {
|
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
||||||
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
|
||||||
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
|
||||||
val groupID = doubleEncodeGroupID(groupPublicKey)
|
|
||||||
val group = groupDB.getGroup(groupID).orNull()
|
|
||||||
if (group == null) {
|
|
||||||
Log.d("Loki", "Can't leave nonexistent closed group.")
|
|
||||||
return@task Error.NoThread
|
|
||||||
}
|
|
||||||
val updatedMembers = group.members.map { it.serialize() }.toSet() + membersToAdd
|
|
||||||
// Save the new group members
|
|
||||||
groupDB.updateMembers(groupID, updatedMembers.map { Address.fromSerialized(it) })
|
|
||||||
val membersAsData = updatedMembers.map { Hex.fromStringCondensed(it) }
|
|
||||||
val newMembersAsData = membersToAdd.map { Hex.fromStringCondensed(it) }
|
|
||||||
val admins = group.admins.map { it.serialize() }
|
|
||||||
val adminsAsData = admins.map { Hex.fromStringCondensed(it) }
|
|
||||||
val sentTime = System.currentTimeMillis()
|
|
||||||
val encryptionKeyPair = pendingKeyPair.getOrElse(groupPublicKey) {
|
|
||||||
Optional.fromNullable(apiDB.getLatestClosedGroupEncryptionKeyPair(groupPublicKey))
|
|
||||||
}.orNull()
|
|
||||||
if (encryptionKeyPair == null) {
|
|
||||||
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
|
||||||
return@task Error.NoKeyPair
|
|
||||||
}
|
|
||||||
val name = group.title
|
|
||||||
// Send the update to the group
|
|
||||||
val memberUpdateKind = ClosedGroupUpdateMessageSendJobV2.Kind.AddMembers(newMembersAsData)
|
|
||||||
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, memberUpdateKind, sentTime)
|
|
||||||
job.setContext(context)
|
|
||||||
job.onRun() // Run the job immediately
|
|
||||||
// Notify the user
|
|
||||||
val infoType = GroupContext.Type.UPDATE
|
|
||||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
|
||||||
insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
|
||||||
// Send closed group update messages to any new members individually
|
|
||||||
for (member in membersToAdd) {
|
|
||||||
@Suppress("NAME_SHADOWING")
|
|
||||||
val closedGroupNewKind = ClosedGroupUpdateMessageSendJobV2.Kind.New(Hex.fromStringCondensed(groupPublicKey), name, encryptionKeyPair, membersAsData, adminsAsData)
|
|
||||||
@Suppress("NAME_SHADOWING")
|
|
||||||
val newMemberJob = ClosedGroupUpdateMessageSendJobV2(member, closedGroupNewKind, sentTime)
|
|
||||||
ApplicationContext.getInstance(context).jobManager.add(newMemberJob)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun explicitRemoveMembers(context: Context, groupPublicKey: String, membersToRemove: List<String>): Promise<Any, Exception> {
|
|
||||||
return task {
|
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
|
||||||
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
|
||||||
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
|
||||||
val groupID = doubleEncodeGroupID(groupPublicKey)
|
|
||||||
val group = groupDB.getGroup(groupID).orNull()
|
|
||||||
if (group == null) {
|
|
||||||
Log.d("Loki", "Can't leave nonexistent closed group.")
|
|
||||||
return@task Error.NoThread
|
|
||||||
}
|
|
||||||
val updatedMembers = group.members.map { it.serialize() }.toSet() - membersToRemove
|
|
||||||
// Save the new group members
|
|
||||||
groupDB.updateMembers(groupID, updatedMembers.map { Address.fromSerialized(it) })
|
|
||||||
val removeMembersAsData = membersToRemove.map { Hex.fromStringCondensed(it) }
|
|
||||||
val admins = group.admins.map { it.serialize() }
|
|
||||||
val sentTime = System.currentTimeMillis()
|
|
||||||
val encryptionKeyPair = apiDB.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
|
||||||
if (encryptionKeyPair == null) {
|
|
||||||
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
|
||||||
return@task Error.NoKeyPair
|
|
||||||
}
|
|
||||||
if (membersToRemove.any { it in admins } && updatedMembers.isNotEmpty()) {
|
|
||||||
Log.d("Loki", "Can't remove admin from closed group unless the group is destroyed entirely.")
|
|
||||||
return@task Error.InvalidUpdate
|
|
||||||
}
|
|
||||||
val name = group.title
|
|
||||||
// Send the update to the group
|
|
||||||
val memberUpdateKind = ClosedGroupUpdateMessageSendJobV2.Kind.RemoveMembers(removeMembersAsData)
|
|
||||||
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, memberUpdateKind, sentTime)
|
|
||||||
job.setContext(context)
|
|
||||||
job.onRun() // Run the job immediately
|
|
||||||
// Notify the user
|
|
||||||
val infoType = GroupContext.Type.UPDATE
|
|
||||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
|
||||||
insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
|
||||||
val isCurrentUserAdmin = admins.contains(userPublicKey)
|
|
||||||
if (isCurrentUserAdmin) {
|
|
||||||
generateAndSendNewEncryptionKeyPair(context, groupPublicKey, updatedMembers)
|
|
||||||
}
|
|
||||||
return@task Unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun explicitNameChange(context: Context, groupPublicKey: String, newName: String): Promise<Unit, Exception> {
|
|
||||||
val deferred = deferred<Unit, Exception>()
|
|
||||||
ThreadUtils.queue {
|
|
||||||
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
|
||||||
val groupID = doubleEncodeGroupID(groupPublicKey)
|
|
||||||
val group = groupDB.getGroup(groupID).orNull()
|
|
||||||
val members = group.members.map { it.serialize() }.toSet()
|
|
||||||
val admins = group.admins.map { it.serialize() }
|
|
||||||
val sentTime = System.currentTimeMillis()
|
|
||||||
if (group == null) {
|
|
||||||
Log.d("Loki", "Can't leave nonexistent closed group.")
|
|
||||||
return@queue deferred.reject(Error.NoThread)
|
|
||||||
}
|
|
||||||
// Send the update to the group
|
|
||||||
val kind = ClosedGroupUpdateMessageSendJobV2.Kind.NameChange(newName)
|
|
||||||
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, kind, sentTime)
|
|
||||||
job.setContext(context)
|
|
||||||
job.onRun() // Run the job immediately
|
|
||||||
// Notify the user
|
|
||||||
val infoType = GroupContext.Type.UPDATE
|
|
||||||
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
|
||||||
insertOutgoingInfoMessage(context, groupID, infoType, newName, members, admins, threadID, sentTime)
|
|
||||||
// Update the group
|
|
||||||
groupDB.updateTitle(groupID, newName)
|
|
||||||
deferred.resolve(Unit)
|
|
||||||
}
|
|
||||||
return deferred.promise
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun leave(context: Context, groupPublicKey: String): Promise<Unit, Exception> {
|
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
|
||||||
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
||||||
val groupID = doubleEncodeGroupID(groupPublicKey)
|
val groupID = doubleEncodeGroupID(groupPublicKey)
|
||||||
val group = groupDB.getGroup(groupID).orNull()
|
val group = groupDB.getGroup(groupID).orNull()
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
Log.d("Loki", "Can't leave nonexistent closed group.")
|
Log.d("Loki", "Can't leave nonexistent closed group.")
|
||||||
return Promise.ofFail(Error.NoThread)
|
throw Error.NoThread
|
||||||
|
}
|
||||||
|
val updatedMembers = group.members.map { it.serialize() }.toSet() + membersToAdd
|
||||||
|
val membersAsData = updatedMembers.map { Hex.fromStringCondensed(it) }
|
||||||
|
val newMembersAsData = membersToAdd.map { Hex.fromStringCondensed(it) }
|
||||||
|
val admins = group.admins.map { it.serialize() }
|
||||||
|
val adminsAsData = admins.map { Hex.fromStringCondensed(it) }
|
||||||
|
val sentTime = System.currentTimeMillis()
|
||||||
|
val encryptionKeyPair = pendingKeyPair.getOrElse(groupPublicKey) {
|
||||||
|
Optional.fromNullable(apiDB.getLatestClosedGroupEncryptionKeyPair(groupPublicKey))
|
||||||
|
}.orNull()
|
||||||
|
if (encryptionKeyPair == null) {
|
||||||
|
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
||||||
|
throw Error.NoKeyPair
|
||||||
}
|
}
|
||||||
val name = group.title
|
val name = group.title
|
||||||
val oldMembers = group.members.map { it.serialize() }.toSet()
|
// Send the update to the group
|
||||||
val newMembers: Set<String>
|
val memberUpdateKind = ClosedGroupUpdateMessageSendJobV2.Kind.AddMembers(newMembersAsData)
|
||||||
val isCurrentUserAdmin = group.admins.map { it.toString() }.contains(userPublicKey)
|
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, memberUpdateKind, sentTime)
|
||||||
if (!isCurrentUserAdmin) {
|
job.setContext(context)
|
||||||
newMembers = oldMembers.minus(userPublicKey)
|
job.onRun() // Run the job immediately
|
||||||
} else {
|
// Save the new group members
|
||||||
newMembers = setOf() // If the admin leaves the group is destroyed
|
groupDB.updateMembers(groupID, updatedMembers.map { Address.fromSerialized(it) })
|
||||||
|
// Notify the user
|
||||||
|
val infoType = GroupContext.Type.UPDATE
|
||||||
|
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
||||||
|
insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
||||||
|
// Send closed group update messages to any new members individually
|
||||||
|
for (member in membersToAdd) {
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val closedGroupNewKind = ClosedGroupUpdateMessageSendJobV2.Kind.New(Hex.fromStringCondensed(groupPublicKey), name, encryptionKeyPair, membersAsData, adminsAsData)
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val newMemberJob = ClosedGroupUpdateMessageSendJobV2(member, closedGroupNewKind, sentTime)
|
||||||
|
ApplicationContext.getInstance(context).jobManager.add(newMemberJob)
|
||||||
}
|
}
|
||||||
return update(context, groupPublicKey, newMembers, name)
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun explicitRemoveMembers(context: Context, groupPublicKey: String, membersToRemove: List<String>) {
|
||||||
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||||
|
val apiDB = DatabaseFactory.getLokiAPIDatabase(context)
|
||||||
|
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
||||||
|
val groupID = doubleEncodeGroupID(groupPublicKey)
|
||||||
|
val group = groupDB.getGroup(groupID).orNull()
|
||||||
|
if (group == null) {
|
||||||
|
Log.d("Loki", "Can't leave nonexistent closed group.")
|
||||||
|
throw Error.NoThread
|
||||||
|
}
|
||||||
|
val updatedMembers = group.members.map { it.serialize() }.toSet() - membersToRemove
|
||||||
|
val removeMembersAsData = membersToRemove.map { Hex.fromStringCondensed(it) }
|
||||||
|
val admins = group.admins.map { it.serialize() }
|
||||||
|
val sentTime = System.currentTimeMillis()
|
||||||
|
val encryptionKeyPair = apiDB.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
||||||
|
if (encryptionKeyPair == null) {
|
||||||
|
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
||||||
|
throw Error.NoKeyPair
|
||||||
|
}
|
||||||
|
if (membersToRemove.any { it in admins } && updatedMembers.isNotEmpty()) {
|
||||||
|
Log.d("Loki", "Can't remove admin from closed group unless the group is destroyed entirely.")
|
||||||
|
throw Error.InvalidUpdate
|
||||||
|
}
|
||||||
|
val name = group.title
|
||||||
|
// Send the update to the group
|
||||||
|
val memberUpdateKind = ClosedGroupUpdateMessageSendJobV2.Kind.RemoveMembers(removeMembersAsData)
|
||||||
|
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, memberUpdateKind, sentTime)
|
||||||
|
job.setContext(context)
|
||||||
|
job.onRun() // Run the job immediately
|
||||||
|
// Save the new group members
|
||||||
|
groupDB.updateMembers(groupID, updatedMembers.map { Address.fromSerialized(it) })
|
||||||
|
// Notify the user
|
||||||
|
val infoType = GroupContext.Type.UPDATE
|
||||||
|
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
||||||
|
insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
||||||
|
val isCurrentUserAdmin = admins.contains(userPublicKey)
|
||||||
|
if (isCurrentUserAdmin) {
|
||||||
|
generateAndSendNewEncryptionKeyPair(context, groupPublicKey, updatedMembers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun explicitNameChange(context: Context, groupPublicKey: String, newName: String) {
|
||||||
|
val groupDB = DatabaseFactory.getGroupDatabase(context)
|
||||||
|
val groupID = doubleEncodeGroupID(groupPublicKey)
|
||||||
|
val group = groupDB.getGroup(groupID).orNull()
|
||||||
|
val members = group.members.map { it.serialize() }.toSet()
|
||||||
|
val admins = group.admins.map { it.serialize() }
|
||||||
|
val sentTime = System.currentTimeMillis()
|
||||||
|
if (group == null) {
|
||||||
|
Log.d("Loki", "Can't leave nonexistent closed group.")
|
||||||
|
throw Error.NoThread
|
||||||
|
}
|
||||||
|
// Send the update to the group
|
||||||
|
val kind = ClosedGroupUpdateMessageSendJobV2.Kind.NameChange(newName)
|
||||||
|
val job = ClosedGroupUpdateMessageSendJobV2(groupPublicKey, kind, sentTime)
|
||||||
|
job.setContext(context)
|
||||||
|
job.onRun() // Run the job immediately
|
||||||
|
// Notify the user
|
||||||
|
val infoType = GroupContext.Type.UPDATE
|
||||||
|
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(Recipient.from(context, Address.fromSerialized(groupID), false))
|
||||||
|
insertOutgoingInfoMessage(context, groupID, infoType, newName, members, admins, threadID, sentTime)
|
||||||
|
// Update the group
|
||||||
|
groupDB.updateTitle(groupID, newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(context: Context, groupPublicKey: String, members: Collection<String>, name: String): Promise<Unit, Exception> {
|
fun update(context: Context, groupPublicKey: String, members: Collection<String>, name: String): Promise<Unit, Exception> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user