From dcd14071091757d712c0d5a734a1a833c648f3af Mon Sep 17 00:00:00 2001 From: JC Brand Date: Wed, 13 Jan 2021 10:42:22 +0100 Subject: [PATCH] New config setting mam_request_all_pages --- CHANGES.md | 1 + docs/source/configuration.rst | 24 +++++++++++++++++++ src/headless/plugins/mam/index.js | 1 + src/headless/plugins/mam/utils.js | 38 +++++++++++++++++-------------- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ac957ed63..9ca89baf9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ - File structure reordering: All plugins are now in `./plugins` folders. - New configuration setting: [show_tab_notifications](https://conversejs.org/docs/html/configuration.html#show-tab-notifications) - New configuration setting: [muc_clear_messages_on_leave](https://conversejs.org/docs/html/configuration.html#muc-clear-messages-on-leave) +- #1823: New config options [mam_request_all_pages](https://conversejs.org/docs/html/configuration.html#mam-request-all-pages) - Use the MUC stanza id when sending XEP-0333 markers ### Breaking Changes diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 785bc513a..899be2746 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -1071,6 +1071,30 @@ VCard is taken, and if that is not set but `muc_nickname_from_jid`_ is set to If no nickame value is found, then an error will be raised. +mam_request_all_pages +--------------------- + +* Default: ``true`` + +When requesting messages from the archive, Converse will ask only for messages +newer than the most recent cached message. + +When there are many archived messages since that one, the returned results will +be broken up in to pages, set by `archived_messages_page_size`_. + +By default Converse will request all the pages until all messages have been +fetched, however for large archives this can slow things down dramatically. + +This setting turns the paging off, and Converse will only fetch the latest +page. + +.. note:: + + If paging is turned off, there will appear gaps in the message history. + Converse currently doesn't yet have a way to inform the user of these gaps or + to let them be filled. + + muc_hats -------- diff --git a/src/headless/plugins/mam/index.js b/src/headless/plugins/mam/index.js index 5964a4cbb..d891999c6 100644 --- a/src/headless/plugins/mam/index.js +++ b/src/headless/plugins/mam/index.js @@ -24,6 +24,7 @@ converse.plugins.add('converse-mam', { initialize () { api.settings.extend({ archived_messages_page_size: '50', + mam_request_all_pages: true, message_archiving: undefined, // Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs) message_archiving_timeout: 20000 // Time (in milliseconds) to wait before aborting MAM request }); diff --git a/src/headless/plugins/mam/utils.js b/src/headless/plugins/mam/utils.js index 4ddd9b27e..f0dd80c53 100644 --- a/src/headless/plugins/mam/utils.js +++ b/src/headless/plugins/mam/utils.js @@ -73,7 +73,7 @@ export function preMUCJoinMAMFetch (muc) { muc.save({ 'prejoin_mam_fetched': true }); } -export async function handleMAMResult (model, result, query, options, page_direction) { +export async function handleMAMResult (model, result, query, options, should_page) { await api.emojis.initialize(); const is_muc = model.get('type') === _converse.CHATROOMS_TYPE; result.messages = result.messages.map(s => @@ -91,7 +91,7 @@ export async function handleMAMResult (model, result, query, options, page_direc result.messages.forEach(m => model.queueMessage(m)); if (result.error) { const event_id = (result.error.retry_event_id = u.getUniqueId()); - api.listen.once(event_id, () => fetchArchivedMessages(model, options, page_direction)); + api.listen.once(event_id, () => fetchArchivedMessages(model, options, should_page)); model.createMessageFromError(result.error); } } @@ -112,10 +112,10 @@ export async function handleMAMResult (model, result, query, options, page_direc * @param { string } [options.with] - The JID of the entity with * which messages were exchanged. * @param { boolean } [options.groupchat] - True if archive in groupchat. - * @param { ('forwards'|'backwards')} [page_direction] - Determines whether this function should + * @param { ('forwards'|'backwards'|null)} [should_page=null] - Determines whether this function should * recursively page through the entire result set if a limited number of results were returned. */ -export async function fetchArchivedMessages (model, options = {}, page_direction) { +export async function fetchArchivedMessages (model, options = {}, should_page=null) { if (model.disable_mam) { return; } @@ -135,19 +135,21 @@ export async function fetchArchivedMessages (model, options = {}, page_direction ); const result = await api.archive.query(query); - await handleMAMResult(model, result, query, options, page_direction); + await handleMAMResult(model, result, query, options, should_page); - if (page_direction && result.rsm && !result.complete) { - if (page_direction === 'forwards') { - options = result.rsm.next(max, options.before).query; - } else if (page_direction === 'backwards') { - options = result.rsm.previous(max, options.after).query; + if (result.rsm && !result.complete) { + if (should_page) { + if (should_page === 'forwards') { + options = result.rsm.next(max, options.before).query; + } else if (should_page === 'backwards') { + options = result.rsm.previous(max, options.after).query; + } + return fetchArchivedMessages(model, options, should_page); + } else { + // TODO: Add a special kind of message which will + // render as a link to fetch further messages, either + // to fetch older messages or to fill in a gap. } - return fetchArchivedMessages(model, options, page_direction); - } else { - // TODO: Add a special kind of message which will - // render as a link to fetch further messages, either - // to fetch older messages or to fill in a gap. } } @@ -159,16 +161,18 @@ export function fetchNewestMessages (model) { if (model.disable_mam) { return; } + const most_recent_msg = model.getMostRecentMessage(); // if clear_messages_on_reconnection is true, than any recent messages // must have been received *after* connection and we instead must query // for earlier messages if (most_recent_msg && !api.settings.get('clear_messages_on_reconnection')) { + const should_page = api.settings.get('mam_request_all_pages'); const stanza_id = most_recent_msg.get(`stanza_id ${model.get('jid')}`); if (stanza_id) { - fetchArchivedMessages(model, { 'after': stanza_id }, 'forwards'); + fetchArchivedMessages(model, { 'after': stanza_id }, should_page ? 'forwards' : null); } else { - fetchArchivedMessages(model, { 'start': most_recent_msg.get('time') }, 'forwards'); + fetchArchivedMessages(model, { 'start': most_recent_msg.get('time') }, should_page ? 'forwards' : null); } } else { fetchArchivedMessages(model, { 'before': '' });