Add button to fetch MAM history for conversation

This commit is contained in:
Konstantin Kuznetsov 2024-03-12 11:30:39 +03:00
parent bf9f401743
commit bf07ecddb3
5 changed files with 80 additions and 0 deletions

View file

@ -120,6 +120,31 @@ public class Dino.HistorySync {
} }
} }
public async void fetch_history(Account account, Jid target, Cancellable? cancellable = null) {
debug("Fetch history for %s", target.to_string());
RowOption latest_row_opt = db.mam_catchup.select()
.with(db.mam_catchup.account_id, "=", account.id)
.with(db.mam_catchup.server_jid, "=", target.to_string())
.with(db.mam_catchup.to_time, ">=", (long) new DateTime.from_unix_utc(0).to_unix())
.order_by(db.mam_catchup.to_time, "DESC")
.single().row();
Row? latest_row = latest_row_opt.is_present() ? latest_row_opt.inner : null;
if (latest_row == null) {
warning("Failed to fetch history for %s, no mam catchup data", target.to_string());
return;
}
DateTime latest_time = new DateTime.now();
string latest_id = latest_row[db.mam_catchup.from_id];
Xmpp.MessageArchiveManagement.V2.MamQueryParams query_params;
query_params = new Xmpp.MessageArchiveManagement.V2.MamQueryParams.query_before(target, latest_time, latest_id);
yield fetch_query(account, query_params, latest_row[db.mam_catchup.id], cancellable);
}
public async void fetch_everything(Account account, Jid mam_server, Cancellable? cancellable = null, DateTime until_earliest_time = new DateTime.from_unix_utc(0)) { public async void fetch_everything(Account account, Jid mam_server, Cancellable? cancellable = null, DateTime until_earliest_time = new DateTime.from_unix_utc(0)) {
debug("Fetch everything for %s %s", mam_server.to_string(), until_earliest_time != null ? @"(until $until_earliest_time)" : ""); debug("Fetch everything for %s %s", mam_server.to_string(), until_earliest_time != null ? @"(until $until_earliest_time)" : "");
RowOption latest_row_opt = db.mam_catchup.select() RowOption latest_row_opt = db.mam_catchup.select()

View file

@ -203,6 +203,7 @@ SOURCES
src/ui/contact_details/settings_provider.vala src/ui/contact_details/settings_provider.vala
src/ui/contact_details/permissions_provider.vala src/ui/contact_details/permissions_provider.vala
src/ui/contact_details/history_provider.vala
src/ui/conversation_details.vala src/ui/conversation_details.vala

View file

@ -39,6 +39,7 @@ sources = files(
'src/ui/chat_input/view.vala', 'src/ui/chat_input/view.vala',
'src/ui/contact_details/permissions_provider.vala', 'src/ui/contact_details/permissions_provider.vala',
'src/ui/contact_details/settings_provider.vala', 'src/ui/contact_details/settings_provider.vala',
'src/ui/contact_details/history_provider.vala',
'src/ui/conversation_content_view/call_widget.vala', 'src/ui/conversation_content_view/call_widget.vala',
'src/ui/conversation_content_view/chat_state_populator.vala', 'src/ui/conversation_content_view/chat_state_populator.vala',
'src/ui/conversation_content_view/content_populator.vala', 'src/ui/conversation_content_view/content_populator.vala',

View file

@ -0,0 +1,52 @@
using Gee;
using Gtk;
using Dino.Entities;
using Xmpp;
namespace Dino.Ui.ContactDetails {
public class HistoryProvider : Plugins.ContactDetailsProvider, Object {
public string id { get { return "history_settings"; } }
private StreamInteractor stream_interactor;
private HashMap<Account, HashMap<Jid, Cancellable>> sync_cancellables = new HashMap<Account, HashMap<Jid, Cancellable>>(Account.hash_func, Account.equals_func);
public HistoryProvider(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
}
public void populate(Conversation conversation, Plugins.ContactDetails contact_details, Plugins.WidgetType type) {
if (type != Plugins.WidgetType.GTK4) return;
EntityInfo entity_info = stream_interactor.get_module(EntityInfo.IDENTITY);
string RESYNC_LABEL = _("Resync");
string RESYNC_DESC_LABEL = _("Fetch a complete MAM history for this chat");
entity_info.has_feature.begin(conversation.account, conversation.counterpart, Xmpp.MessageArchiveManagement.NS_URI, (_, res) => {
bool can_do_mam = entity_info.has_feature.end(res);
if (can_do_mam) {
Button resync_button = new Button.with_label(RESYNC_LABEL);
contact_details.add("Permissions", RESYNC_DESC_LABEL, "", resync_button);
resync_button.clicked.connect(() => {
if (!sync_cancellables.has_key(conversation.account)) {
sync_cancellables[conversation.account] = new HashMap<Jid, Cancellable>();
}
if (!sync_cancellables[conversation.account].has_key(conversation.counterpart.bare_jid)) {
sync_cancellables[conversation.account][conversation.counterpart.bare_jid] = new Cancellable();
var history_sync = stream_interactor.get_module(MessageProcessor.IDENTITY).history_sync;
history_sync.fetch_history.begin(conversation.account, conversation.counterpart.bare_jid, sync_cancellables[conversation.account][conversation.counterpart.bare_jid], (_, res) => {
history_sync.fetch_everything.end(res);
sync_cancellables[conversation.account].unset(conversation.counterpart.bare_jid);
});
}
});
}
});
}
}
}

View file

@ -152,6 +152,7 @@ namespace Dino.Ui.ConversationDetails {
Application app = GLib.Application.get_default() as Application; Application app = GLib.Application.get_default() as Application;
app.plugin_registry.register_contact_details_entry(new ContactDetails.SettingsProvider(stream_interactor)); app.plugin_registry.register_contact_details_entry(new ContactDetails.SettingsProvider(stream_interactor));
app.plugin_registry.register_contact_details_entry(new ContactDetails.PermissionsProvider(stream_interactor)); app.plugin_registry.register_contact_details_entry(new ContactDetails.PermissionsProvider(stream_interactor));
app.plugin_registry.register_contact_details_entry(new ContactDetails.HistoryProvider(stream_interactor));
foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) { foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) {
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4); provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4);