mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-25 11:05:25 +00:00
feat: syncs the user profile stuff for now, and errors back to placeholder instead of unknown recipient
This commit is contained in:
parent
fb21f58cbd
commit
03a343d832
@ -108,12 +108,14 @@ class ProfilePictureView @JvmOverloads constructor(
|
|||||||
val signalProfilePicture = recipient.contactPhoto
|
val signalProfilePicture = recipient.contactPhoto
|
||||||
val avatar = (signalProfilePicture as? ProfileContactPhoto)?.avatarObject
|
val avatar = (signalProfilePicture as? ProfileContactPhoto)?.avatarObject
|
||||||
|
|
||||||
|
val placeholder = PlaceholderAvatarPhoto(context, publicKey, displayName ?: "${publicKey.take(4)}...${publicKey.takeLast(4)}")
|
||||||
|
|
||||||
if (signalProfilePicture != null && avatar != "0" && avatar != "") {
|
if (signalProfilePicture != null && avatar != "0" && avatar != "") {
|
||||||
glide.clear(imageView)
|
glide.clear(imageView)
|
||||||
glide.load(signalProfilePicture)
|
glide.load(signalProfilePicture)
|
||||||
.placeholder(unknownRecipientDrawable)
|
.placeholder(unknownRecipientDrawable)
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.error(unknownRecipientDrawable)
|
.error(glide.load(placeholder))
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
.circleCrop()
|
.circleCrop()
|
||||||
.into(imageView)
|
.into(imageView)
|
||||||
@ -121,8 +123,6 @@ class ProfilePictureView @JvmOverloads constructor(
|
|||||||
glide.clear(imageView)
|
glide.clear(imageView)
|
||||||
imageView.setImageDrawable(unknownOpenGroupDrawable)
|
imageView.setImageDrawable(unknownOpenGroupDrawable)
|
||||||
} else {
|
} else {
|
||||||
val placeholder = PlaceholderAvatarPhoto(context, publicKey, displayName ?: "${publicKey.take(4)}...${publicKey.takeLast(4)}")
|
|
||||||
|
|
||||||
glide.clear(imageView)
|
glide.clear(imageView)
|
||||||
glide.load(placeholder)
|
glide.load(placeholder)
|
||||||
.placeholder(unknownRecipientDrawable)
|
.placeholder(unknownRecipientDrawable)
|
||||||
|
@ -126,8 +126,6 @@ class ConfigFactory(private val context: Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun notifyUpdates(forConfigObject: ConfigBase) {
|
override fun notifyUpdates(forConfigObject: ConfigBase) {
|
||||||
if (!forConfigObject.needsDump()) return
|
|
||||||
|
|
||||||
when (forConfigObject) {
|
when (forConfigObject) {
|
||||||
is UserProfile -> updateUser(forConfigObject)
|
is UserProfile -> updateUser(forConfigObject)
|
||||||
is Contacts -> updateContacts(forConfigObject)
|
is Contacts -> updateContacts(forConfigObject)
|
||||||
|
@ -20,9 +20,11 @@ import android.view.View
|
|||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import network.loki.messenger.BuildConfig
|
import network.loki.messenger.BuildConfig
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import network.loki.messenger.databinding.ActivitySettingsBinding
|
import network.loki.messenger.databinding.ActivitySettingsBinding
|
||||||
|
import network.loki.messenger.libsession_util.util.UserPic
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.all
|
import nl.komponents.kovenant.all
|
||||||
import nl.komponents.kovenant.ui.alwaysUi
|
import nl.komponents.kovenant.ui.alwaysUi
|
||||||
@ -35,6 +37,7 @@ import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol
|
|||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
import org.thoughtcrime.securesms.avatar.AvatarSelection
|
import org.thoughtcrime.securesms.avatar.AvatarSelection
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||||
import org.thoughtcrime.securesms.home.PathActivity
|
import org.thoughtcrime.securesms.home.PathActivity
|
||||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
|
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp
|
import org.thoughtcrime.securesms.mms.GlideApp
|
||||||
@ -50,9 +53,14 @@ import org.thoughtcrime.securesms.util.push
|
|||||||
import org.thoughtcrime.securesms.util.show
|
import org.thoughtcrime.securesms.util.show
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.util.Date
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var configFactory: ConfigFactory
|
||||||
|
|
||||||
private lateinit var binding: ActivitySettingsBinding
|
private lateinit var binding: ActivitySettingsBinding
|
||||||
private var displayNameEditActionMode: ActionMode? = null
|
private var displayNameEditActionMode: ActionMode? = null
|
||||||
set(value) { field = value; handleDisplayNameEditActionModeChanged() }
|
set(value) { field = value; handleDisplayNameEditActionModeChanged() }
|
||||||
@ -196,6 +204,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
val displayName = displayNameToBeUploaded
|
val displayName = displayNameToBeUploaded
|
||||||
if (displayName != null) {
|
if (displayName != null) {
|
||||||
TextSecurePreferences.setProfileName(this, displayName)
|
TextSecurePreferences.setProfileName(this, displayName)
|
||||||
|
configFactory.user?.setName(displayName)
|
||||||
}
|
}
|
||||||
val profilePicture = profilePictureToBeUploaded
|
val profilePicture = profilePictureToBeUploaded
|
||||||
val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this)
|
val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this)
|
||||||
@ -207,8 +216,13 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
if (isUpdatingProfilePicture && profilePicture != null) {
|
if (isUpdatingProfilePicture && profilePicture != null) {
|
||||||
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
|
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
|
||||||
TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt())
|
TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt())
|
||||||
TextSecurePreferences.setLastProfilePictureUpload(this, Date().time)
|
|
||||||
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
|
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
|
||||||
|
// new config
|
||||||
|
val url = TextSecurePreferences.getProfilePictureURL(this)
|
||||||
|
val profileKey = ProfileKeyUtil.getProfileKey(this)
|
||||||
|
if (!url.isNullOrEmpty() && !profileKey.isEmpty()) {
|
||||||
|
configFactory.user?.setPic(UserPic(url, profileKey))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (profilePicture != null || displayName != null) {
|
if (profilePicture != null || displayName != null) {
|
||||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@SettingsActivity)
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@SettingsActivity)
|
||||||
@ -218,10 +232,8 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
if (displayName != null) {
|
if (displayName != null) {
|
||||||
binding.btnGroupNameDisplay.text = displayName
|
binding.btnGroupNameDisplay.text = displayName
|
||||||
}
|
}
|
||||||
if (isUpdatingProfilePicture && profilePicture != null) {
|
|
||||||
binding.profilePictureView.root.recycle() // Clear the cached image before updating
|
binding.profilePictureView.root.recycle() // Clear the cached image before updating
|
||||||
binding.profilePictureView.root.update()
|
binding.profilePictureView.root.update()
|
||||||
}
|
|
||||||
displayNameToBeUploaded = null
|
displayNameToBeUploaded = null
|
||||||
profilePictureToBeUploaded = null
|
profilePictureToBeUploaded = null
|
||||||
binding.loader.isVisible = false
|
binding.loader.isVisible = false
|
||||||
|
@ -27,7 +27,10 @@ object ConfigurationMessageUtilities {
|
|||||||
if (ConfigBase.isNewConfigEnabled) {
|
if (ConfigBase.isNewConfigEnabled) {
|
||||||
// don't schedule job if we already have one
|
// don't schedule job if we already have one
|
||||||
val ourDestination = Destination.Contact(userPublicKey)
|
val ourDestination = Destination.Contact(userPublicKey)
|
||||||
if (storage.getConfigSyncJob(ourDestination) != null) return
|
if (storage.getConfigSyncJob(ourDestination) != null) {
|
||||||
|
Log.d("Loki", "ConfigSyncJob is already running for our destination")
|
||||||
|
return
|
||||||
|
}
|
||||||
val newConfigSync = ConfigurationSyncJob(ourDestination)
|
val newConfigSync = ConfigurationSyncJob(ourDestination)
|
||||||
Log.d("Loki", "Scheduling new ConfigurationSyncJob")
|
Log.d("Loki", "Scheduling new ConfigurationSyncJob")
|
||||||
JobQueue.shared.add(newConfigSync)
|
JobQueue.shared.add(newConfigSync)
|
||||||
|
@ -85,7 +85,10 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
val allRequests = mutableListOf<SnodeAPI.SnodeBatchRequestInfo>()
|
val allRequests = mutableListOf<SnodeAPI.SnodeBatchRequestInfo>()
|
||||||
allRequests += batchObjects.requireNoNulls().map { (_, request) -> request }
|
allRequests += batchObjects.requireNoNulls().map { (_, request) -> request }
|
||||||
// add in the deletion if we have any hashes
|
// add in the deletion if we have any hashes
|
||||||
if (toDeleteRequest != null) allRequests += toDeleteRequest
|
if (toDeleteRequest != null) {
|
||||||
|
allRequests += toDeleteRequest
|
||||||
|
Log.d(TAG, "Including delete request for current hashes")
|
||||||
|
}
|
||||||
|
|
||||||
val batchResponse = SnodeAPI.getSingleTargetSnode(destination.destinationPublicKey()).bind { snode ->
|
val batchResponse = SnodeAPI.getSingleTargetSnode(destination.destinationPublicKey()).bind { snode ->
|
||||||
SnodeAPI.getRawBatchResponse(
|
SnodeAPI.getRawBatchResponse(
|
||||||
@ -104,17 +107,29 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
val deletionResponse = if (toDeleteRequest != null) responseList.last() else null
|
val deletionResponse = if (toDeleteRequest != null) responseList.last() else null
|
||||||
val deletedHashes = deletionResponse?.let {
|
val deletedHashes = deletionResponse?.let {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
deletionResponse["deleted"] as? List<String>
|
// get the sub-request body
|
||||||
}?.toSet() ?: emptySet()
|
(deletionResponse["body"] as? RawResponse)?.let { body ->
|
||||||
|
// get the swarm dict
|
||||||
|
body["swarm"] as? RawResponse
|
||||||
|
}?.mapValues { (_, swarmDict) ->
|
||||||
|
// get the deleted values from dict
|
||||||
|
((swarmDict as? RawResponse)?.get("deleted") as? List<String>)?.toSet() ?: emptySet()
|
||||||
|
}?.values?.reduce { acc, strings ->
|
||||||
|
// create an intersection of all deleted hashes (common between all swarm nodes)
|
||||||
|
acc intersect strings
|
||||||
|
}
|
||||||
|
} ?: emptySet()
|
||||||
|
|
||||||
// at this point responseList index should line up with configsRequiringPush index
|
// at this point responseList index should line up with configsRequiringPush index
|
||||||
configsRequiringPush.forEachIndexed { index, config ->
|
configsRequiringPush.forEachIndexed { index, config ->
|
||||||
val (toPushMessage, _) = batchObjects[index]!!
|
val (toPushMessage, _) = batchObjects[index]!!
|
||||||
val response = responseList[index]
|
val response = responseList[index]
|
||||||
val insertHash = response["hash"] as? String ?: run {
|
val responseBody = response["body"] as? RawResponse
|
||||||
|
val insertHash = responseBody?.get("hash") as? String ?: run {
|
||||||
Log.w(TAG, "No hash returned for the configuration in namespace ${config.configNamespace()}")
|
Log.w(TAG, "No hash returned for the configuration in namespace ${config.configNamespace()}")
|
||||||
return@forEachIndexed
|
return@forEachIndexed
|
||||||
}
|
}
|
||||||
|
Log.d(TAG, "Hash $insertHash returned from store request for new config")
|
||||||
|
|
||||||
// confirm pushed seqno
|
// confirm pushed seqno
|
||||||
val thisSeqNo = toPushMessage.seqNo
|
val thisSeqNo = toPushMessage.seqNo
|
||||||
@ -129,7 +144,8 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
|
|||||||
configFactory.persist(config)
|
configFactory.persist(config)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error performing batch request")
|
Log.e(TAG, "Error performing batch request", e)
|
||||||
|
return delegate.handleJobFailedPermanently(this, e)
|
||||||
}
|
}
|
||||||
delegate.handleJobSucceeded(this)
|
delegate.handleJobSucceeded(this)
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ class JobQueue : JobDelegate {
|
|||||||
|
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
when (val job = queue.receive()) {
|
when (val job = queue.receive()) {
|
||||||
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> {
|
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob, is ConfigurationSyncJob -> {
|
||||||
txQueue.send(job)
|
txQueue.send(job)
|
||||||
}
|
}
|
||||||
is AttachmentDownloadJob -> {
|
is AttachmentDownloadJob -> {
|
||||||
|
@ -26,7 +26,6 @@ import org.session.libsession.snode.RawResponse
|
|||||||
import org.session.libsession.snode.SnodeAPI
|
import org.session.libsession.snode.SnodeAPI
|
||||||
import org.session.libsession.snode.SnodeModule
|
import org.session.libsession.snode.SnodeModule
|
||||||
import org.session.libsession.utilities.ConfigFactoryProtocol
|
import org.session.libsession.utilities.ConfigFactoryProtocol
|
||||||
import org.session.libsignal.utilities.JsonUtil
|
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import org.session.libsignal.utilities.Namespace
|
import org.session.libsignal.utilities.Namespace
|
||||||
import org.session.libsignal.utilities.Snode
|
import org.session.libsignal.utilities.Snode
|
||||||
@ -133,8 +132,18 @@ class Poller(private val configFactory: ConfigFactoryProtocol) {
|
|||||||
snode,
|
snode,
|
||||||
userPublicKey,
|
userPublicKey,
|
||||||
namespace,
|
namespace,
|
||||||
updateLatestHash = false
|
updateLatestHash = false,
|
||||||
)
|
updateStoredHashes = false,
|
||||||
|
).filter { (_, hash) -> !configFactory.getHashesFor(forConfigObject).contains(hash) }
|
||||||
|
|
||||||
|
if (messages.isEmpty()) {
|
||||||
|
// no new messages to process
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("Loki-DBG", "Received configs with hashes: ${messages.map { it.second }}")
|
||||||
|
Log.d("Loki-DBG", "Hashes we have for config: ${configFactory.getHashesFor(forConfigObject)}")
|
||||||
|
|
||||||
messages.forEach { (envelope, hash) ->
|
messages.forEach { (envelope, hash) ->
|
||||||
try {
|
try {
|
||||||
val (message, _) = MessageReceiver.parse(data = envelope.toByteArray(), openGroupServerID = null)
|
val (message, _) = MessageReceiver.parse(data = envelope.toByteArray(), openGroupServerID = null)
|
||||||
@ -143,7 +152,6 @@ class Poller(private val configFactory: ConfigFactoryProtocol) {
|
|||||||
Log.w("Loki-DBG", "shared config message handled in configs wasn't SharedConfigurationMessage but was ${message.javaClass.simpleName}")
|
Log.w("Loki-DBG", "shared config message handled in configs wasn't SharedConfigurationMessage but was ${message.javaClass.simpleName}")
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
// maybe do something with seqNo ?
|
|
||||||
Log.d("Loki-DBG", "Merging config of kind ${message.kind} into ${forConfigObject.javaClass.simpleName}")
|
Log.d("Loki-DBG", "Merging config of kind ${message.kind} into ${forConfigObject.javaClass.simpleName}")
|
||||||
forConfigObject.merge(message.data)
|
forConfigObject.merge(message.data)
|
||||||
configFactory.appendHash(forConfigObject, hash!!)
|
configFactory.appendHash(forConfigObject, hash!!)
|
||||||
@ -184,20 +192,27 @@ class Poller(private val configFactory: ConfigFactoryProtocol) {
|
|||||||
if (deferred.promise.isDone()) {
|
if (deferred.promise.isDone()) {
|
||||||
return@bind Promise.ofSuccess(Unit)
|
return@bind Promise.ofSuccess(Unit)
|
||||||
} else {
|
} else {
|
||||||
// TODO: remove log after testing responses
|
|
||||||
Log.d("Loki-DBG", JsonUtil.toJson(rawResponses))
|
|
||||||
val requestList = (rawResponses["results"] as List<RawResponse>)
|
val requestList = (rawResponses["results"] as List<RawResponse>)
|
||||||
// in case we had null configs, the array won't be fully populated
|
// in case we had null configs, the array won't be fully populated
|
||||||
// index of the sparse array key iterator should be the request index, with the key being the namespace
|
// index of the sparse array key iterator should be the request index, with the key being the namespace
|
||||||
requestSparseArray.keyIterator().withIndex().forEach { (requestIndex, key) ->
|
requestSparseArray.keyIterator().withIndex().forEach { (requestIndex, key) ->
|
||||||
requestList.getOrNull(requestIndex)?.let { rawResponse ->
|
requestList.getOrNull(requestIndex)?.let { rawResponse ->
|
||||||
|
if (rawResponse["code"] as? Int != 200) {
|
||||||
|
Log.e("Loki-DBG", "Batch sub-request had non-200 response code, returned code ${(rawResponse["code"] as? Int) ?: "[unknown]"}")
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
val body = rawResponse["body"] as? RawResponse
|
||||||
|
if (body == null) {
|
||||||
|
Log.e("Loki-DBG", "Batch sub-request didn't contain a body")
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
if (key == Namespace.DEFAULT) {
|
if (key == Namespace.DEFAULT) {
|
||||||
processPersonalMessages(snode, rawResponse)
|
processPersonalMessages(snode, body)
|
||||||
} else {
|
} else {
|
||||||
when (ConfigBase.kindFor(key)) {
|
when (ConfigBase.kindFor(key)) {
|
||||||
UserProfile::class.java -> processConfig(snode, rawResponse, key, configFactory.user)
|
UserProfile::class.java -> processConfig(snode, body, key, configFactory.user)
|
||||||
Contacts::class.java -> processConfig(snode, rawResponse, key, configFactory.contacts)
|
Contacts::class.java -> processConfig(snode, body, key, configFactory.contacts)
|
||||||
ConversationVolatileConfig::class.java -> processConfig(snode, rawResponse, key, configFactory.convoVolatile)
|
ConversationVolatileConfig::class.java -> processConfig(snode, body, key, configFactory.convoVolatile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ object SnodeAPI {
|
|||||||
params["pubkey_ed25519"] = ed25519PublicKey
|
params["pubkey_ed25519"] = ed25519PublicKey
|
||||||
params["signature"] = Base64.encodeBytes(signature)
|
params["signature"] = Base64.encodeBytes(signature)
|
||||||
return SnodeBatchRequestInfo(
|
return SnodeBatchRequestInfo(
|
||||||
Snode.Method.Retrieve.rawValue,
|
Snode.Method.DeleteMessage.rawValue,
|
||||||
params,
|
params,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@ -711,13 +711,13 @@ object SnodeAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseRawMessagesResponse(rawResponse: RawResponse, snode: Snode, publicKey: String, namespace: Int = 0, updateLatestHash: Boolean = true): List<Pair<SignalServiceProtos.Envelope, String?>> {
|
fun parseRawMessagesResponse(rawResponse: RawResponse, snode: Snode, publicKey: String, namespace: Int = 0, updateLatestHash: Boolean = true, updateStoredHashes: Boolean = true): List<Pair<SignalServiceProtos.Envelope, String?>> {
|
||||||
val messages = rawResponse["messages"] as? List<*>
|
val messages = rawResponse["messages"] as? List<*>
|
||||||
return if (messages != null) {
|
return if (messages != null) {
|
||||||
if (updateLatestHash) {
|
if (updateLatestHash) {
|
||||||
updateLastMessageHashValueIfPossible(snode, publicKey, messages, namespace)
|
updateLastMessageHashValueIfPossible(snode, publicKey, messages, namespace)
|
||||||
}
|
}
|
||||||
val newRawMessages = removeDuplicates(publicKey, messages, namespace)
|
val newRawMessages = removeDuplicates(publicKey, messages, namespace, updateStoredHashes)
|
||||||
return parseEnvelopes(newRawMessages)
|
return parseEnvelopes(newRawMessages)
|
||||||
} else {
|
} else {
|
||||||
listOf()
|
listOf()
|
||||||
@ -734,7 +734,7 @@ object SnodeAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeDuplicates(publicKey: String, rawMessages: List<*>, namespace: Int): List<*> {
|
private fun removeDuplicates(publicKey: String, rawMessages: List<*>, namespace: Int, updateStoredHashes: Boolean): List<*> {
|
||||||
val originalMessageHashValues = database.getReceivedMessageHashValues(publicKey, namespace)?.toMutableSet() ?: mutableSetOf()
|
val originalMessageHashValues = database.getReceivedMessageHashValues(publicKey, namespace)?.toMutableSet() ?: mutableSetOf()
|
||||||
val receivedMessageHashValues = originalMessageHashValues.toMutableSet()
|
val receivedMessageHashValues = originalMessageHashValues.toMutableSet()
|
||||||
val result = rawMessages.filter { rawMessage ->
|
val result = rawMessages.filter { rawMessage ->
|
||||||
@ -749,7 +749,7 @@ object SnodeAPI {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (originalMessageHashValues != receivedMessageHashValues) {
|
if (originalMessageHashValues != receivedMessageHashValues && updateStoredHashes) {
|
||||||
database.setReceivedMessageHashValues(publicKey, receivedMessageHashValues, namespace)
|
database.setReceivedMessageHashValues(publicKey, receivedMessageHashValues, namespace)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
Loading…
Reference in New Issue
Block a user