gui: Stop log tailing on scroll (#5013)

This commit is contained in:
Audrius Butkevicius 2018-06-18 12:27:54 +01:00 committed by GitHub
parent c2784d76e4
commit b3007c03bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 6 deletions

View File

@ -8,8 +8,8 @@
<div id="log-viewer-log" class="tab-pane in active"> <div id="log-viewer-log" class="tab-pane in active">
<label translate ng-if="logging.logEntries.length == 0">Loading...</label> <label translate ng-if="logging.logEntries.length == 0">Loading...</label>
<textarea ng-focus="logging.paused = true" ng-blur="logging.paused = false" id="logViewerText" class="form-control" rows="20" ng-if="logging.logEntries.length != 0" readonly style="font-family: Consolas; font-size: 11px; overflow: auto;">{{ logging.content() }}</textarea> <textarea id="logViewerText" class="form-control" rows="20" ng-if="logging.logEntries.length != 0" readonly style="font-family: Consolas; font-size: 11px; overflow: auto;">{{ logging.content() }}</textarea>
<p translate class="help-block" ng-style="{'visibility': logging.paused ? 'visible' : 'hidden'}">Log tailing paused. Click here to continue.</p> <p translate class="help-block" ng-style="{'visibility': logging.paused ? 'visible' : 'hidden'}">Log tailing paused. Scroll to bottom continue.</p>
</div> </div>
<div id="log-viewer-facilities" class="tab-pane"> <div id="log-viewer-facilities" class="tab-pane">

View File

@ -1097,8 +1097,14 @@ angular.module('syncthing.core')
show: function() { show: function() {
$scope.logging.refreshFacilities(); $scope.logging.refreshFacilities();
$scope.logging.timer = $timeout($scope.logging.fetch); $scope.logging.timer = $timeout($scope.logging.fetch);
$('#logViewer').modal().on('hidden.bs.modal', function () { var textArea = $('#logViewerText');
textArea.on("scroll", $scope.logging.onScroll);
$('#logViewer').modal().on('shown.bs.modal', function() {
// Scroll to bottom.
textArea.scrollTop(textArea[0].scrollHeight);
}).on('hidden.bs.modal', function () {
$timeout.cancel($scope.logging.timer); $timeout.cancel($scope.logging.timer);
textArea.off("scroll", $scope.logging.onScroll);
$scope.logging.timer = null; $scope.logging.timer = null;
$scope.logging.entries = []; $scope.logging.entries = [];
}); });
@ -1113,6 +1119,14 @@ angular.module('syncthing.core')
.success($scope.logging.refreshFacilities) .success($scope.logging.refreshFacilities)
.error($scope.emitHTTPError); .error($scope.emitHTTPError);
}, },
onScroll: function() {
var textArea = $('#logViewerText');
var scrollTop = textArea.prop('scrollTop');
var scrollHeight = textArea.prop('scrollHeight');
$scope.logging.paused = scrollHeight > (scrollTop + textArea.outerHeight());
// Browser events do not cause redraw, trigger manually.
$scope.$apply();
},
timer: null, timer: null,
entries: [], entries: [],
paused: false, paused: false,
@ -1125,7 +1139,7 @@ angular.module('syncthing.core')
}, },
fetch: function() { fetch: function() {
var textArea = $('#logViewerText'); var textArea = $('#logViewerText');
if (textArea.is(":focus")) { if ($scope.logging.paused) {
if (!$scope.logging.timer) return; if (!$scope.logging.timer) return;
$scope.logging.timer = $timeout($scope.logging.fetch, 500); $scope.logging.timer = $timeout($scope.logging.fetch, 500);
return; return;
@ -1139,11 +1153,14 @@ angular.module('syncthing.core')
$http.get(urlbase + '/system/log' + (last ? '?since=' + encodeURIComponent(last) : '')).success(function (data) { $http.get(urlbase + '/system/log' + (last ? '?since=' + encodeURIComponent(last) : '')).success(function (data) {
if (!$scope.logging.timer) return; if (!$scope.logging.timer) return;
$scope.logging.timer = $timeout($scope.logging.fetch, 2000); $scope.logging.timer = $timeout($scope.logging.fetch, 2000);
if (!textArea.is(":focus")) { if (!$scope.logging.paused) {
if (data.messages) { if (data.messages) {
$scope.logging.entries.push.apply($scope.logging.entries, data.messages); $scope.logging.entries.push.apply($scope.logging.entries, data.messages);
// Wait for the text area to be redrawn, adding new lines, and then scroll to bottom.
$timeout(function() {
textArea.scrollTop(textArea[0].scrollHeight);
});
} }
textArea.scrollTop(textArea[0].scrollHeight);
} }
}); });
} }