diff --git a/frontend/src/Components/SignalRConnector.js b/frontend/src/Components/SignalRConnector.js index f22975bae..715ea1755 100644 --- a/frontend/src/Components/SignalRConnector.js +++ b/frontend/src/Components/SignalRConnector.js @@ -120,7 +120,7 @@ class SignalRConnector extends Component { this.connection.on('receiveMessage', this.onReceiveMessage); - this.connection.start().then(this.onConnected); + this.connection.start().then(this.onStart, this.onStartFail); } componentWillUnmount() { @@ -286,7 +286,19 @@ class SignalRConnector extends Component { // // Listeners - onConnected = () => { + onStartFail = (error) => { + console.error('[signalR] failed to connect'); + console.error(error); + + this.props.dispatchSetAppValue({ + isConnected: false, + isReconnecting: false, + isDisconnected: false, + isRestarting: false + }); + } + + onStart = () => { console.debug('[signalR] connected'); this.props.dispatchSetAppValue({ diff --git a/frontend/src/Store/Selectors/createHealthCheckSelector.js b/frontend/src/Store/Selectors/createHealthCheckSelector.js new file mode 100644 index 000000000..682f86288 --- /dev/null +++ b/frontend/src/Store/Selectors/createHealthCheckSelector.js @@ -0,0 +1,24 @@ +import { createSelector } from 'reselect'; + +function createHealthCheckSelector() { + return createSelector( + (state) => state.system.health, + (state) => state.app, + (health, app) => { + const items = [...health.items]; + + if (!app.isConnected) { + items.push({ + source: 'UI', + type: 'warning', + message: 'Could not connect to SignalR, UI won\'t update', + wikiUrl: 'https://github.com/Lidarr/Lidarr/wiki/Health-Checks#could-not-connect-to-signalr' + }); + } + + return items; + } + ); +} + +export default createHealthCheckSelector; diff --git a/frontend/src/System/Status/Health/HealthConnector.js b/frontend/src/System/Status/Health/HealthConnector.js index b1339a634..dd13b0a9c 100644 --- a/frontend/src/System/Status/Health/HealthConnector.js +++ b/frontend/src/System/Status/Health/HealthConnector.js @@ -13,11 +13,10 @@ function createMapStateToProps() { (state) => state.system.health, (state) => state.settings.downloadClients.isTestingAll, (state) => state.settings.indexers.isTestingAll, - (health, isTestingAllDownloadClients, isTestingAllIndexers) => { + (items, health, isTestingAllDownloadClients, isTestingAllIndexers) => { const { isFetching, - isPopulated, - items + isPopulated } = health; return { diff --git a/frontend/src/System/Status/Health/HealthStatusConnector.js b/frontend/src/System/Status/Health/HealthStatusConnector.js index 24de5c2ed..bbc6175e1 100644 --- a/frontend/src/System/Status/Health/HealthStatusConnector.js +++ b/frontend/src/System/Status/Health/HealthStatusConnector.js @@ -10,13 +10,14 @@ function createMapStateToProps() { return createSelector( createHealthCheckSelector(), (state) => state.app, + createHealthCheckSelector(), (state) => state.system.health, - (app, health) => { - const count = health.items.length; + (app, items, health) => { + const count = items.length; let errors = false; let warnings = false; - health.items.forEach((item) => { + items.forEach((item) => { if (item.type === 'error') { errors = true; }