From c286f1b18aba9626f53eab288ae81cf1d44e4e13 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 13 Nov 2013 19:38:30 -0800 Subject: [PATCH] UI will reload on navigation if the backend has been update --- src/UI/Controller.js | 18 ++--- src/UI/LifeCycle.js | 6 ++ src/UI/Shared/NzbDroneController.js | 24 ++++++- src/UI/Shared/SignalRBroadcaster.js | 100 ++++++++++++++++------------ src/UI/System/StatusModel.js | 1 - src/UI/app.js | 3 +- src/UI/vent.js | 3 +- 7 files changed, 98 insertions(+), 57 deletions(-) create mode 100644 src/UI/LifeCycle.js diff --git a/src/UI/Controller.js b/src/UI/Controller.js index fb9010218..bd5be1819 100644 --- a/src/UI/Controller.js +++ b/src/UI/Controller.js @@ -29,49 +29,49 @@ define( addSeries: function (action) { this.setTitle('Add Series'); - AppLayout.mainRegion.show(new AddSeriesLayout({action: action})); + this.showMainRegion(new AddSeriesLayout({action: action})); }, calendar: function () { this.setTitle('Calendar'); - AppLayout.mainRegion.show(new CalendarLayout()); + this.showMainRegion(new CalendarLayout()); }, settings: function (action) { this.setTitle('Settings'); - AppLayout.mainRegion.show(new SettingsLayout({ action: action })); + this.showMainRegion(new SettingsLayout({ action: action })); }, missing: function () { this.setTitle('Missing'); - AppLayout.mainRegion.show(new MissingLayout()); + this.showMainRegion(new MissingLayout()); }, history: function (action) { this.setTitle('History'); - AppLayout.mainRegion.show(new HistoryLayout({ action: action })); + this.showMainRegion(new HistoryLayout({ action: action })); }, rss: function () { this.setTitle('RSS'); - AppLayout.mainRegion.show(new ReleaseLayout()); + this.showMainRegion(new ReleaseLayout()); }, system: function (action) { this.setTitle('System'); - AppLayout.mainRegion.show(new SystemLayout({ action: action })); + this.showMainRegion(new SystemLayout({ action: action })); }, seasonPass: function () { this.setTitle('Season Pass'); - AppLayout.mainRegion.show(new SeasonPassLayout()); + this.showMainRegion(new SeasonPassLayout()); }, update: function () { this.setTitle('Updates'); - AppLayout.mainRegion.show(new UpdateLayout()); + this.showMainRegion(new UpdateLayout()); } }); }); diff --git a/src/UI/LifeCycle.js b/src/UI/LifeCycle.js new file mode 100644 index 000000000..919f27fba --- /dev/null +++ b/src/UI/LifeCycle.js @@ -0,0 +1,6 @@ +'use strict'; +define(function () { + window.onbeforeunload = function () { + window.NzbDrone.unloading = true; + }; +}); diff --git a/src/UI/Shared/NzbDroneController.js b/src/UI/Shared/NzbDroneController.js index f5c0adcf1..0d2383fad 100644 --- a/src/UI/Shared/NzbDroneController.js +++ b/src/UI/Shared/NzbDroneController.js @@ -1,15 +1,20 @@ 'use strict'; define( [ + 'vent', 'AppLayout', 'marionette', 'Shared/NotFoundView' - ], function (AppLayout, Marionette, NotFoundView) { + ], function (vent, AppLayout, Marionette, NotFoundView) { return Marionette.AppRouter.extend({ + initialize: function () { + this.listenTo(vent, vent.Events.ServerUpdated, this._onServerUpdated); + }, + showNotFound: function () { this.setTitle('Not Found'); - AppLayout.mainRegion.show(new NotFoundView(this)); + this.showMainRegion(new NotFoundView(this)); }, setTitle: function (title) { @@ -19,6 +24,21 @@ define( else { document.title = title + ' - NzbDrone'; } + }, + + _onServerUpdated: function () { + this.pendingUpdate = true; + }, + + showMainRegion: function (view) { + if (this.pendingUpdate) { + window.location.reload(); + } + + else { + //AppLayout + AppLayout.mainRegion.show(view); + } } }); }); diff --git a/src/UI/Shared/SignalRBroadcaster.js b/src/UI/Shared/SignalRBroadcaster.js index 7a930a437..a91e08a5c 100644 --- a/src/UI/Shared/SignalRBroadcaster.js +++ b/src/UI/Shared/SignalRBroadcaster.js @@ -4,8 +4,9 @@ define( 'vent', 'jquery', 'Shared/Messenger', + 'System/StatusModel', 'signalR' - ], function (vent, $, Messenger) { + ], function (vent, $, Messenger, StatusModel) { return { appInitializer: function () { @@ -39,48 +40,61 @@ define( vent.trigger('server:' + message.name, message.body); }); -// this.signalRconnection.reconnecting(function() { -// tryingToReconnect = true; -// -// Messenger.show({ -// id : messengerId, -// type : 'info', -// hideAfter : 0, -// message : 'Connection to backend lost, attempting to reconnect' -// }); -// }); -// -// this.signalRconnection.reconnected(function() { -// tryingToReconnect = false; -// -// Messenger.show({ -// id : messengerId, -// type : 'success', -// hideAfter : 5, -// message : 'Connection to backend restored' -// }); -// }); -// -// this.signalRconnection.disconnected(function () { -// if (tryingToReconnect) { -// $('').appendTo(document.body); -// -// Messenger.show({ -// id : messengerId, -// type : 'error', -// hideAfter : 0, -// message : 'Connection to backend lost', -// actions : { -// cancel: { -// label: 'Reload', -// action: function() { -// window.location.reload(); -// } -// } -// } -// }); -// } -// }); + this.signalRconnection.reconnecting(function() { + if (window.NzbDrone.unloading) { + return; + } + + tryingToReconnect = true; + + Messenger.show({ + id : messengerId, + type : 'info', + hideAfter : 0, + message : 'Connection to backend lost, attempting to reconnect' + }); + }); + + this.signalRconnection.reconnected(function() { + tryingToReconnect = false; + + var currentVersion = StatusModel.get('version'); + + var promise = StatusModel.fetch(); + promise.done(function () { + if (StatusModel.get('version') !== currentVersion) { + vent.trigger(vent.Events.ServerUpdated); + } + }); + + Messenger.show({ + id : messengerId, + type : 'success', + hideAfter : 5, + message : 'Connection to backend restored' + }); + }); + + this.signalRconnection.disconnected(function () { + if (tryingToReconnect) { + $('').appendTo(document.body); + + Messenger.show({ + id : messengerId, + type : 'error', + hideAfter : 0, + message : 'Connection to backend lost', + actions : { + cancel: { + label: 'Reload', + action: function() { + window.location.reload(); + } + } + } + }); + } + }); this.signalRconnection.start({ transport: [ diff --git a/src/UI/System/StatusModel.js b/src/UI/System/StatusModel.js index 3210fe3e6..97dc696ca 100644 --- a/src/UI/System/StatusModel.js +++ b/src/UI/System/StatusModel.js @@ -8,7 +8,6 @@ define( url: window.NzbDrone.ApiRoot + '/system/status' }); - var instance = new StatusModel(); instance.fetch(); return instance; diff --git a/src/UI/app.js b/src/UI/app.js index 18e2a9454..d8a60ea7b 100644 --- a/src/UI/app.js +++ b/src/UI/app.js @@ -191,7 +191,8 @@ define( 'Series/SeriesController', 'Router', 'Shared/Modal/Controller', - 'Instrumentation/StringFormat' + 'Instrumentation/StringFormat', + 'LifeCycle' ], function ($, Backbone, Marionette, RouteBinder, SignalRBroadcaster, NavbarView, AppLayout, SeriesController, Router, ModalController) { new SeriesController(); diff --git a/src/UI/vent.js b/src/UI/vent.js index 4170ac72b..7ee771295 100644 --- a/src/UI/vent.js +++ b/src/UI/vent.js @@ -11,7 +11,8 @@ define( SeriesAdded : 'series:added', SeriesDeleted : 'series:deleted', SeasonRenamed : 'season:renamed', - CommandComplete: 'command:complete' + CommandComplete: 'command:complete', + ServerUpdated : 'server:updated' }; vent.Commands = {