This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/initializers/message-bus.js
Sam Saffron bed3f7f69a
DEV: long poll for 20 extra minutes when user stops interacting
We have no way of detecting if a browser window is behind another window
or off screen on a virtual desktop.

In some cases we may want events to be delivered quicker to the browser.
Specifically a user may still have a window in view but is not interacting.

This gives users 20 minutes of extra "long polling time" prior to shifting
to short polling.
2020-03-27 10:14:13 +11:00

95 lines
2.8 KiB
JavaScript

// Initialize the message bus to receive messages.
import userPresent from "discourse/lib/user-presence";
import { handleLogoff } from "discourse/lib/ajax";
const LONG_POLL_AFTER_UNSEEN_TIME = 1200000; // 20 minutes
function ajax(opts) {
if (opts.complete) {
const oldComplete = opts.complete;
opts.complete = function(xhr, stat) {
handleLogoff(xhr);
oldComplete(xhr, stat);
};
} else {
opts.complete = handleLogoff;
}
return $.ajax(opts);
}
export default {
name: "message-bus",
after: "inject-objects",
initialize(container) {
// We don't use the message bus in testing
if (Discourse.testing) {
return;
}
const messageBus = container.lookup("message-bus:main"),
user = container.lookup("current-user:main"),
siteSettings = container.lookup("site-settings:main");
messageBus.alwaysLongPoll = Discourse.Environment === "development";
messageBus.shouldLongPollCallback = () =>
userPresent(LONG_POLL_AFTER_UNSEEN_TIME);
// we do not want to start anything till document is complete
messageBus.stop();
if (siteSettings.login_required && !user) {
// Endpoint is not available in this case, so don't try
return;
}
// jQuery ready is called on "interactive" we want "complete"
// Possibly change to document.addEventListener('readystatechange',...
// but would only stop a handful of interval, message bus being delayed by
// 500ms on load is fine. stuff that needs to catch up correctly should
// pass in a position
const interval = setInterval(() => {
if (document.readyState === "complete") {
clearInterval(interval);
messageBus.start();
}
}, 500);
messageBus.callbackInterval = siteSettings.anon_polling_interval;
messageBus.backgroundCallbackInterval =
siteSettings.background_polling_interval;
messageBus.baseUrl =
siteSettings.long_polling_base_url.replace(/\/$/, "") + "/";
if (messageBus.baseUrl !== "/") {
// zepto compatible, 1 param only
messageBus.ajax = function(opts) {
opts.headers = opts.headers || {};
opts.headers["X-Shared-Session-Key"] = $(
"meta[name=shared_session_key]"
).attr("content");
if (userPresent()) {
opts.headers["Discourse-Present"] = "true";
}
return ajax(opts);
};
} else {
messageBus.ajax = function(opts) {
opts.headers = opts.headers || {};
if (userPresent()) {
opts.headers["Discourse-Present"] = "true";
}
return ajax(opts);
};
messageBus.baseUrl = Discourse.getURL("/");
}
if (user) {
messageBus.callbackInterval = siteSettings.polling_interval;
messageBus.enableLongPolling = true;
}
}
};