From b1da6708986db4f12da9e14bd261cad6d1e16678 Mon Sep 17 00:00:00 2001 From: Mark VanLandingham Date: Mon, 1 May 2023 12:41:30 -0500 Subject: [PATCH] FEATURE: Offline indicator controlled by message-bus connectivity (#21324) --- .../app/components/offline-indicator.hbs | 10 +++++++ .../app/components/offline-indicator.js | 16 +++++++++++ .../discourse/app/initializers/message-bus.js | 24 +++++++---------- .../app/services/message-bus-connectivity.js | 16 +++++++++++ .../discourse/app/templates/application.hbs | 1 + .../stylesheets/common/components/_index.scss | 1 + .../common/components/offline-indicator.scss | 10 +++++++ config/locales/client.en.yml | 4 +++ spec/system/network_disconnected_spec.rb | 27 +++++++++++++++++++ 9 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 app/assets/javascripts/discourse/app/components/offline-indicator.hbs create mode 100644 app/assets/javascripts/discourse/app/components/offline-indicator.js create mode 100644 app/assets/javascripts/discourse/app/services/message-bus-connectivity.js create mode 100644 app/assets/stylesheets/common/components/offline-indicator.scss create mode 100644 spec/system/network_disconnected_spec.rb diff --git a/app/assets/javascripts/discourse/app/components/offline-indicator.hbs b/app/assets/javascripts/discourse/app/components/offline-indicator.hbs new file mode 100644 index 00000000000..ee53efd7aeb --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/offline-indicator.hbs @@ -0,0 +1,10 @@ +{{#if this.showing}} +
+ {{i18n "offline_indicator.no_internet"}} + +
+{{/if}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/offline-indicator.js b/app/assets/javascripts/discourse/app/components/offline-indicator.js new file mode 100644 index 00000000000..3a6edebe7a3 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/offline-indicator.js @@ -0,0 +1,16 @@ +import Component from "@glimmer/component"; +import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; + +export default class OfflineIndicator extends Component { + @service messageBusConnectivity; + + get showing() { + return !this.messageBusConnectivity.connected; + } + + @action + refresh() { + window.location.reload(true); + } +} diff --git a/app/assets/javascripts/discourse/app/initializers/message-bus.js b/app/assets/javascripts/discourse/app/initializers/message-bus.js index 8eb790749df..0667340c296 100644 --- a/app/assets/javascripts/discourse/app/initializers/message-bus.js +++ b/app/assets/javascripts/discourse/app/initializers/message-bus.js @@ -5,23 +5,16 @@ import { handleLogoff } from "discourse/lib/ajax"; import userPresent, { onPresenceChange } from "discourse/lib/user-presence"; const LONG_POLL_AFTER_UNSEEN_TIME = 1200000; // 20 minutes -const CONNECTIVITY_ERROR_CLASS = "message-bus-offline"; -function updateConnectivityIndicator(stat) { - if (stat === "error") { - document.documentElement.classList.add(CONNECTIVITY_ERROR_CLASS); - } else { - document.documentElement.classList.remove(CONNECTIVITY_ERROR_CLASS); - } -} - -function ajax(opts) { +function ajax(opts, messageBusConnectivity) { if (opts.complete) { const oldComplete = opts.complete; opts.complete = function (xhr, stat) { handleLogoff(xhr); oldComplete(xhr, stat); - updateConnectivityIndicator(stat); + messageBusConnectivity.setConnectivity( + stat === "abort" || xhr.readyState === 4 + ); }; } else { opts.complete = handleLogoff; @@ -42,7 +35,10 @@ export default { const messageBus = container.lookup("service:message-bus"), user = container.lookup("service:current-user"), - siteSettings = container.lookup("service:site-settings"); + siteSettings = container.lookup("service:site-settings"), + messageBusConnectivity = container.lookup( + "service:message-bus-connectivity" + ); messageBus.alwaysLongPoll = !isProduction(); messageBus.shouldLongPollCallback = () => @@ -97,7 +93,7 @@ export default { if (userPresent()) { opts.headers["Discourse-Present"] = "true"; } - return ajax(opts); + return ajax(opts, messageBusConnectivity); }; } else { messageBus.ajax = function (opts) { @@ -105,7 +101,7 @@ export default { if (userPresent()) { opts.headers["Discourse-Present"] = "true"; } - return ajax(opts); + return ajax(opts, messageBusConnectivity); }; messageBus.baseUrl = getURL("/"); diff --git a/app/assets/javascripts/discourse/app/services/message-bus-connectivity.js b/app/assets/javascripts/discourse/app/services/message-bus-connectivity.js new file mode 100644 index 00000000000..876ecb34e99 --- /dev/null +++ b/app/assets/javascripts/discourse/app/services/message-bus-connectivity.js @@ -0,0 +1,16 @@ +import Service from "@ember/service"; +import { tracked } from "@glimmer/tracking"; + +const CONNECTIVITY_ERROR_CLASS = "message-bus-offline"; + +export default class MessageBusConnectivity extends Service { + @tracked connected = true; + + setConnectivity(connected) { + this.connected = connected; + document.documentElement.classList.toggle( + CONNECTIVITY_ERROR_CLASS, + !connected + ); + } +} diff --git a/app/assets/javascripts/discourse/app/templates/application.hbs b/app/assets/javascripts/discourse/app/templates/application.hbs index 2c6d11c0e4a..623f253f224 100644 --- a/app/assets/javascripts/discourse/app/templates/application.hbs +++ b/app/assets/javascripts/discourse/app/templates/application.hbs @@ -24,6 +24,7 @@ {{/if}} +