mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 18:24:52 -06:00
DEV: Use online/offline window events to track network connectivity (#22243)
This commit is contained in:
parent
dccdbd52a3
commit
fcaa9757f3
@ -3,10 +3,10 @@ import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class OfflineIndicator extends Component {
|
||||
@service messageBusConnectivity;
|
||||
@service networkConnectivity;
|
||||
|
||||
get showing() {
|
||||
return !this.messageBusConnectivity.connected;
|
||||
return !this.networkConnectivity.connected;
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -6,16 +6,12 @@ import userPresent, { onPresenceChange } from "discourse/lib/user-presence";
|
||||
|
||||
const LONG_POLL_AFTER_UNSEEN_TIME = 1200000; // 20 minutes
|
||||
|
||||
function ajax(opts, messageBusConnectivity, appState) {
|
||||
function ajax(opts) {
|
||||
if (opts.complete) {
|
||||
const oldComplete = opts.complete;
|
||||
opts.complete = function (xhr, stat) {
|
||||
handleLogoff(xhr);
|
||||
oldComplete(xhr, stat);
|
||||
|
||||
messageBusConnectivity.setConnectivity(
|
||||
xhr.readyState === 4 || stat === "abort" || appState.background
|
||||
);
|
||||
};
|
||||
} else {
|
||||
opts.complete = handleLogoff;
|
||||
@ -35,9 +31,7 @@ export default {
|
||||
|
||||
const messageBus = owner.lookup("service:message-bus"),
|
||||
user = owner.lookup("service:current-user"),
|
||||
siteSettings = owner.lookup("service:site-settings"),
|
||||
appState = owner.lookup("service:app-state"),
|
||||
messageBusConnectivity = owner.lookup("service:message-bus-connectivity");
|
||||
siteSettings = owner.lookup("service:site-settings");
|
||||
|
||||
messageBus.alwaysLongPoll = !isProduction();
|
||||
messageBus.shouldLongPollCallback = () =>
|
||||
@ -92,7 +86,7 @@ export default {
|
||||
if (userPresent()) {
|
||||
opts.headers["Discourse-Present"] = "true";
|
||||
}
|
||||
return ajax(opts, messageBusConnectivity, appState);
|
||||
return ajax(opts);
|
||||
};
|
||||
} else {
|
||||
messageBus.ajax = function (opts) {
|
||||
@ -100,7 +94,7 @@ export default {
|
||||
if (userPresent()) {
|
||||
opts.headers["Discourse-Present"] = "true";
|
||||
}
|
||||
return ajax(opts, messageBusConnectivity, appState);
|
||||
return ajax(opts);
|
||||
};
|
||||
|
||||
messageBus.baseUrl = getURL("/");
|
||||
|
@ -1,28 +0,0 @@
|
||||
import Service, { inject as service } from "@ember/service";
|
||||
|
||||
export default class AppState extends Service {
|
||||
@service capabilities;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
if (this.capabilities.isAppWebview) {
|
||||
window.addEventListener("AppStateChange", (event) => {
|
||||
// Possible states: "active", "inactive", and "background"
|
||||
this._state = event.detail?.newAppState;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get active() {
|
||||
return this._state === "active";
|
||||
}
|
||||
|
||||
get inactive() {
|
||||
return this._state === "inactive";
|
||||
}
|
||||
|
||||
get background() {
|
||||
return this._state === "background";
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
import Service from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
const CONNECTIVITY_ERROR_CLASS = "network-disconnected";
|
||||
|
||||
export default class NetworkConnectivity extends Service {
|
||||
@tracked connected = true;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.setConnectivity(navigator.onLine);
|
||||
|
||||
window.addEventListener("offline", () => {
|
||||
this.handleConnectivityChangeEvent(false);
|
||||
});
|
||||
|
||||
window.addEventListener("online", () => {
|
||||
this.handleConnectivityChangeEvent(true);
|
||||
});
|
||||
}
|
||||
|
||||
handleConnectivityChangeEvent(connected) {
|
||||
if (connected) {
|
||||
// Make a super cheap request to the server. If we get a response, we are connected!
|
||||
return ajax("/srv/status", { dataType: "text" })
|
||||
.then((response) => {
|
||||
this.setConnectivity(response === "ok");
|
||||
})
|
||||
.catch(() => {
|
||||
this.setConnectivity(false);
|
||||
});
|
||||
} else {
|
||||
this.setConnectivity(false);
|
||||
}
|
||||
}
|
||||
|
||||
setConnectivity(connected) {
|
||||
this.connected = connected;
|
||||
|
||||
document.documentElement.classList.toggle(
|
||||
CONNECTIVITY_ERROR_CLASS,
|
||||
!connected
|
||||
);
|
||||
}
|
||||
}
|
26
spec/system/network_disconnected_spec.rb
Normal file
26
spec/system/network_disconnected_spec.rb
Normal file
@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Network Disconnected", type: :system do
|
||||
def with_network_disconnected
|
||||
page.driver.browser.network_conditions = { offline: true }
|
||||
yield
|
||||
page.driver.browser.network_conditions = { offline: false }
|
||||
end
|
||||
|
||||
it "NetworkConnectivity service adds class to DOM and displays offline indicator" do
|
||||
SiteSetting.enable_offline_indicator = true
|
||||
|
||||
visit("/c")
|
||||
|
||||
expect(page).to have_no_css("html.network-disconnected")
|
||||
expect(page).to have_no_css(".offline-indicator")
|
||||
|
||||
with_network_disconnected do
|
||||
# Message bus connectivity services adds the disconnected class to the DOM
|
||||
expect(page).to have_css("html.network-disconnected")
|
||||
|
||||
# Offline indicator is rendered
|
||||
expect(page).to have_css(".offline-indicator")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user