Do not reload all projector elements on every autoupdate (fixes #3259).

This commit is contained in:
FinnStutzenstein 2017-05-24 15:41:43 +02:00 committed by Emanuel Schütze
parent 5771eab820
commit 678a56db08
4 changed files with 66 additions and 5 deletions

View File

@ -48,6 +48,9 @@ Core:
- Enhanced performance esp. for server restart and first connection of all
clients by refactorting autoupdate, Collection and AccessPermission [#3223].
Mediafiles:
- Fixed reloading of PDF on page change [#3274]
General:
- Switched from npm to Yarn [#3188].
- Several bugfixes and minor improvements.

View File

@ -157,17 +157,50 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
$scope.broadcast = 0;
var setElements = function (projector) {
$scope.elements = [];
// Get all elements, that should be projected.
var newElements = [];
_.forEach(slides.getElements(projector), function (element) {
if (!element.error) {
// Exclude the clock if it should be disabled.
if (Config.get('projector_enable_clock').value || element.name !== 'core/clock') {
$scope.elements.push(element);
newElements.push(element);
}
} else {
console.error("Error for slide " + element.name + ": " + element.error);
}
});
// Now we have to align $scope.elements to newElements:
// We cannot just assign them, because the ng-repeat would reload every
// element. This should be prevented (see #3259). To change $scope.elements:
// 1) remove all elements from scope, that are not in newElements (compared by the uuid)
// 2) Every new element in newElements, that is not in $scope.elements, get inserted there.
// 3) If there is the same element in newElements and $scope.elements every changed property
// is copied from the new element to the scope element.
$scope.elements = _.filter($scope.elements, function (element) {
return _.some(newElements, function (newElement) {
return element.uuid === newElement.uuid;
});
});
_.forEach(newElements, function (newElement) {
var matchingElement = _.find($scope.elements, function (element) {
return element.uuid === newElement.uuid;
});
if (matchingElement) {
// copy all changed properties.
_.forEach(newElement, function (value, key) {
if (newElement.hasOwnProperty(key) && !key.startsWith('$')) {
if (typeof matchingElement[key] === 'undefined' || matchingElement[key] !== value) {
matchingElement[key] = value;
}
}
});
} else {
$scope.elements.push(newElement);
}
});
};
// This function scrolls the projector smoothly. It scrolls is steps calling each

View File

@ -18,11 +18,36 @@ angular.module('OpenSlidesApp.mediafiles.projector', [
.controller('SlideMediafileCtrl', [
'$scope',
'$timeout',
'Mediafile',
function ($scope, Mediafile) {
function ($scope, $timeout, Mediafile) {
// load mediafile object
Mediafile.bindOne($scope.element.id, $scope, 'mediafile');
$scope.showPdf = true;
// Watch for page changes in the projector element. Adjust the page
// in the canvas scope, so the viewer can change the size automatically.
$scope.$watch(function () {
return $scope.element.page;
}, function () {
var canvasScope = angular.element('#pdf-canvas').scope();
if (canvasScope) {
canvasScope.pageNum = $scope.element.page;
}
});
// Watch for scale changes. If the scale is changed, reload the pdf
// viewer by just disable and re-enable it.
$scope.$watch(function () {
return $scope.element.scale;
}, function () {
$scope.showPdf = false;
$timeout(function () {
$scope.showPdf = true;
}, 1);
});
// Allow the elements to render properly
setTimeout(function() {
if ($scope.mediafile) {

View File

@ -1,7 +1,7 @@
<div ng-controller="SlideMediafileCtrl" class="content" ng-class="{'fullscreen': element.fullscreen, 'video-container': element.is_video}">
<!-- PDF -->
<ng-pdf ng-if="mediafile.is_pdf" template-url="/static/templates/mediafiles/slide_mediafile_partial.html"
ng-attr-scale="{{ element.scale }}"
<ng-pdf ng-if="mediafile.is_pdf && showPdf" template-url="/static/templates/mediafiles/slide_mediafile_partial.html"
scale="{{ element.scale }}"
ng-attr-page="{{ element.page }}">
</ng-pdf>