From fb36ea055301b6db513a31acde30f315e2c0fd68 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Wed, 16 Aug 2017 11:44:42 +0200 Subject: Message Archive Management --- libdino/src/entity/account.vala | 7 ++++++- libdino/src/plugin/interfaces.vala | 2 +- libdino/src/service/chat_interaction.vala | 4 +++- libdino/src/service/database.vala | 5 +++-- libdino/src/service/message_processor.vala | 21 ++++++++++++++++++--- libdino/src/service/module_manager.vala | 1 + 6 files changed, 32 insertions(+), 8 deletions(-) (limited to 'libdino/src') diff --git a/libdino/src/entity/account.vala b/libdino/src/entity/account.vala index 23544b46..f0628ca4 100644 --- a/libdino/src/entity/account.vala +++ b/libdino/src/entity/account.vala @@ -16,6 +16,7 @@ public class Account : Object { public string? alias { get; set; } public bool enabled { get; set; default = false; } public string? roster_version { get; set; } + public DateTime mam_earliest_synced { get; set; default=new DateTime.from_unix_utc(0); } private Database? db; @@ -36,6 +37,7 @@ public class Account : Object { alias = row[db.account.alias]; enabled = row[db.account.enabled]; roster_version = row[db.account.roster_version]; + mam_earliest_synced = new DateTime.from_unix_utc(row[db.account.mam_earliest_synced]); notify.connect(on_update); } @@ -49,6 +51,7 @@ public class Account : Object { .value(db.account.alias, alias) .value(db.account.enabled, enabled) .value(db.account.roster_version, roster_version) + .value(db.account.mam_earliest_synced, (long)mam_earliest_synced.to_unix()) .perform(); notify.connect(on_update); @@ -88,9 +91,11 @@ public class Account : Object { update.set(db.account.enabled, enabled); break; case "roster-version": update.set(db.account.roster_version, roster_version); break; + case "mam-earliest-synced": + update.set(db.account.mam_earliest_synced, (long)mam_earliest_synced.to_unix()); break; } update.perform(); } } -} \ No newline at end of file +} diff --git a/libdino/src/plugin/interfaces.vala b/libdino/src/plugin/interfaces.vala index 178ca1ab..dbed6a00 100644 --- a/libdino/src/plugin/interfaces.vala +++ b/libdino/src/plugin/interfaces.vala @@ -50,7 +50,7 @@ public abstract class ContactDetailsProvider : Object { public class ContactDetails : Object { public signal void save(); - public signal void add(string category, string label, string desc, Widget widget); + public signal void add(string category, string label, string? desc, Widget widget); } public abstract class ConversationTitlebarEntry : Object { diff --git a/libdino/src/service/chat_interaction.vala b/libdino/src/service/chat_interaction.vala index d7b8f839..3e8f4b24 100644 --- a/libdino/src/service/chat_interaction.vala +++ b/libdino/src/service/chat_interaction.vala @@ -124,6 +124,8 @@ public class ChatInteraction : StreamInteractionModule, Object { } private void on_message_received(Entities.Message message, Conversation conversation) { + if (Xep.MessageArchiveManagement.MessageFlag.get_flag(message.stanza) != null) return; + send_delivery_receipt(conversation, message); if (is_active_focus(conversation)) { check_send_read(); @@ -160,4 +162,4 @@ public class ChatInteraction : StreamInteractionModule, Object { } } -} \ No newline at end of file +} diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index b414b943..5a7eb46d 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -6,7 +6,7 @@ using Dino.Entities; namespace Dino { public class Database : Qlite.Database { - private const int VERSION = 3; + private const int VERSION = 4; public class AccountTable : Table { public Column id = new Column.Integer("id") { primary_key = true, auto_increment = true }; @@ -16,10 +16,11 @@ public class Database : Qlite.Database { public Column alias = new Column.Text("alias"); public Column enabled = new Column.BoolInt("enabled"); public Column roster_version = new Column.Text("roster_version") { min_version=2 }; + public Column mam_earliest_synced = new Column.Long("mam_earliest_synced") { min_version=4 }; internal AccountTable(Database db) { base(db, "account"); - init({id, bare_jid, resourcepart, password, alias, enabled, roster_version}); + init({id, bare_jid, resourcepart, password, alias, enabled, roster_version, mam_earliest_synced}); } } diff --git a/libdino/src/service/message_processor.vala b/libdino/src/service/message_processor.vala index 390199d5..85b62a42 100644 --- a/libdino/src/service/message_processor.vala +++ b/libdino/src/service/message_processor.vala @@ -44,6 +44,9 @@ public class MessageProcessor : StreamInteractionModule, Object { stream_interactor.module_manager.get_module(account, Xmpp.Message.Module.IDENTITY).received_message.connect( (stream, message) => { on_message_received(account, message); }); + stream_interactor.module_manager.get_module(account, Xmpp.Xep.MessageArchiveManagement.Module.IDENTITY).feature_available.connect( (stream) => { + stream.get_module(Xep.MessageArchiveManagement.Module.IDENTITY).query_archive(stream, null, account.mam_earliest_synced.add_minutes(-1), null); + }); } private void send_unsent_messages(Account account) { @@ -80,9 +83,15 @@ public class MessageProcessor : StreamInteractionModule, Object { new_message.counterpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.to) : new Jid(message.from); new_message.ourpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.from) : new Jid(message.to); new_message.stanza = message; - Xep.DelayedDelivery.MessageFlag? deleyed_delivery_flag = Xep.DelayedDelivery.MessageFlag.get_flag(message); - new_message.time = deleyed_delivery_flag != null ? deleyed_delivery_flag.datetime : new DateTime.now_local(); - new_message.local_time = new DateTime.now_local(); + + Xep.MessageArchiveManagement.MessageFlag? mam_message_flag = Xep.MessageArchiveManagement.MessageFlag.get_flag(message); + if (mam_message_flag != null) new_message.local_time = mam_message_flag.server_time; + if (new_message.local_time == null || new_message.local_time.compare(new DateTime.now_local()) > 0) new_message.local_time = new DateTime.now_local(); + + Xep.DelayedDelivery.MessageFlag? delayed_message_flag = Xep.DelayedDelivery.MessageFlag.get_flag(message); + if (delayed_message_flag != null) new_message.time = delayed_message_flag.datetime; + if (new_message.time == null || new_message.time.compare(new_message.local_time) > 0) new_message.time = new_message.local_time; + return new_message; } @@ -100,6 +109,12 @@ public class MessageProcessor : StreamInteractionModule, Object { } else { message_received(new_message, conversation); } + + Core.XmppStream? stream = stream_interactor.get_stream(conversation.account); + Xep.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xep.MessageArchiveManagement.Flag.IDENTITY) : null; + if (Xep.MessageArchiveManagement.MessageFlag.get_flag(stanza) != null || (mam_flag != null && mam_flag.cought_up == true)) { + conversation.account.mam_earliest_synced = new_message.local_time; + } } } } diff --git a/libdino/src/service/module_manager.vala b/libdino/src/service/module_manager.vala index 437ecaf0..c2acf9ed 100644 --- a/libdino/src/service/module_manager.vala +++ b/libdino/src/service/module_manager.vala @@ -64,6 +64,7 @@ public class ModuleManager { module_map[account].add(new Xep.Bookmarks.Module()); module_map[account].add(new Presence.Module()); module_map[account].add(new Xmpp.Message.Module()); + module_map[account].add(new Xep.MessageArchiveManagement.Module()); module_map[account].add(new Xep.MessageCarbons.Module()); module_map[account].add(new Xep.Muc.Module()); module_map[account].add(new Xep.Pubsub.Module()); -- cgit v1.2.3-70-g09d2