feat: fix the invite order properly
This commit is contained in:
parent
cc24542af3
commit
d162522ac2
|
@ -19,6 +19,7 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
|
|||
import network.loki.messenger.libsession_util.util.GroupDisplayInfo
|
||||
import network.loki.messenger.libsession_util.util.GroupInfo
|
||||
import network.loki.messenger.libsession_util.util.UserPic
|
||||
import nl.komponents.kovenant.functional.bind
|
||||
import org.session.libsession.avatars.AvatarHelper
|
||||
import org.session.libsession.database.StorageProtocol
|
||||
import org.session.libsession.messaging.BlindedIdMapping
|
||||
|
@ -1277,7 +1278,78 @@ open class Storage(
|
|||
override fun inviteClosedGroupMembers(groupSessionId: String, invitees: List<String>) {
|
||||
// don't try to process invitee acceptance if we aren't admin
|
||||
if (configFactory.userGroups?.getClosedGroup(groupSessionId)?.hasAdminKey() != true) return
|
||||
val infoConfig = configFactory
|
||||
val adminKey = configFactory.userGroups?.getClosedGroup(groupSessionId)?.adminKey ?: return
|
||||
val sessionId = SessionId.from(groupSessionId)
|
||||
val membersConfig = configFactory.getGroupMemberConfig(sessionId) ?: return
|
||||
val infoConfig = configFactory.getGroupInfoConfig(sessionId) ?: return
|
||||
|
||||
val filteredMembers = invitees.filter {
|
||||
membersConfig.get(it) == null
|
||||
}
|
||||
filteredMembers.forEach { memberSessionId ->
|
||||
val member = membersConfig.getOrConstruct(memberSessionId).copy(
|
||||
invitePending = true,
|
||||
)
|
||||
membersConfig.set(member)
|
||||
}
|
||||
|
||||
val keysConfig = configFactory.getGroupKeysConfig(
|
||||
sessionId,
|
||||
info = infoConfig,
|
||||
members = membersConfig,
|
||||
free = false
|
||||
) ?: return
|
||||
|
||||
keysConfig.rekey(infoConfig, membersConfig)
|
||||
|
||||
val sentTimestamp = SnodeAPI.nowWithOffset
|
||||
|
||||
val message = SnodeMessage(
|
||||
groupSessionId,
|
||||
Base64.encodeBytes(keysConfig.pendingConfig()!!), // should not be null from checking has pending
|
||||
SnodeMessage.CONFIG_TTL,
|
||||
sentTimestamp
|
||||
)
|
||||
val authenticatedBatch = SnodeAPI.buildAuthenticatedStoreBatchInfo(
|
||||
keysConfig.namespace(),
|
||||
message,
|
||||
adminKey
|
||||
)
|
||||
|
||||
val response = SnodeAPI.getSingleTargetSnode(groupSessionId).bind { snode ->
|
||||
SnodeAPI.getRawBatchResponse(
|
||||
snode,
|
||||
groupSessionId,
|
||||
listOf(authenticatedBatch),
|
||||
)
|
||||
}
|
||||
|
||||
val destination = Destination.ClosedGroup(groupSessionId)
|
||||
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(destination)
|
||||
|
||||
try {
|
||||
response.get()
|
||||
} catch (e: Exception) {
|
||||
Log.e("ClosedGroup", "Failed to store new key", e)
|
||||
infoConfig.free()
|
||||
membersConfig.free()
|
||||
keysConfig.free()
|
||||
// toaster toast here
|
||||
return
|
||||
}
|
||||
|
||||
configFactory.saveGroupConfigs(keysConfig, infoConfig, membersConfig)
|
||||
|
||||
infoConfig.free()
|
||||
membersConfig.free()
|
||||
keysConfig.free()
|
||||
|
||||
val newConfigSync = ConfigurationSyncJob(destination)
|
||||
JobQueue.shared.add(newConfigSync)
|
||||
|
||||
val job = InviteContactsJob(groupSessionId, filteredMembers.toTypedArray())
|
||||
JobQueue.shared.add(job)
|
||||
}
|
||||
|
||||
override fun setServerCapabilities(server: String, capabilities: List<String>) {
|
||||
|
|
|
@ -221,6 +221,8 @@ class ConfigFactory(
|
|||
info?.free()
|
||||
members?.free()
|
||||
}
|
||||
if (usedInfo !== info) usedInfo.free()
|
||||
if (usedMembers !== members) usedMembers.free()
|
||||
keys
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ import network.loki.messenger.R
|
|||
import network.loki.messenger.libsession_util.util.GroupMember
|
||||
import org.session.libsession.database.StorageProtocol
|
||||
import org.session.libsession.messaging.contacts.Contact
|
||||
import org.session.libsession.messaging.jobs.InviteContactsJob
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.thoughtcrime.securesms.groups.ContactList
|
||||
import org.thoughtcrime.securesms.groups.destinations.EditClosedGroupInviteScreenDestination
|
||||
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||
|
@ -98,7 +96,6 @@ fun EditClosedGroupInviteScreen(
|
|||
val state by viewModel.viewState.collectAsState()
|
||||
val viewState = state.viewState
|
||||
val currentMemberSessionIds = viewState.currentMembers.map { it.memberSessionId }
|
||||
val eventSink = state.eventSink
|
||||
|
||||
SelectContacts(
|
||||
viewState.allContacts
|
||||
|
@ -156,15 +153,10 @@ class EditGroupViewModel @AssistedInject constructor(
|
|||
when (event) {
|
||||
is EditGroupEvent.InviteContacts -> {
|
||||
val sessionIds = event.contacts
|
||||
val invite = InviteContactsJob(
|
||||
groupSessionId,
|
||||
sessionIds.contacts.map(Contact::sessionID).toTypedArray()
|
||||
)
|
||||
storage.inviteClosedGroupMembers(
|
||||
groupSessionId,
|
||||
sessionIds.contacts.map(Contact::sessionID)
|
||||
)
|
||||
JobQueue.shared.add(invite)
|
||||
Toast.makeText(
|
||||
event.context,
|
||||
"Inviting ${event.contacts.contacts.size}",
|
||||
|
@ -210,9 +202,7 @@ class EditGroupInviteViewModel @AssistedInject constructor(
|
|||
|
||||
EditGroupInviteState(
|
||||
EditGroupInviteViewState(closedGroupMembers, contacts)
|
||||
) { event ->
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
@ -321,7 +311,6 @@ data class EditGroupState(
|
|||
|
||||
data class EditGroupInviteState(
|
||||
val viewState: EditGroupInviteViewState,
|
||||
val eventSink: (Unit) -> Unit
|
||||
)
|
||||
|
||||
data class MemberViewModel(
|
||||
|
|
|
@ -104,6 +104,8 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_needsDump(JNIEnv *e
|
|||
return keys->needs_dump();
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_GroupKeysConfig_pendingKey(JNIEnv *env, jobject thiz) {
|
||||
|
@ -258,3 +260,17 @@ Java_network_loki_messenger_libsession_1util_GroupKeysConfig_subAccountSign(JNIE
|
|||
auto swarm_auth = ptr->swarm_subaccount_sign(message_ustring, signing_value_ustring, false);
|
||||
return util::deserialize_swarm_auth(env, swarm_auth);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_network_loki_messenger_libsession_1util_GroupKeysConfig_supplementFor(JNIEnv *env,
|
||||
jobject thiz,
|
||||
jstring user_session_id) {
|
||||
std::lock_guard lock{util::util_mutex_};
|
||||
auto ptr = ptrToKeys(env, thiz);
|
||||
auto string = env->GetStringUTFChars(user_session_id, nullptr);
|
||||
auto supplement = ptr->key_supplement(string);
|
||||
auto supplement_jbytearray = util::bytes_from_ustring(env, supplement);
|
||||
env->ReleaseStringUTFChars(user_session_id, string);
|
||||
return supplement_jbytearray;
|
||||
}
|
|
@ -321,6 +321,7 @@ class GroupKeysConfig(pointer: Long): ConfigSig(pointer) {
|
|||
members: GroupMembersConfig)
|
||||
external fun needsRekey(): Boolean
|
||||
external fun pendingKey(): ByteArray?
|
||||
external fun supplementFor(userSessionId: String): ByteArray
|
||||
external fun pendingConfig(): ByteArray?
|
||||
external fun currentHashes(): List<String>
|
||||
external fun rekey(info: GroupInfoConfig, members: GroupMembersConfig): ByteArray
|
||||
|
|
|
@ -234,8 +234,8 @@ data class ConfigurationSyncJob(val destination: Destination) : Job {
|
|||
responseBody?.get("hash") as? String
|
||||
?: run {
|
||||
Log.w(
|
||||
TAG,
|
||||
"No hash returned for the configuration in namespace ${config.namespace()}"
|
||||
TAG,
|
||||
"No hash returned for the configuration in namespace ${config.namespace()}"
|
||||
)
|
||||
return@forEachIndexed
|
||||
}
|
||||
|
@ -247,8 +247,8 @@ data class ConfigurationSyncJob(val destination: Destination) : Job {
|
|||
}
|
||||
|
||||
Log.d(
|
||||
TAG,
|
||||
"Successfully removed the deleted hashes from ${config.javaClass.simpleName}"
|
||||
TAG,
|
||||
"Successfully removed the deleted hashes from ${config.javaClass.simpleName}"
|
||||
)
|
||||
// dump and write config after successful
|
||||
if (config is ConfigBase && config.needsDump()) { // usually this will be true? ))
|
||||
|
|
|
@ -24,10 +24,13 @@ import kotlin.math.roundToLong
|
|||
class JobQueue : JobDelegate {
|
||||
private var hasResumedPendingJobs = false // Just for debugging
|
||||
private val jobTimestampMap = ConcurrentHashMap<Long, AtomicInteger>()
|
||||
|
||||
private val rxDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
private val rxMediaDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
|
||||
private val openGroupDispatcher = Executors.newFixedThreadPool(8).asCoroutineDispatcher()
|
||||
private val txDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
private val configDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.Default) + SupervisorJob()
|
||||
private val queue = Channel<Job>(UNLIMITED)
|
||||
private val pendingJobIds = mutableSetOf<String>()
|
||||
|
@ -114,19 +117,23 @@ class JobQueue : JobDelegate {
|
|||
val txQueue = Channel<Job>(capacity = UNLIMITED)
|
||||
val mediaQueue = Channel<Job>(capacity = UNLIMITED)
|
||||
val openGroupQueue = Channel<Job>(capacity = UNLIMITED)
|
||||
val configQueue = Channel<Job>(capacity = UNLIMITED)
|
||||
|
||||
val receiveJob = processWithDispatcher(rxQueue, rxDispatcher, "rx", asynchronous = false)
|
||||
val txJob = processWithDispatcher(txQueue, txDispatcher, "tx")
|
||||
val mediaJob = processWithDispatcher(mediaQueue, rxMediaDispatcher, "media")
|
||||
val openGroupJob = processWithOpenGroupDispatcher(openGroupQueue, openGroupDispatcher, "openGroup")
|
||||
val configJob = processWithDispatcher(configQueue, configDispatcher, "configDispatcher")
|
||||
|
||||
while (isActive) {
|
||||
when (val job = queue.receive()) {
|
||||
is InviteContactsJob,
|
||||
is ConfigurationSyncJob -> {
|
||||
configQueue.send(job)
|
||||
}
|
||||
is NotifyPNServerJob,
|
||||
is AttachmentUploadJob,
|
||||
is MessageSendJob,
|
||||
is ConfigurationSyncJob,
|
||||
is InviteContactsJob -> {
|
||||
is MessageSendJob -> {
|
||||
txQueue.send(job)
|
||||
}
|
||||
is RetrieveProfileAvatarJob,
|
||||
|
@ -158,6 +165,7 @@ class JobQueue : JobDelegate {
|
|||
txJob.cancel()
|
||||
mediaJob.cancel()
|
||||
openGroupJob.cancel()
|
||||
configJob.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue