From 678a56db08c09d2043b832bfa428935da6e2a2e0 Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Wed, 24 May 2017 15:41:43 +0200 Subject: [PATCH] Do not reload all projector elements on every autoupdate (fixes #3259). --- CHANGELOG | 3 ++ openslides/core/static/js/core/projector.js | 37 ++++++++++++++++++- .../static/js/mediafiles/projector.js | 27 +++++++++++++- .../templates/mediafiles/slide_mediafile.html | 4 +- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ff35a9fa6..1e1a341e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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. diff --git a/openslides/core/static/js/core/projector.js b/openslides/core/static/js/core/projector.js index 8a0d89660..9c3380695 100644 --- a/openslides/core/static/js/core/projector.js +++ b/openslides/core/static/js/core/projector.js @@ -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 diff --git a/openslides/mediafiles/static/js/mediafiles/projector.js b/openslides/mediafiles/static/js/mediafiles/projector.js index fb9319bf1..175377ae8 100644 --- a/openslides/mediafiles/static/js/mediafiles/projector.js +++ b/openslides/mediafiles/static/js/mediafiles/projector.js @@ -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) { diff --git a/openslides/mediafiles/static/templates/mediafiles/slide_mediafile.html b/openslides/mediafiles/static/templates/mediafiles/slide_mediafile.html index 19d5c182a..c28f06f48 100644 --- a/openslides/mediafiles/static/templates/mediafiles/slide_mediafile.html +++ b/openslides/mediafiles/static/templates/mediafiles/slide_mediafile.html @@ -1,7 +1,7 @@
-