fix: don't recreate thread after leaving

This commit is contained in:
0x330a 2023-04-06 16:39:40 +10:00
parent 74f05a166b
commit 6d37fb29ab
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
6 changed files with 31 additions and 13 deletions

View File

@ -98,17 +98,21 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
// TODO: maybe add time here from formation / creation message // TODO: maybe add time here from formation / creation message
override fun threadCreated(address: Address, threadId: Long) { override fun threadCreated(address: Address, threadId: Long) {
Log.d("Loki-DBG", "creating thread for $address")
val volatile = configFactory.convoVolatile ?: return val volatile = configFactory.convoVolatile ?: return
if (address.isGroup) { if (address.isGroup) {
val groups = configFactory.userGroups ?: return val groups = configFactory.userGroups ?: return
if (address.isClosedGroup) { if (address.isClosedGroup) {
val sessionId = GroupUtil.doubleDecodeGroupId(address.serialize()) val sessionId = GroupUtil.doubleDecodeGroupId(address.serialize())
val legacyGroup = groups.getOrConstructLegacyGroupInfo(sessionId) val closedGroup = getGroup(address.toGroupString())
groups.set(legacyGroup) if (closedGroup != null && closedGroup.isActive) {
val newVolatileParams = volatile.getOrConstructLegacyGroup(sessionId).copy( val legacyGroup = groups.getOrConstructLegacyGroupInfo(sessionId)
lastRead = SnodeAPI.nowWithOffset, groups.set(legacyGroup)
) val newVolatileParams = volatile.getOrConstructLegacyGroup(sessionId).copy(
volatile.set(newVolatileParams) lastRead = SnodeAPI.nowWithOffset,
)
volatile.set(newVolatileParams)
}
} else if (address.isOpenGroup) { } else if (address.isOpenGroup) {
// these should be added on the group join / group info fetch // these should be added on the group join / group info fetch
Log.w("Loki", "Thread created called for open group address, not adding any extra information") Log.w("Loki", "Thread created called for open group address, not adding any extra information")
@ -132,6 +136,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
} }
override fun threadDeleted(address: Address, threadId: Long) { override fun threadDeleted(address: Address, threadId: Long) {
Log.d("Loki-DBG", "deleting thread for $address")
val volatile = configFactory.convoVolatile ?: return val volatile = configFactory.convoVolatile ?: return
if (address.isGroup) { if (address.isGroup) {
val groups = configFactory.userGroups ?: return val groups = configFactory.userGroups ?: return
@ -1181,11 +1186,14 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
override fun deleteConversation(threadID: Long) { override fun deleteConversation(threadID: Long) {
// TODO: delete from either contacts / convo volatile or the closed groups // TODO: delete from either contacts / convo volatile or the closed groups
// TODO: message request deletion properly (not just doing a hidden priority)
val recipient = getRecipientForThread(threadID) val recipient = getRecipientForThread(threadID)
val threadDB = DatabaseComponent.get(context).threadDatabase() val threadDB = DatabaseComponent.get(context).threadDatabase()
threadDB.deleteConversation(threadID) threadDB.deleteConversation(threadID)
if (recipient != null) { if (recipient != null) {
Log.d("Loki-DBG", "Deleting conversation for ${recipient.address}")
if (recipient.isContactRecipient) { if (recipient.isContactRecipient) {
if (recipient.isLocalNumber) return
// TODO: handle contact // TODO: handle contact
val contacts = configFactory.contacts ?: return val contacts = configFactory.contacts ?: return
contacts.upsertContact(recipient.address.serialize()) { contacts.upsertContact(recipient.address.serialize()) {
@ -1194,6 +1202,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
} else if (recipient.isClosedGroupRecipient) { } else if (recipient.isClosedGroupRecipient) {
// TODO: handle closed group // TODO: handle closed group
val volatile = configFactory.convoVolatile ?: return
val groups = configFactory.userGroups ?: return
val closedGroup = getGroup(recipient.address.toGroupString())
val groupPublicKey = GroupUtil.doubleDecodeGroupId(recipient.address.serialize())
if (closedGroup != null) {
volatile.eraseLegacyClosedGroup(groupPublicKey)
groups.eraseLegacyGroup(groupPublicKey)
} else {
Log.w("Loki-DBG", "Failed to find a closed group for $groupPublicKey, ${recipient.address.serialize()}")
}
} }
} }
} }

View File

@ -245,11 +245,10 @@ object ConfigurationMessageUtilities {
val encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: return@mapNotNull null val encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: return@mapNotNull null
val threadId = storage.getThreadId(group.encodedId) val threadId = storage.getThreadId(group.encodedId)
val isPinned = threadId?.let { storage.isPinned(threadId) } ?: false val isPinned = threadId?.let { storage.isPinned(threadId) } ?: false
val sessionId = GroupUtil.doubleEncodeGroupID(group.getId())
val admins = group.admins.map { it.serialize() to true }.toMap() val admins = group.admins.map { it.serialize() to true }.toMap()
val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap() val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap()
GroupInfo.LegacyGroupInfo( GroupInfo.LegacyGroupInfo(
sessionId = sessionId, sessionId = groupPublicKey,
name = group.title, name = group.title,
members = admins + members, members = admins + members,
priority = if (isPinned) ConfigBase.PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE, priority = if (isPinned) ConfigBase.PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE,

View File

@ -178,7 +178,6 @@ inline jobject iterator_as_java_stack(JNIEnv *env, const session::config::UserGr
jobject serialized = nullptr; jobject serialized = nullptr;
if (auto* lgc = std::get_if<session::config::legacy_group_info>(&item)) { if (auto* lgc = std::get_if<session::config::legacy_group_info>(&item)) {
serialized = serialize_legacy_group_info(env, *lgc); serialized = serialize_legacy_group_info(env, *lgc);
} else if (auto* community = std::get_if<session::config::community_info>(&item)) { } else if (auto* community = std::get_if<session::config::community_info>(&item)) {
serialized = serialize_community_info(env, *community); serialized = serialize_community_info(env, *community);
} }

View File

@ -73,6 +73,7 @@ inline session::config::legacy_group_info deserialize_legacy_group_info(JNIEnv *
info_deserialized.name = name_bytes; info_deserialized.name = name_bytes;
info_deserialized.enc_pubkey = enc_pub_key_bytes; info_deserialized.enc_pubkey = enc_pub_key_bytes;
info_deserialized.enc_seckey = enc_sec_key_bytes; info_deserialized.enc_seckey = enc_sec_key_bytes;
info_deserialized.priority = priority;
info_deserialized.disappearing_timer = std::chrono::seconds(env->GetLongField(info, disappearing_timer_field)); info_deserialized.disappearing_timer = std::chrono::seconds(env->GetLongField(info, disappearing_timer_field));
env->ReleaseStringUTFChars(id, id_bytes); env->ReleaseStringUTFChars(id, id_bytes);
env->ReleaseStringUTFChars(name, name_bytes); env->ReleaseStringUTFChars(name, name_bytes);
@ -104,7 +105,6 @@ inline jobject serialize_members(JNIEnv *env, std::map<std::string, bool> member
bool is_admin = it->second; bool is_admin = it->second;
auto jbool = env->NewObject(boxed_bool, new_bool, is_admin); auto jbool = env->NewObject(boxed_bool, new_bool, is_admin);
env->CallObjectMethod(new_map, insert, session_id, jbool); env->CallObjectMethod(new_map, insert, session_id, jbool);
++it;
} }
return new_map; return new_map;
} }

View File

@ -229,8 +229,8 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success { sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
// Notify the user // Notify the user
val infoType = SignalServiceGroup.Type.QUIT val infoType = SignalServiceGroup.Type.QUIT
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
if (notifyUser) { if (notifyUser) {
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime) storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
} }
// Remove the group private key and unsubscribe from PNs // Remove the group private key and unsubscribe from PNs

View File

@ -761,8 +761,10 @@ private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupCont
} }
// Notify the user // Notify the user
if (userLeft) { if (userLeft) {
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) val threadID = storage.getThreadId(Address.fromSerialized(groupID))
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, threadID, message.sentTimestamp!!) if (threadID != null) {
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, threadID, message.sentTimestamp!!)
}
} else { } else {
storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, message.sentTimestamp!!) storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, message.sentTimestamp!!)
} }