diff --git a/Duplicati/Server/webroot/ngax/index.html b/Duplicati/Server/webroot/ngax/index.html index 2df33a9ba..1c7e4f3d8 100644 --- a/Duplicati/Server/webroot/ngax/index.html +++ b/Duplicati/Server/webroot/ngax/index.html @@ -16,7 +16,7 @@ - + @@ -76,9 +76,9 @@ - + -
+
+
+ +
+
+
Connection lost
+
+ The connection to the server is lost, attempting again in {{ state.connectionAttemptTimer + 1000 | timeremaining }} ... +
+
+ Connnecting to server ... +
+ +
+
diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js index 8c0e05e6c..837c33862 100644 --- a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js +++ b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js @@ -2,4 +2,8 @@ backupApp.controller('AppController', function($scope, BrandingService, ServerSt $scope.appName = BrandingService.appName; $scope.state = ServerStatus.watch($scope); $scope.localized = {}; + + $scope.doReconnect = function() { + ServerStatus.reconnect(); + }; }); \ No newline at end of file diff --git a/Duplicati/Server/webroot/ngax/scripts/filters/timeremaining.js b/Duplicati/Server/webroot/ngax/scripts/filters/timeremaining.js index 7dfbfe85e..964a21295 100644 --- a/Duplicati/Server/webroot/ngax/scripts/filters/timeremaining.js +++ b/Duplicati/Server/webroot/ngax/scripts/filters/timeremaining.js @@ -48,6 +48,9 @@ backupApp.filter('timeremaining', function() { r[i] = v; }; + if (r.length == 1) + r.unshift('0'); + return r.join(':'); } }); \ No newline at end of file diff --git a/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js b/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js index 955d5864e..18e20c5fc 100644 --- a/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js +++ b/Duplicati/Server/webroot/ngax/scripts/services/ServerStatus.js @@ -15,6 +15,7 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi connectionState: 'connected', xsfrerror: false, connectionAttemptTimer: 0, + failedConnectionAttempts: 0, lastPgEvent: null }; @@ -143,7 +144,7 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi $rootScope.$broadcast('serverstatechanged'); } - }, 500); + }, 1000); }; var updatepausetimer = null; @@ -188,6 +189,7 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi var url = '/serverstate/?lasteventid=' + parseInt(state.lastEventId) + '&longpoll=' + (state.lastEventId > 0 ? 'true' : 'false') + '&duration=' + parseInt((longpolltime-1000) / 1000) + 's'; AppService.get(url, {timeout: state.lastEventId > 0 ? longpolltime : 5000}).then( function (response) { + var oldEventId = state.lastEventId; var anychanged = notifyIfChanged(response.data, 'LastEventID', 'lastEventId') | notifyIfChanged(response.data, 'LastDataUpdateID', 'lastDataUpdateId') | @@ -196,11 +198,18 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi notifyIfChanged(response.data, 'ProgramState', 'programState') | notifyIfChanged(response.data, 'EstimatedPauseEnd', 'estimatedPauseEnd'); + // Clear error indicators + state.failedConnectionAttempts = 0; + state.xsfrerror = false; if (state.connectionState != 'connected') { state.connectionState = 'connected'; $rootScope.$broadcast('serverstatechanged.connectionState', state.connectionState); anychanged = true; + + // Reload page, server restarted + if (oldEventId > state.lastEventId) + location.reload(true); } anychanged |= pauseTimerUpdater(true); @@ -215,20 +224,28 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi longpoll(); }, - function(respone) { - if (state.connectionState == 'connected') { - // First failure, we ignore - state.connectionState = 'connecting'; + function(response) { + + var oldxsfrstate = state.xsfrerror; + state.failedConnectionAttempts++; + state.xsfrerror = response.statusText.toLowerCase().indexOf('xsrf') >= 0; + + // First failure, we ignore + if (state.connectionState == 'connected' && state.failedConnectionAttempts == 1) { // Try again longpoll(); } else { - // Real failure, start countdown - state.lastEventId = -1; state.connectionState = 'disconnected'; - countdownForForReLongPoll(longpoll); + //If we got a new XSRF token this time, quickly retry + if (state.xsfrerror && !oldxsfrstate) { + longpoll(); + } else { + // Otherwise, start countdown to next try + countdownForForReLongPoll(longpoll); + } } // Notify @@ -238,5 +255,7 @@ backupApp.service('ServerStatus', function($http, $rootScope, $timeout, AppServi ); }; + this.reconnect = longpoll; + longpoll(); }); \ No newline at end of file diff --git a/Duplicati/Server/webroot/ngax/styles/styles2.css b/Duplicati/Server/webroot/ngax/styles/styles2.css index bd2c5b398..4bc91fe1a 100644 --- a/Duplicati/Server/webroot/ngax/styles/styles2.css +++ b/Duplicati/Server/webroot/ngax/styles/styles2.css @@ -444,3 +444,59 @@ ul.tabs > li.active, ul.tabs > li.active > a { background-color: lightgray; color: black; } + +div.connection-lost, div.blocker { + position: absolute; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + margin: auto; +} + +div.connection-lost { + width: 250px; + height: 200px; +} + +div.blocker { + background-color: #000000; + opacity: 0.65; +} + +.connection-lost div.info { + display: inline-block; +} + +.connection-lost div.title { + border: 1px solid #65b1dd; + background-color: #65b1dd; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + padding: 10px; + padding-left: 20px; + padding-right: 20px; + font-weight: bold; + color: lightgray; + width: 100%; + text-align: center; +} + +.connection-lost div.content { + background-color: white; + border: 1px solid white; + padding: 20px; + width: 100%; + min-width: 250px; +} + +.connection-lost div.content.buttons { + padding-bottom: 45px; + border-top-left-radius: 0px; + border-top-right-radius: 0px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + diff --git a/Duplicati/Server/webroot/ngax/templates/home.html b/Duplicati/Server/webroot/ngax/templates/home.html index 807294a5b..d0a0c9e93 100644 --- a/Duplicati/Server/webroot/ngax/templates/home.html +++ b/Duplicati/Server/webroot/ngax/templates/home.html @@ -34,7 +34,7 @@
-

Scheduled backups:

+

Stored backup jobs: