diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 19c3dd3bdd..b916f4474c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -98,17 +98,21 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF // TODO: maybe add time here from formation / creation message override fun threadCreated(address: Address, threadId: Long) { + Log.d("Loki-DBG", "creating thread for $address") val volatile = configFactory.convoVolatile ?: return if (address.isGroup) { val groups = configFactory.userGroups ?: return if (address.isClosedGroup) { val sessionId = GroupUtil.doubleDecodeGroupId(address.serialize()) - val legacyGroup = groups.getOrConstructLegacyGroupInfo(sessionId) - groups.set(legacyGroup) - val newVolatileParams = volatile.getOrConstructLegacyGroup(sessionId).copy( - lastRead = SnodeAPI.nowWithOffset, - ) - volatile.set(newVolatileParams) + val closedGroup = getGroup(address.toGroupString()) + if (closedGroup != null && closedGroup.isActive) { + val legacyGroup = groups.getOrConstructLegacyGroupInfo(sessionId) + groups.set(legacyGroup) + val newVolatileParams = volatile.getOrConstructLegacyGroup(sessionId).copy( + lastRead = SnodeAPI.nowWithOffset, + ) + volatile.set(newVolatileParams) + } } else if (address.isOpenGroup) { // 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") @@ -132,6 +136,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF } override fun threadDeleted(address: Address, threadId: Long) { + Log.d("Loki-DBG", "deleting thread for $address") val volatile = configFactory.convoVolatile ?: return if (address.isGroup) { val groups = configFactory.userGroups ?: return @@ -1181,11 +1186,14 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF override fun deleteConversation(threadID: Long) { // 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 threadDB = DatabaseComponent.get(context).threadDatabase() threadDB.deleteConversation(threadID) if (recipient != null) { + Log.d("Loki-DBG", "Deleting conversation for ${recipient.address}") if (recipient.isContactRecipient) { + if (recipient.isLocalNumber) return // TODO: handle contact val contacts = configFactory.contacts ?: return contacts.upsertContact(recipient.address.serialize()) { @@ -1194,6 +1202,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) } else if (recipient.isClosedGroupRecipient) { // 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()}") + } } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt index bc0210bf49..edc1bc56ca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt @@ -245,11 +245,10 @@ object ConfigurationMessageUtilities { val encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: return@mapNotNull null val threadId = storage.getThreadId(group.encodedId) 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 members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap() GroupInfo.LegacyGroupInfo( - sessionId = sessionId, + sessionId = groupPublicKey, name = group.title, members = admins + members, priority = if (isPinned) ConfigBase.PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE, diff --git a/libsession-util/src/main/cpp/user_groups.cpp b/libsession-util/src/main/cpp/user_groups.cpp index 32775f8fd1..9ae524663a 100644 --- a/libsession-util/src/main/cpp/user_groups.cpp +++ b/libsession-util/src/main/cpp/user_groups.cpp @@ -178,7 +178,6 @@ inline jobject iterator_as_java_stack(JNIEnv *env, const session::config::UserGr jobject serialized = nullptr; if (auto* lgc = std::get_if(&item)) { serialized = serialize_legacy_group_info(env, *lgc); - } else if (auto* community = std::get_if(&item)) { serialized = serialize_community_info(env, *community); } diff --git a/libsession-util/src/main/cpp/user_groups.h b/libsession-util/src/main/cpp/user_groups.h index aa3f3e1410..a79d01a0a7 100644 --- a/libsession-util/src/main/cpp/user_groups.h +++ b/libsession-util/src/main/cpp/user_groups.h @@ -73,6 +73,7 @@ inline session::config::legacy_group_info deserialize_legacy_group_info(JNIEnv * info_deserialized.name = name_bytes; info_deserialized.enc_pubkey = enc_pub_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)); env->ReleaseStringUTFChars(id, id_bytes); env->ReleaseStringUTFChars(name, name_bytes); @@ -104,7 +105,6 @@ inline jobject serialize_members(JNIEnv *env, std::map member bool is_admin = it->second; auto jbool = env->NewObject(boxed_bool, new_bool, is_admin); env->CallObjectMethod(new_map, insert, session_id, jbool); - ++it; } return new_map; } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt index 89c5d68340..4894565632 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt @@ -229,8 +229,8 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success { // Notify the user val infoType = SignalServiceGroup.Type.QUIT - val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) if (notifyUser) { + val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime) } // Remove the group private key and unsubscribe from PNs diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 1a72b87e8f..aa882c6771 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -761,8 +761,10 @@ private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupCont } // Notify the user if (userLeft) { - val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) - storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, threadID, message.sentTimestamp!!) + val threadID = storage.getThreadId(Address.fromSerialized(groupID)) + if (threadID != null) { + storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, threadID, message.sentTimestamp!!) + } } else { storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, SignalServiceGroup.Type.QUIT, name, members, admins, message.sentTimestamp!!) }