Add various fixes for pinned messages.

This commit is contained in:
Michelle Tang
2025-11-26 11:31:21 -05:00
committed by jeffrey-signal
parent 864867f60e
commit 804f479cb0
4 changed files with 121 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExtras
import org.thoughtcrime.securesms.database.model.databaseprotos.PinnedMessage
import org.thoughtcrime.securesms.database.model.databaseprotos.PollTerminate
import org.thoughtcrime.securesms.database.model.toBodyRangeList
import org.thoughtcrime.securesms.dependencies.AppDependencies
@@ -251,6 +252,11 @@ object SyncMessageProcessor {
threadId = SignalDatabase.threads.getOrCreateThreadIdFor(getSyncMessageDestination(sent))
}
dataMessage.pollTerminate != null -> threadId = handleSynchronizedPollEnd(envelope, dataMessage, sent, senderRecipient, earlyMessageCacheEntry)
dataMessage.pinMessage != null -> threadId = handleSynchronizedPinMessage(envelope, dataMessage, sent, senderRecipient, earlyMessageCacheEntry)
dataMessage.unpinMessage != null -> {
DataMessageProcessor.handleUnpinMessage(envelope, dataMessage, senderRecipient, threadRecipient, earlyMessageCacheEntry)
threadId = SignalDatabase.threads.getOrCreateThreadIdFor(getSyncMessageDestination(sent))
}
else -> threadId = handleSynchronizeSentTextMessage(sent, envelope.timestamp!!)
}
@@ -1857,6 +1863,59 @@ object SyncMessageProcessor {
return threadId
}
private fun handleSynchronizedPinMessage(
envelope: Envelope,
message: DataMessage,
sent: Sent,
senderRecipient: Recipient,
earlyMessageCacheEntry: EarlyMessageCacheEntry?
): Long {
if (!RemoteConfig.receivePinnedMessages) {
log(envelope.timestamp!!, "Sync pinned messages not allowed due to remote config.")
}
log(envelope.timestamp!!, "Synchronize pinned message")
val recipient = getSyncMessageDestination(sent)
val threadId = SignalDatabase.threads.getOrCreateThreadIdFor(recipient)
val expiresInMillis = message.expireTimerDuration.inWholeMilliseconds
if (recipient.expiresInSeconds != message.expireTimerDuration.inWholeSeconds.toInt() || ((message.expireTimerVersion ?: -1) > recipient.expireTimerVersion)) {
handleSynchronizeSentExpirationUpdate(sent, sideEffect = true)
}
val pinMessage = message.pinMessage!!
val targetMessage = SignalDatabase.messages.getMessageFor(pinMessage.targetSentTimestamp!!, Recipient.self().id)
if (targetMessage == null) {
warn(envelope.timestamp!!, "Unable to find target message for sync message. Putting in early message cache.")
if (earlyMessageCacheEntry != null) {
AppDependencies.earlyMessageCache.store(senderRecipient.id, pinMessage.targetSentTimestamp!!, earlyMessageCacheEntry)
PushProcessEarlyMessagesJob.enqueue()
}
return -1
}
val duration = if (pinMessage.pinDurationForever == true) MessageTable.PIN_FOREVER else pinMessage.pinDurationSeconds!!.toLong()
val outgoingMessage = OutgoingMessage.pinMessage(
threadRecipient = recipient,
sentTimeMillis = sent.timestamp!!,
expiresIn = recipient.expiresInSeconds.seconds.inWholeMilliseconds,
messageExtras = MessageExtras(pinnedMessage = PinnedMessage(pinnedMessageId = targetMessage.id, targetAuthorAci = pinMessage.targetAuthorAciBinary!!, targetTimestamp = pinMessage.targetSentTimestamp!!, pinDurationInSeconds = duration))
)
val messageId = SignalDatabase.messages.insertMessageOutbox(outgoingMessage, threadId, false, GroupReceiptTable.STATUS_UNKNOWN, null).messageId
SignalDatabase.messages.markAsSent(messageId, true)
log(envelope.timestamp!!, "Inserted sync pin message as messageId $messageId")
if (expiresInMillis > 0) {
SignalDatabase.messages.markExpireStarted(messageId, sent.expirationStartTimestamp ?: 0)
AppDependencies.expiringMessageManager.scheduleDeletion(messageId, recipient.isGroup, sent.expirationStartTimestamp ?: 0, expiresInMillis)
}
return threadId
}
private fun ConversationIdentifier.toRecipientId(): RecipientId? {
val threadServiceId = ServiceId.parseOrNull(this.threadServiceId, this.threadServiceIdBinary)
return when {