aboutsummaryrefslogtreecommitdiff
path: root/libdino/src/service
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2026-03-25 19:19:29 +0100
committerfiaxh <git@lightrise.org>2026-03-25 19:20:26 +0100
commit0b92ee2a113ca8da2d3a4d4b06056f291738b5fe (patch)
treee1279162ba45c66397d0ef0b9f3ad4ffda055c50 /libdino/src/service
parentcf352dbf57add6e038fc919172bb5d32fb5f775f (diff)
Fix wrongly using message ids for MUC corrections; store original message db ids
Diffstat (limited to 'libdino/src/service')
-rw-r--r--libdino/src/service/content_item_store.vala2
-rw-r--r--libdino/src/service/database.vala5
-rw-r--r--libdino/src/service/message_correction.vala22
-rw-r--r--libdino/src/service/message_storage.vala17
4 files changed, 35 insertions, 11 deletions
diff --git a/libdino/src/service/content_item_store.vala b/libdino/src/service/content_item_store.vala
index 11512a53..99475492 100644
--- a/libdino/src/service/content_item_store.vala
+++ b/libdino/src/service/content_item_store.vala
@@ -121,7 +121,7 @@ public class ContentItemStore : StreamInteractionModule, Object {
Message? message = get_message_for_content_item(conversation, content_item);
if (message == null) return null;
- return MessageStorage.get_reference_id(message);
+ return stream_interactor.get_module(MessageStorage.IDENTITY).get_reference_id(message, conversation);
}
public Jid? get_message_sender_for_content_item(Conversation conversation, ContentItem content_item) {
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala
index 58ff3b14..54f5ab42 100644
--- a/libdino/src/service/database.vala
+++ b/libdino/src/service/database.vala
@@ -7,7 +7,7 @@ using Dino.Entities;
namespace Dino {
public class Database : Qlite.Database {
- private const int VERSION = 30;
+ private const int VERSION = 31;
public class AccountTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
@@ -134,10 +134,11 @@ public class Database : Qlite.Database {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
public Column<int> message_id = new Column.Integer("message_id") { unique=true };
public Column<string> to_stanza_id = new Column.Text("to_stanza_id");
+ public Column<int> to_message_db_id = new Column.Integer("to_message_db_id") { min_version=31 };
internal MessageCorrectionTable(Database db) {
base(db, "message_correction");
- init({id, message_id, to_stanza_id});
+ init({id, message_id, to_stanza_id, to_message_db_id});
index("message_correction_to_stanza_id_idx", {to_stanza_id});
}
}
diff --git a/libdino/src/service/message_correction.vala b/libdino/src/service/message_correction.vala
index 6c4383ba..2d710f1c 100644
--- a/libdino/src/service/message_correction.vala
+++ b/libdino/src/service/message_correction.vala
@@ -49,6 +49,7 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
db.message_correction.insert()
.value(db.message_correction.message_id, message.id)
.value(db.message_correction.to_stanza_id, reference_stanza_id)
+ .value(db.message_correction.to_message_db_id, old_message.id)
.perform();
db.content_item.update()
@@ -92,6 +93,12 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
public override string[] after_actions { get { return after_actions_const; } }
public override async bool run(Entities.Message message, Xmpp.MessageStanza stanza, Conversation conversation) {
+
+ string? replace_id = Xep.LastMessageCorrection.get_replace_id(stanza);
+ if (replace_id != null) {
+ message.edit_to = replace_id; // This isn't persisted here, but later after verifying that it's an allowed edit TODO?
+ }
+
// Check if we already know a newer correction for this message
if (unmatched_corrections.has_key(conversation) && unmatched_corrections[conversation].size > 0) {
ContentItem? remove_from_list = null;
@@ -99,7 +106,7 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
foreach (var unmatched_correction_item in unmatched_corrections[conversation]) {
MessageItem unmatched_correction_message_item = unmatched_correction_item as MessageItem;
if (unmatched_correction_message_item != null) {
- if (MessageStorage.get_reference_id(message) == unmatched_correction_message_item.message.edit_to) {
+ if (stream_interactor.get_module(MessageStorage.IDENTITY).get_reference_id(message, conversation) == unmatched_correction_message_item.message.edit_to) {
debug("Matching original message to correction retrospectively %s", unmatched_correction_message_item.message.edit_to);
remove_from_list = unmatched_correction_item;
ret = process_wrong_order_correction(conversation, message, unmatched_correction_message_item);
@@ -113,8 +120,6 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
if (ret != null) return ret;
}
- string? replace_id = Xep.LastMessageCorrection.get_replace_id(stanza);
-
// Store the latest message for every resource. This enables the corrections-allowed-check specified in the XEP.
// This is only needed for MUCs - In case the MUC doesn't support occupant ids, the last message can still be corrected.
if (replace_id == null && conversation.type_.is_muc_semantic()) {
@@ -129,7 +134,6 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
}
if (replace_id != null) {
- message.edit_to = replace_id; // This isn't persisted here, but later after verifying that it's an allowed edit TODO?
return process_unverified_in_order_correction(conversation, message, replace_id);
}
return false;
@@ -140,10 +144,14 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
return false;
}
- db.message_correction.insert()
+ var qry = db.message_correction.insert()
.value(db.message_correction.message_id, correction_item.message.id)
- .value(db.message_correction.to_stanza_id, correction_item.message.edit_to)
+ .value(db.message_correction.to_stanza_id, correction_item.message.edit_to);
+ if (earlier_message.edit_to == null) {
+ // If this is the original message, link the id
+ qry.value(db.message_correction.to_message_db_id, earlier_message.id)
.perform();
+ }
db.content_item.update()
.with(db.content_item.id, "=", correction_item.id)
@@ -171,6 +179,7 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
Message? original_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(replace_id, conversation);
if (original_message != null && is_correction_acceptable(original_message, correction_message)) {
correction_message.edit_to = replace_id;
+ correction_message.edit_to_id = original_message.id;
return process_in_order_correction(conversation, original_message, correction_message);
}
return false;
@@ -182,6 +191,7 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
db.message_correction.insert()
.value(db.message_correction.message_id, correction_message.id)
.value(db.message_correction.to_stanza_id, correction_message.edit_to)
+ .value(db.message_correction.to_message_db_id, original_message.id)
.perform();
int current_correction_message_id = get_latest_correction_message_id(conversation, original_message);
diff --git a/libdino/src/service/message_storage.vala b/libdino/src/service/message_storage.vala
index 59e43d32..d6b8d6e3 100644
--- a/libdino/src/service/message_storage.vala
+++ b/libdino/src/service/message_storage.vala
@@ -204,8 +204,21 @@ public class MessageStorage : StreamInteractionModule, Object {
}
}
- public static string? get_reference_id(Message message) {
- if (message.edit_to != null) return message.edit_to;
+ public string? get_reference_id(Message message, Conversation conversation) {
+ if (message.edit_to != null) {
+ // This is a message edit, so the reference id should be the one of the original message
+ if (message.type_ == Message.Type.CHAT) {
+ return message.edit_to;
+ } else {
+ if (message.edit_to_id != 0) {
+ Message original_message = get_message_by_id(message.edit_to_id, conversation);
+ return original_message.server_id;
+ } else {
+ // We don't know the original message, so taking the server id of the correction is the best we can do
+ return message.server_id;
+ }
+ }
+ }
if (message.type_ == Message.Type.CHAT) {
return message.stanza_id;