aboutsummaryrefslogtreecommitdiff
path: root/libdino/src
diff options
context:
space:
mode:
Diffstat (limited to 'libdino/src')
-rw-r--r--libdino/src/application.vala1
-rw-r--r--libdino/src/entity/message.vala18
-rw-r--r--libdino/src/service/content_item_store.vala23
-rw-r--r--libdino/src/service/database.vala19
-rw-r--r--libdino/src/service/message_correction.vala140
-rw-r--r--libdino/src/service/message_storage.vala4
-rw-r--r--libdino/src/service/occupant_id_store.vala88
-rw-r--r--libdino/src/service/reactions.vala20
-rw-r--r--libdino/src/service/replies.vala2
9 files changed, 253 insertions, 62 deletions
diff --git a/libdino/src/application.vala b/libdino/src/application.vala
index 4aa4b8ad..de1325ad 100644
--- a/libdino/src/application.vala
+++ b/libdino/src/application.vala
@@ -41,6 +41,7 @@ public interface Application : GLib.Application {
BlockingManager.start(stream_interactor);
Calls.start(stream_interactor, db);
ConversationManager.start(stream_interactor, db);
+ OccupantIdStore.start(stream_interactor, db);
MucManager.start(stream_interactor);
AvatarManager.start(stream_interactor, db);
RosterManager.start(stream_interactor, db);
diff --git a/libdino/src/entity/message.vala b/libdino/src/entity/message.vala
index 4de17125..0d53fd70 100644
--- a/libdino/src/entity/message.vala
+++ b/libdino/src/entity/message.vala
@@ -46,6 +46,7 @@ public class Message : Object {
}
public bool direction { get; set; }
public Jid? real_jid { get; set; }
+ public int occupant_db_id { get; set; default=-1; }
public Type type_ { get; set; default = Type.UNKNOWN; }
private string? body_;
public string? body {
@@ -105,9 +106,12 @@ public class Message : Object {
body = row[db.message.body];
marked = (Message.Marked) row[db.message.marked];
encryption = (Encryption) row[db.message.encryption];
+
string? real_jid_str = row[db.real_jid.real_jid];
if (real_jid_str != null) real_jid = new Jid(real_jid_str);
+ occupant_db_id = row[db.message_occupant_id.occupant_id];
+
edit_to = row[db.message_correction.to_stanza_id];
quoted_item_id = row[db.reply.quoted_content_item_id];
@@ -140,6 +144,13 @@ public class Message : Object {
.value(db.real_jid.real_jid, real_jid.to_string())
.perform();
}
+
+ if (occupant_db_id != -1) {
+ db.message_occupant_id.insert()
+ .value(db.message_occupant_id.occupant_id, occupant_db_id)
+ .value(db.message_occupant_id.message_id, id)
+ .perform();
+ }
notify.connect(on_update);
}
@@ -320,6 +331,13 @@ public class Message : Object {
.value(db.reply.quoted_content_item_id, quoted_item_id)
.perform();
}
+
+ if (sp.get_name() == "message-occupant-id" && occupant_db_id != -1) {
+ db.message_occupant_id.upsert()
+ .value(db.message_occupant_id.occupant_id, occupant_db_id, true)
+ .value(db.message_occupant_id.message_id, id)
+ .perform();
+ }
}
}
diff --git a/libdino/src/service/content_item_store.vala b/libdino/src/service/content_item_store.vala
index 7d7ed1fb..b3ec5d67 100644
--- a/libdino/src/service/content_item_store.vala
+++ b/libdino/src/service/content_item_store.vala
@@ -148,31 +148,26 @@ public class ContentItemStore : StreamInteractionModule, Object {
return null;
}
- public ContentItem? get_content_item_for_message_id(Conversation conversation, string message_id) {
- Row? row = get_content_item_row_for_message_id(conversation, message_id);
+ public ContentItem? get_content_item_for_referencing_id(Conversation conversation, string message_id) {
+ Row? row = get_content_item_row_for_referencing_id(conversation, message_id);
if (row != null) {
return get_item_from_row(row, conversation);
}
return null;
}
- public int get_content_item_id_for_message_id(Conversation conversation, string message_id) {
- Row? row = get_content_item_row_for_message_id(conversation, message_id);
+ public int get_content_item_id_for_referencing_id(Conversation conversation, string message_id) {
+ Row? row = get_content_item_row_for_referencing_id(conversation, message_id);
if (row != null) {
return row[db.content_item.id];
}
return -1;
}
- private Row? get_content_item_row_for_message_id(Conversation conversation, string message_id) {
+ private Row? get_content_item_row_for_referencing_id(Conversation conversation, string message_id) {
var content_item_row = db.content_item.select();
- Message? message = null;
- if (conversation.type_ == Conversation.Type.CHAT) {
- message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(message_id, conversation);
- } else {
- message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(message_id, conversation);
- }
+ Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_referencing_id(message_id, conversation);
if (message == null) return null;
RowOption file_transfer_row = db.file_transfer.select()
@@ -186,7 +181,11 @@ public class ContentItemStore : StreamInteractionModule, Object {
content_item_row.with(db.content_item.foreign_id, "=", file_transfer_row[db.file_transfer.id])
.with(db.content_item.content_type, "=", 2);
} else {
- content_item_row.with(db.content_item.foreign_id, "=", message.id)
+ // Check if this message has been corrected. In that case, the foreign id is the latest correction.
+ int correction_message_db_id = stream_interactor.get_module(MessageCorrection.IDENTITY).get_latest_correction_message_id(conversation, message_id);
+ int message_db_id = correction_message_db_id != -1 ? correction_message_db_id : message.id;
+
+ content_item_row.with(db.content_item.foreign_id, "=", message_db_id)
.with(db.content_item.content_type, "=", 1);
}
RowOption content_item_row_option = content_item_row.single().row();
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala
index e47e24e9..58ff3b14 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 = 29;
+ private const int VERSION = 30;
public class AccountTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
@@ -103,6 +103,19 @@ public class Database : Qlite.Database {
}
}
+ public class MessageOccupantId : Table {
+ public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
+ public Column<int> message_id = new Column.Integer("message_id") { not_null = true };
+ public Column<int> occupant_id = new Column.Integer("occupant_id") { not_null = true };
+
+ internal MessageOccupantId(Database db) {
+ base(db, "message_occupant_id");
+ init({id, message_id, occupant_id});
+
+ index("message_id_occupant_id", { message_id, occupant_id });
+ }
+ }
+
public class BodyMeta : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
public Column<int> message_id = new Column.Integer("message_id");
@@ -440,6 +453,7 @@ public class Database : Qlite.Database {
public EntityTable entity { get; private set; }
public ContentItemTable content_item { get; private set; }
public MessageTable message { get; private set; }
+ public MessageOccupantId message_occupant_id { get; private set; }
public BodyMeta body_meta { get; private set; }
public ReplyTable reply { get; private set; }
public MessageCorrectionTable message_correction { get; private set; }
@@ -473,6 +487,7 @@ public class Database : Qlite.Database {
entity = new EntityTable(this);
content_item = new ContentItemTable(this);
message = new MessageTable(this);
+ message_occupant_id = new MessageOccupantId(this);
body_meta = new BodyMeta(this);
message_correction = new MessageCorrectionTable(this);
reply = new ReplyTable(this);
@@ -494,7 +509,7 @@ public class Database : Qlite.Database {
settings = new SettingsTable(this);
account_settings = new AccountSettingsTable(this);
conversation_settings = new ConversationSettingsTable(this);
- init({ account, jid, entity, content_item, message, body_meta, message_correction, reply, real_jid, occupantid, file_transfer, file_hashes, file_thumbnails, sfs_sources, call, call_counterpart, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, reaction, settings, account_settings, conversation_settings });
+ init({ account, jid, entity, content_item, message, message_occupant_id, body_meta, message_correction, reply, real_jid, occupantid, file_transfer, file_hashes, file_thumbnails, sfs_sources, call, call_counterpart, conversation, avatar, entity_identity, entity_feature, roster, mam_catchup, reaction, settings, account_settings, conversation_settings });
try {
exec("PRAGMA journal_mode = WAL");
diff --git a/libdino/src/service/message_correction.vala b/libdino/src/service/message_correction.vala
index 08145a6b..191f737f 100644
--- a/libdino/src/service/message_correction.vala
+++ b/libdino/src/service/message_correction.vala
@@ -16,8 +16,9 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
private StreamInteractor stream_interactor;
private Database db;
- private HashMap<Conversation, HashMap<Jid, Message>> last_messages = new HashMap<Conversation, HashMap<Jid, Message>>(Conversation.hash_func, Conversation.equals_func);
+ public HashMap<Conversation, Gee.List<ContentItem>> unmatched_corrections = new HashMap<Conversation, Gee.List<ContentItem>>(Conversation.hash_func, Conversation.equals_func);
+ private HashMap<Conversation, HashMap<Jid, Message>> last_messages = new HashMap<Conversation, HashMap<Jid, Message>>(Conversation.hash_func, Conversation.equals_func);
private HashMap<string, string> outstanding_correction_nodes = new HashMap<string, string>();
public static void start(StreamInteractor stream_interactor, Database db) {
@@ -37,6 +38,7 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
if (last_messages.has_key(conversation)) last_messages[conversation].unset(jid);
}
});
+ stream_interactor.get_module(ContentItemStore.IDENTITY).new_item.connect(cache_unmatched_correction);
}
public void set_correction(Conversation conversation, Message message, Message old_message) {
@@ -90,51 +92,110 @@ 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) {
- if (conversation.type_ != Conversation.Type.CHAT) {
- // Don't process messages or corrections from MUC history or MUC MAM
- DateTime? mam_delay = Xep.DelayedDelivery.get_time_for_message(stanza, message.from.bare_jid);
- if (mam_delay != null) return false;
- if (Xmpp.MessageArchiveManagement.MessageFlag.get_flag(stanza) != null) return false;
+ if (unmatched_corrections.has_key(conversation) && unmatched_corrections[conversation].size > 0) {
+ ContentItem? remove_from_list = null;
+ bool? ret = null;
+ 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) {
+ 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);
+ } else if (unmatched_correction_message_item.message.edit_to == message.edit_to) {
+ debug("Got another correction to the same (unknown) original message %s", message.edit_to);
+ ret = process_wrong_order_correction(conversation, message, unmatched_correction_message_item);
+ }
+ }
+ }
+ if (remove_from_list != null) unmatched_corrections[conversation].remove(remove_from_list);
+ if (ret != null) return ret;
}
string? replace_id = Xep.LastMessageCorrection.get_replace_id(stanza);
- if (replace_id == null) {
- if (!last_messages.has_key(conversation)) {
- last_messages[conversation] = new HashMap<Jid, Message>(Jid.hash_func, Jid.equals_func);
+
+ // 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()) {
+ // Don't process messages or corrections from MUC history or MUC MAM
+ if (Xep.DelayedDelivery.get_time_for_message(stanza, message.from.bare_jid) == null &&
+ Xmpp.MessageArchiveManagement.MessageFlag.get_flag(stanza) == null) {
+ if (!last_messages.has_key(conversation)) {
+ last_messages[conversation] = new HashMap<Jid, Message>(Jid.hash_func, Jid.equals_func);
+ }
+ last_messages[conversation][message.from] = message;
+ }
+ }
+
+ if (replace_id != null) {
+ var correction_message = message;
+ correction_message.edit_to = replace_id; // This isn't persisted TODO
+
+ // Check if it's maybe accepted by the XEP rules (for MUCs without occupant id)
+ if (conversation.type_.is_muc_semantic()) {
+ if (last_messages.has_key(conversation) && last_messages[conversation].has_key(correction_message.from)) {
+ var last_message = last_messages[conversation][correction_message.from];
+ // TODO this should be the referencing id (-> in MUCs the server id), but this implementation is temporarily for backwards-compatibility.
+ bool acceptable = last_message.stanza_id == replace_id || last_message.server_id == replace_id;
+ if (acceptable) {
+ return process_in_order_correction(conversation, last_messages[conversation][correction_message.from], correction_message);
+ }
+ }
}
- last_messages[conversation][message.from] = message;
+ Message? original_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_referencing_id(replace_id, conversation);
+ if (original_message != null && is_correction_acceptable(original_message, correction_message)) {
+ return process_in_order_correction(conversation, original_message, correction_message);
+ }
return false;
}
+ return false;
+ }
- if (!last_messages.has_key(conversation) || !last_messages[conversation].has_key(message.from)) return false;
- Message original_message = last_messages[conversation][message.from];
- // TODO this should be the referencing id (-> in MUCs the server id), but this implementation is temporarily for backwards-compatibility.
- if (original_message.stanza_id != replace_id && original_message.server_id != replace_id) return false;
+ private bool process_wrong_order_correction(Conversation conversation, Message earlier_message, MessageItem correction_message) {
+ if (!is_correction_acceptable(earlier_message, correction_message.message)) {
+ return false;
+ }
+
+ db.content_item.update()
+ .with(db.content_item.id, "=", correction_message.id)
+ .set(db.content_item.time, (long) earlier_message.time.to_unix())
+ .set(db.content_item.local_time, (long) earlier_message.local_time.to_unix())
+ .perform();
+
+ correction_message.time = earlier_message.time;
- int message_id_to_be_updated = get_latest_correction_message_id(conversation.account.id, replace_id, db.get_jid_id(message.counterpart), message.counterpart.resourcepart);
+ on_received_correction(conversation, correction_message.message.id);
+
+ return true;
+ }
+
+ private bool process_in_order_correction(Conversation conversation, Message original_message, Message correction_message) {
+ int message_id_to_be_updated = get_latest_correction_message_id(conversation, correction_message.edit_to);
if (message_id_to_be_updated == -1) {
message_id_to_be_updated = original_message.id;
}
- db.message_correction.insert()
- .value(db.message_correction.message_id, message.id)
- .value(db.message_correction.to_stanza_id, replace_id)
- .perform();
+ ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_for_referencing_id(conversation, correction_message.edit_to);
- int current_correction_message_id = get_latest_correction_message_id(conversation.account.id, replace_id, db.get_jid_id(message.counterpart), message.counterpart.resourcepart);
+ db.message_correction.insert()
+ .value(db.message_correction.message_id, correction_message.id)
+ .value(db.message_correction.to_stanza_id, correction_message.edit_to)
+ .perform();
- if (current_correction_message_id != message_id_to_be_updated) {
+ int current_correction_message_id = get_latest_correction_message_id(conversation, correction_message.edit_to);
+ if (content_item != null) {
db.content_item.update()
- .with(db.content_item.foreign_id, "=", message_id_to_be_updated)
+ .with(db.content_item.id, "=", content_item.id)
.with(db.content_item.content_type, "=", 1)
.set(db.content_item.foreign_id, current_correction_message_id)
.perform();
- message.edit_to = replace_id;
on_received_correction(conversation, current_correction_message_id);
return true;
+ } else {
+ warning("Got no content item for %s", correction_message.edit_to);
}
return false;
@@ -147,16 +208,16 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
}
}
- private int get_latest_correction_message_id(int account_id, string stanza_id, int counterpart_jid_id, string? counterpart_resource) {
+ public int get_latest_correction_message_id(Conversation conversation, string stanza_ref_id) {
var qry = db.message_correction.select({db.message.id})
.join_with(db.message, db.message.id, db.message_correction.message_id)
- .with(db.message.account_id, "=", account_id)
- .with(db.message.counterpart_id, "=", counterpart_jid_id)
- .with(db.message_correction.to_stanza_id, "=", stanza_id)
+ .with(db.message.account_id, "=", conversation.account.id)
+ .with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart))
+ .with(db.message_correction.to_stanza_id, "=", stanza_ref_id)
.order_by(db.message.time, "DESC");
- if (counterpart_resource != null) {
- qry.with(db.message.counterpart_resource, "=", counterpart_resource);
+ if (conversation.counterpart.resourcepart != null) {
+ qry.with(db.message.counterpart_resource, "=", conversation.counterpart.resourcepart);
}
RowOption row = qry.single().row();
if (row.is_present()) {
@@ -181,6 +242,27 @@ public class MessageCorrection : StreamInteractionModule, MessageListener {
last_messages[conversation] = last_conversation_messages;
}
}
+
+ private void cache_unmatched_correction(ContentItem content_item, Conversation conversation) {
+ MessageItem message_item = content_item as MessageItem;
+ if (message_item == null || message_item.message.edit_to == null) return;
+
+ // Check if this is an unmatched correction
+ if (content_item.time != message_item.time) return;
+
+ debug(@"Caching unmatched correction $(message_item.message.server_id) $(message_item.id)");
+ if (!unmatched_corrections.has_key(conversation)) unmatched_corrections[conversation] = new ArrayList<ContentItem>();
+ unmatched_corrections[conversation].add(content_item);
+ }
}
+ // Accepts MUC corrections iff the occupant id matches
+ // Accepts 1:1 corrections iff the bare jid matches
+ private bool is_correction_acceptable(Message original_message, Message correction_message) {
+ bool acceptable = (original_message.type_.is_muc_semantic() && original_message.occupant_db_id != -1 && original_message.occupant_db_id == correction_message.occupant_db_id) ||
+ (original_message.type_ == Message.Type.CHAT && original_message.from.equals_bare(correction_message.from));
+ if (!acceptable) warning("Got unacceptable correction (%i to %i from %s)", correction_message.id, original_message.id, correction_message.from.to_string());
+ return acceptable;
+ }
+
}
diff --git a/libdino/src/service/message_storage.vala b/libdino/src/service/message_storage.vala
index 81df46d5..59e43d32 100644
--- a/libdino/src/service/message_storage.vala
+++ b/libdino/src/service/message_storage.vala
@@ -41,6 +41,7 @@ public class MessageStorage : StreamInteractionModule, Object {
.with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart))
.with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation))
.order_by(db.message.time, "DESC")
+ .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id)
.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id)
.outer_join_with(db.reply, db.reply.message_id, db.message.id)
.limit(count);
@@ -92,6 +93,7 @@ public class MessageStorage : StreamInteractionModule, Object {
}
RowOption row_option = db.message.select().with(db.message.id, "=", id)
+ .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id)
.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id)
.outer_join_with(db.reply, db.reply.message_id, db.message.id)
.row();
@@ -121,6 +123,7 @@ public class MessageStorage : StreamInteractionModule, Object {
.with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation))
.with(db.message.stanza_id, "=", stanza_id)
.order_by(db.message.time, "DESC")
+ .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id)
.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id)
.outer_join_with(db.reply, db.reply.message_id, db.message.id);
@@ -147,6 +150,7 @@ public class MessageStorage : StreamInteractionModule, Object {
.with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation))
.with(db.message.server_id, "=", server_id)
.order_by(db.message.time, "DESC")
+ .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id)
.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id)
.outer_join_with(db.reply, db.reply.message_id, db.message.id);
diff --git a/libdino/src/service/occupant_id_store.vala b/libdino/src/service/occupant_id_store.vala
new file mode 100644
index 00000000..662b9cbb
--- /dev/null
+++ b/libdino/src/service/occupant_id_store.vala
@@ -0,0 +1,88 @@
+using Xmpp;
+using Gee;
+using Qlite;
+
+using Dino.Entities;
+
+namespace Dino {
+
+ public class OccupantIdStore : StreamInteractionModule, Object {
+ public static ModuleIdentity<OccupantIdStore> IDENTITY = new ModuleIdentity<OccupantIdStore>("occupant_id_cache");
+ public string id { get { return IDENTITY.id; } }
+
+ private Database db;
+
+ // (Account, MUC JID, occupant id) -> occupant db id
+ private HashMap<Account, HashMap<Jid, HashMap<string, int>>> occupant_db_ids = new HashMap<Account, HashMap<Jid, HashMap<string, int>>>(Account.hash_func, Account.equals_func);
+ private HashMap<int, string> occupant_nicks = new HashMap<int, string>();
+
+ public static void start(StreamInteractor stream_interactor, Database db) {
+ OccupantIdStore m = new OccupantIdStore(db);
+ stream_interactor.add_module(m);
+ }
+
+ private OccupantIdStore(Database db) {
+ this.db = db;
+ }
+
+ public int get_occupant_db_id(Account account, string occupant_id, Jid muc_jid) {
+ if (!occupant_db_ids.has_key(account) || !occupant_db_ids[account].has_key(muc_jid) || !occupant_db_ids[account][muc_jid].has_key(occupant_id)) {
+ warning("Requested unknown occupant db id");
+ return -1;
+ }
+
+ return occupant_db_ids[account][muc_jid][occupant_id];
+ }
+
+ public int cache_occupant_id(Account account, string occupant_id, Jid occupant_jid) {
+ string last_nick = occupant_jid.resourcepart;
+ Jid muc_jid = occupant_jid.bare_jid;
+
+ if (occupant_db_ids.has_key(account) && occupant_db_ids[account].has_key(muc_jid) && occupant_db_ids[account][muc_jid].has_key(occupant_id)) {
+ int occupant_db_id = occupant_db_ids[account][muc_jid][occupant_id];
+ if (occupant_nicks[occupant_db_id] == last_nick) {
+ return occupant_db_id;
+ }
+ }
+
+ if (!occupant_db_ids.has_key(account)) occupant_db_ids[account] = new HashMap<Jid, HashMap<string, int>>(Jid.hash_bare_func, Jid.equals_bare_func);
+ if (!occupant_db_ids[account].has_key(muc_jid)) occupant_db_ids[account][muc_jid] = new HashMap<string, int>();
+
+ int muc_jid_id = db.get_jid_id(muc_jid);
+
+ RowOption row = db.occupantid.select()
+ .with(db.occupantid.account_id, "=", account.id)
+ .with(db.occupantid.jid_id, "=", muc_jid_id)
+ .with(db.occupantid.occupant_id, "=", occupant_id)
+ .single().row();
+
+ int occupant_db_id = -1;
+ if (row.is_present()) {
+ occupant_db_id = row[db.occupantid.id];
+
+ if (row[db.occupantid.last_nick] != last_nick) {
+ db.occupantid.upsert()
+ .value(db.occupantid.account_id, account.id, true)
+ .value(db.occupantid.jid_id, muc_jid_id, true)
+ .value(db.occupantid.occupant_id, occupant_id, true)
+ .value(db.occupantid.last_nick, last_nick, false)
+ .perform();
+ }
+ } else {
+ occupant_db_id = (int)db.occupantid.upsert()
+ .value(db.occupantid.account_id, account.id, true)
+ .value(db.occupantid.jid_id, muc_jid_id, true)
+ .value(db.occupantid.occupant_id, occupant_id, true)
+ .value(db.occupantid.last_nick, muc_jid.resourcepart, false)
+ .perform();
+ }
+
+ occupant_db_ids[account][muc_jid][occupant_id] = occupant_db_id;
+ occupant_nicks[occupant_db_id] = last_nick;
+
+ return occupant_db_id;
+ }
+
+
+ }
+} \ No newline at end of file
diff --git a/libdino/src/service/reactions.vala b/libdino/src/service/reactions.vala
index 91651db7..f6050d28 100644
--- a/libdino/src/service/reactions.vala
+++ b/libdino/src/service/reactions.vala
@@ -251,7 +251,7 @@ public class Dino.Reactions : StreamInteractionModule, Object {
Message reaction_message = yield stream_interactor.get_module(MessageProcessor.IDENTITY).parse_message_stanza(account, stanza);
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_for_message(reaction_message);
- int content_item_id = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_id_for_message_id(conversation, message_id);
+ int content_item_id = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_id_for_referencing_id(conversation, message_id);
var reaction_info = new ReactionInfo() { conversation=conversation, from_jid=from_jid, reactions=reactions, stanza=stanza, received_time=new DateTime.now() };
if (content_item_id != -1) {
@@ -425,23 +425,7 @@ public class Dino.Reactions : StreamInteractionModule, Object {
}
if (occupant_id != null) {
- RowOption row = db.occupantid.select()
- .with(db.occupantid.account_id, "=", account.id)
- .with(db.occupantid.jid_id, "=", jid_id)
- .with(db.occupantid.occupant_id, "=", occupant_id)
- .single().row();
-
- int occupant_db_id = -1;
- if (row.is_present()) {
- occupant_db_id = row[db.occupantid.id];
- } else {
- occupant_db_id = (int)db.occupantid.upsert()
- .value(db.occupantid.account_id, account.id, true)
- .value(db.occupantid.jid_id, jid_id, true)
- .value(db.occupantid.occupant_id, occupant_id, true)
- .value(db.occupantid.last_nick, jid.resourcepart, false)
- .perform();
- }
+ int occupant_db_id = stream_interactor.get_module(OccupantIdStore.IDENTITY).cache_occupant_id(account, occupant_id, jid);
builder.value(db.reaction.occupant_id, occupant_db_id, true);
}
diff --git a/libdino/src/service/replies.vala b/libdino/src/service/replies.vala
index cc9f43cc..ea10cf88 100644
--- a/libdino/src/service/replies.vala
+++ b/libdino/src/service/replies.vala
@@ -64,7 +64,7 @@ public class Dino.Replies : StreamInteractionModule, Object {
Xep.Replies.ReplyTo? reply_to = Xep.Replies.get_reply_to(stanza);
if (reply_to == null) return;
- ContentItem? quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_for_message_id(conversation, reply_to.to_message_id);
+ ContentItem? quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_for_referencing_id(conversation, reply_to.to_message_id);
if (quoted_content_item == null) return;
message.set_quoted_item(quoted_content_item.id);