Fix backup export/import of quote mentions.

This commit is contained in:
Greyson Parrelli 2025-01-24 10:38:16 -05:00
parent a47714d700
commit 252b1dbb2d
19 changed files with 28 additions and 21 deletions

View file

@ -940,13 +940,15 @@ private fun BackupMessageRecord.toRemoteQuote(mediaArchiveEnabled: Boolean, atta
QuoteModel.Type.GIFT_BADGE -> Quote.Type.GIFT_BADGE QuoteModel.Type.GIFT_BADGE -> Quote.Type.GIFT_BADGE
} }
val bodyRanges = this.quoteBodyRanges?.toRemoteBodyRanges(dateSent) ?: emptyList()
return Quote( return Quote(
targetSentTimestamp = this.quoteTargetSentTimestamp.takeIf { !this.quoteMissing && it != MessageTable.QUOTE_TARGET_MISSING_ID }?.clampToValidBackupRange(), targetSentTimestamp = this.quoteTargetSentTimestamp.takeIf { !this.quoteMissing && it != MessageTable.QUOTE_TARGET_MISSING_ID }?.clampToValidBackupRange(),
authorId = this.quoteAuthor, authorId = this.quoteAuthor,
text = this.quoteBody?.let { body -> text = this.quoteBody?.let { body ->
Text( Text(
body = body, body = body,
bodyRanges = this.quoteBodyRanges?.toRemoteBodyRanges(this.dateSent) ?: emptyList() bodyRanges = bodyRanges
) )
}, },
attachments = if (remoteType == Quote.Type.VIEW_ONCE) { attachments = if (remoteType == Quote.Type.VIEW_ONCE) {

View file

@ -383,25 +383,12 @@ class ChatItemArchiveImporter(
} }
if (this.standardMessage != null) { if (this.standardMessage != null) {
val bodyRanges = this.standardMessage.text?.bodyRanges val mentions = this.standardMessage.text?.bodyRanges.filterToLocalMentions()
if (!bodyRanges.isNullOrEmpty()) {
val mentions = bodyRanges.filter { it.mentionAci != null && it.start != null && it.length != null }
.mapNotNull {
val aci = ServiceId.ACI.parseOrNull(it.mentionAci!!)
if (aci != null && !aci.isUnknown) {
val id = RecipientId.from(aci)
Mention(id, it.start!!, it.length!!)
} else {
null
}
}
if (mentions.isNotEmpty()) { if (mentions.isNotEmpty()) {
followUps += { messageId -> followUps += { messageId ->
SignalDatabase.mentions.insert(threadId, messageId, mentions) SignalDatabase.mentions.insert(threadId, messageId, mentions)
} }
} }
}
val linkPreviews = this.standardMessage.linkPreview.map { it.toLocalLinkPreview() } val linkPreviews = this.standardMessage.linkPreview.map { it.toLocalLinkPreview() }
val linkPreviewAttachments: List<Attachment> = linkPreviews.mapNotNull { it.thumbnail.orNull() } val linkPreviewAttachments: List<Attachment> = linkPreviews.mapNotNull { it.thumbnail.orNull() }
val attachments: List<Attachment> = this.standardMessage.attachments.mapNotNull { attachment -> val attachments: List<Attachment> = this.standardMessage.attachments.mapNotNull { attachment ->
@ -929,7 +916,7 @@ class ChatItemArchiveImporter(
this.put(MessageTable.QUOTE_AUTHOR, importState.requireLocalRecipientId(quote.authorId).serialize()) this.put(MessageTable.QUOTE_AUTHOR, importState.requireLocalRecipientId(quote.authorId).serialize())
this.put(MessageTable.QUOTE_BODY, quote.text?.body) this.put(MessageTable.QUOTE_BODY, quote.text?.body)
this.put(MessageTable.QUOTE_TYPE, quote.type.toLocalQuoteType()) this.put(MessageTable.QUOTE_TYPE, quote.type.toLocalQuoteType())
this.put(MessageTable.QUOTE_BODY_RANGES, quote.text?.bodyRanges?.toLocalBodyRanges()?.encode()) this.put(MessageTable.QUOTE_BODY_RANGES, quote.text?.bodyRanges?.toLocalBodyRanges(includeMentions = true)?.encode())
this.put(MessageTable.QUOTE_MISSING, (quote.targetSentTimestamp == null).toInt()) this.put(MessageTable.QUOTE_MISSING, (quote.targetSentTimestamp == null).toInt())
} }
@ -983,13 +970,13 @@ class ChatItemArchiveImporter(
} }
} }
private fun List<BodyRange>.toLocalBodyRanges(): BodyRangeList? { private fun List<BodyRange>.toLocalBodyRanges(includeMentions: Boolean = false): BodyRangeList? {
if (this.isEmpty()) { if (this.isEmpty()) {
return null return null
} }
return BodyRangeList( return BodyRangeList(
ranges = this.filter { it.mentionAci == null }.map { bodyRange -> ranges = this.filter { includeMentions || it.mentionAci == null }.map { bodyRange ->
BodyRangeList.BodyRange( BodyRangeList.BodyRange(
mentionUuid = bodyRange.mentionAci?.let { UuidUtil.fromByteString(it) }?.toString(), mentionUuid = bodyRange.mentionAci?.let { UuidUtil.fromByteString(it) }?.toString(),
style = bodyRange.style?.let { style = bodyRange.style?.let {
@ -1135,6 +1122,24 @@ class ChatItemArchiveImporter(
} }
} }
private fun List<BodyRange>?.filterToLocalMentions(): List<Mention> {
if (this == null) {
return emptyList()
}
return this.filter { it.mentionAci != null && it.start != null && it.length != null }
.mapNotNull {
val aci = ServiceId.ACI.parseOrNull(it.mentionAci!!)
if (aci != null && !aci.isUnknown) {
val id = RecipientId.from(aci)
Mention(id, it.start!!, it.length!!)
} else {
null
}
}
}
private class MessageInsert( private class MessageInsert(
val contentValues: ContentValues, val contentValues: ContentValues,
val followUp: ((Long) -> Unit)?, val followUp: ((Long) -> Unit)?,