feat: open group joining should work now

This commit is contained in:
0x330a
2023-03-16 12:15:21 +11:00
parent c28fe290df
commit 061cff8437
12 changed files with 92 additions and 63 deletions

View File

@@ -40,7 +40,7 @@ class JoinOpenGroupDialog(private val name: String, private val url: String) : B
ThreadUtils.queue {
try {
OpenGroupManager.add(openGroup.server, openGroup.room, openGroup.serverPublicKey, activity)
MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server)
MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server, openGroup.room)
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(activity)
} catch (e: Exception) {
Toast.makeText(activity, R.string.activity_join_public_chat_error, Toast.LENGTH_SHORT).show()

View File

@@ -7,13 +7,18 @@ import network.loki.messenger.libsession_util.Contacts
import network.loki.messenger.libsession_util.ConversationVolatileConfig
import network.loki.messenger.libsession_util.UserGroupsConfig
import network.loki.messenger.libsession_util.UserProfile
import network.loki.messenger.libsession_util.util.*
import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import network.loki.messenger.libsession_util.util.Conversation
import network.loki.messenger.libsession_util.util.ExpiryMode
import network.loki.messenger.libsession_util.util.GroupInfo
import network.loki.messenger.libsession_util.util.UserPic
import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.BlindedIdMapping
import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.AttachmentUploadJob
import org.session.libsession.messaging.jobs.BackgroundGroupAddJob
import org.session.libsession.messaging.jobs.ConfigurationSyncJob
import org.session.libsession.messaging.jobs.GroupAvatarDownloadJob
import org.session.libsession.messaging.jobs.Job
@@ -64,6 +69,7 @@ import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.messages.SignalServiceAttachmentPointer
import org.session.libsignal.messages.SignalServiceGroup
import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.KeyHelper
import org.session.libsignal.utilities.Log
@@ -400,8 +406,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
val lgc = userGroups.allLegacyGroupInfo()
val allOpenGroups = getAllOpenGroups()
val toDeleteCommunities = allOpenGroups.filter { it.value.joinURL !in communities.map { it.community.fullUrl() } }
val existingOpenGroups: Map<Long, OpenGroup> = allOpenGroups.filterKeys { it !in toDeleteCommunities.keys }
val existingJoinUrls = existingOpenGroups.values.map { it.joinURL }
val existingCommunities: Map<Long, OpenGroup> = allOpenGroups.filterKeys { it !in toDeleteCommunities.keys }
val toAddCommunities = communities.filter { it.community.fullUrl() !in existingCommunities.map { it.value.joinURL } }
val existingJoinUrls = existingCommunities.values.map { it.joinURL }
val existingClosedGroups = getAllGroups()
val lgcIds = lgc.map { it.sessionId }
val toDeleteClosedGroups = existingClosedGroups.filter { group ->
@@ -422,6 +431,14 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
}
}
toAddCommunities.forEach { toAddCommunity ->
val joinUrl = toAddCommunity.community.fullUrl()
if (!hasBackgroundGroupAddJob(joinUrl)) {
Log.d("Loki-DBG", "Doesn't contain background job for open group, adding from config update")
JobQueue.shared.add(BackgroundGroupAddJob(joinUrl))
}
}
for (groupInfo in communities) {
val groupBaseCommunity = groupInfo.community
if (groupBaseCommunity.fullUrl() !in existingJoinUrls) {
@@ -429,7 +446,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
val (threadId, _) = OpenGroupManager.add(groupBaseCommunity.baseUrl, groupBaseCommunity.room, groupBaseCommunity.pubKeyHex, context)
threadDb.setPinned(threadId, groupInfo.priority >= 1)
} else {
val (threadId, _) = existingOpenGroups.entries.first { (_, v) -> v.joinURL == groupInfo.community.fullUrl() }
val (threadId, _) = existingCommunities.entries.first { (_, v) -> v.joinURL == groupInfo.community.fullUrl() }
threadDb.setPinned(threadId, groupInfo.priority >= 1)
}
}
@@ -699,6 +716,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
val existingGroup = getGroup(groupID)
?: return Log.w("Loki-DBG", "No existing group for ${groupPublicKey.take(4)}...${groupPublicKey.takeLast(4)} when updating group config")
val userGroups = configFactory.userGroups ?: return
if (!existingGroup.isActive) {
userGroups.eraseLegacyGroup(groupPublicKey)
return
}
val name = existingGroup.title
val admins = existingGroup.admins.map { it.serialize() }
val members = existingGroup.members.map { it.serialize() }
@@ -855,8 +876,19 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
return OpenGroupManager.addOpenGroup(urlAsString, context)
}
override fun onOpenGroupAdded(server: String) {
override fun onOpenGroupAdded(server: String, room: String) {
OpenGroupManager.restartPollerForServer(server.removeSuffix("/"))
val groups = configFactory.userGroups ?: return
val volatileConfig = configFactory.convoVolatile ?: return
val openGroup = getOpenGroup(room, server) ?: return
val (infoServer, infoRoom, pubKey) = BaseCommunityInfo.parseFullUrl(openGroup.joinURL) ?: return
val pubKeyHex = Hex.toStringCondensed(pubKey)
val communityInfo = groups.getOrConstructCommunityInfo(infoServer, infoRoom, pubKeyHex)
groups.set(communityInfo)
val volatile = volatileConfig.getOrConstructCommunity(infoServer, infoRoom, pubKey).copy(
lastRead = SnodeAPI.nowWithOffset,
)
volatileConfig.set(volatile)
}
override fun hasBackgroundGroupAddJob(groupJoinUrl: String): Boolean {

View File

@@ -11,6 +11,7 @@ import org.session.libsession.utilities.ConfigFactoryUpdateListener
import org.session.libsignal.protos.SignalServiceProtos.SharedConfigMessage
import org.thoughtcrime.securesms.database.ConfigDatabase
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
import java.util.concurrent.Executors
class ConfigFactory(private val context: Context,
private val configDatabase: ConfigDatabase,
@@ -34,6 +35,7 @@ class ConfigFactory(private val context: Context,
private var _convoVolatileConfig: ConversationVolatileConfig? = null
private val userGroupsLock = Object()
private var _userGroups: UserGroupsConfig? = null
private val factoryExecutor = Executors.newSingleThreadExecutor()
private val listeners: MutableList<ConfigFactoryUpdateListener> = mutableListOf()
fun registerListener(listener: ConfigFactoryUpdateListener) { listeners += listener }
@@ -127,15 +129,17 @@ class ConfigFactory(private val context: Context,
}
override fun persist(forConfigObject: ConfigBase) {
listeners.forEach { listener ->
listener.notifyUpdates(forConfigObject)
}
when (forConfigObject) {
is UserProfile -> persistUserConfigDump()
is Contacts -> persistContactsConfigDump()
is ConversationVolatileConfig -> persistConvoVolatileConfigDump()
is UserGroupsConfig -> persistUserGroupsConfigDump()
else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet")
factoryExecutor.submit {
listeners.forEach { listener ->
listener.notifyUpdates(forConfigObject)
}
when (forConfigObject) {
is UserProfile -> persistUserConfigDump()
is Contacts -> persistContactsConfigDump()
is ConversationVolatileConfig -> persistConvoVolatileConfigDump()
is UserGroupsConfig -> persistUserGroupsConfigDump()
else -> throw UnsupportedOperationException("Can't support type of ${forConfigObject::class.simpleName} yet")
}
}
}

View File

@@ -79,7 +79,7 @@ class JoinCommunityFragment : Fragment() {
val openGroupID = "$sanitizedServer.${openGroup.room}"
OpenGroupManager.add(sanitizedServer, openGroup.room, openGroup.serverPublicKey, requireContext())
val storage = MessagingModuleConfiguration.shared.storage
storage.onOpenGroupAdded(sanitizedServer)
storage.onOpenGroupAdded(sanitizedServer, openGroup.room)
val threadID = GroupManager.getOpenGroupThreadID(openGroupID, requireContext())
val groupID = GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())

View File

@@ -3,9 +3,11 @@ package org.thoughtcrime.securesms.sskenvironment
import android.content.Context
import network.loki.messenger.libsession_util.util.UserPic
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.utilities.SessionId
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.IdPrefix
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
@@ -86,6 +88,8 @@ class ProfileManager(private val context: Context, private val configFactory: Co
override fun contactUpdatedInternal(contact: Contact) {
val contactConfig = configFactory.contacts ?: return
if (contact.sessionID == TextSecurePreferences.getLocalNumber(context)) return
val sessionId = SessionId(contact.sessionID)
if (sessionId.prefix != IdPrefix.STANDARD) return // only internally store standard session IDs
contactConfig.upsertContact(contact.sessionID) {
this.name = contact.name.orEmpty()
this.nickname = contact.nickname.orEmpty()

View File

@@ -6,7 +6,11 @@ import network.loki.messenger.libsession_util.Contacts
import network.loki.messenger.libsession_util.ConversationVolatileConfig
import network.loki.messenger.libsession_util.UserGroupsConfig
import network.loki.messenger.libsession_util.UserProfile
import network.loki.messenger.libsession_util.util.*
import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import network.loki.messenger.libsession_util.util.Contact
import network.loki.messenger.libsession_util.util.ExpiryMode
import network.loki.messenger.libsession_util.util.GroupInfo
import network.loki.messenger.libsession_util.util.UserPic
import nl.komponents.kovenant.Promise
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.jobs.ConfigurationSyncJob
@@ -17,7 +21,6 @@ import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.messaging.utilities.SessionId
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.Log
@@ -167,6 +170,7 @@ object ConfigurationMessageUtilities {
}
val dump = contactConfig.dump()
contactConfig.free()
if (dump.isEmpty()) return null
return dump
}
@@ -177,7 +181,7 @@ object ConfigurationMessageUtilities {
val threadDb = DatabaseComponent.get(context).threadDatabase()
threadDb.approvedConversationList.use { cursor ->
val reader = threadDb.readerFor(cursor)
var current = reader.current
var current = reader.next
while (current != null) {
val recipient = current.recipient
val contact = when {
@@ -210,6 +214,7 @@ object ConfigurationMessageUtilities {
val dump = convoConfig.dump()
convoConfig.free()
if (dump.isEmpty()) return null
return dump
}
@@ -226,7 +231,7 @@ object ConfigurationMessageUtilities {
GroupInfo.CommunityGroupInfo(baseInfo, if (isPinned) 1 else 0)
}
val allLgc = storage.getAllGroups().filter { it.isClosedGroup }.mapNotNull { group ->
val allLgc = storage.getAllGroups().filter { it.isClosedGroup && it.isActive }.mapNotNull { group ->
val groupAddress = Address.fromSerialized(group.encodedId)
val groupPublicKey = GroupUtil.doubleDecodeGroupID(groupAddress.serialize()).toHexString()
val recipient = storage.getRecipientSettings(groupAddress) ?: return@mapNotNull null
@@ -252,6 +257,7 @@ object ConfigurationMessageUtilities {
}
val dump = groupConfig.dump()
groupConfig.free()
if (dump.isEmpty()) return null
return dump
}