From cac14449ddd52183d12fc4357eb3d1f05e11fba1 Mon Sep 17 00:00:00 2001 From: Reaby Date: Sun, 14 Jul 2019 21:41:19 +0300 Subject: [PATCH] implement announce to all displays, add favicon, enhance caching and reduce requests, better iframe handling... --- config-default.js | 3 - locales/en/translation.json | 3 +- locales/fi/translation.json | 3 +- modules/admin.js | 19 +++-- modules/display.js | 8 +++ public/favicon.ico | Bin 0 -> 318 bytes public/js/display.js | 95 +++++++++++++----------- public/js/displayLite.js | 139 ++++++++++++++++++------------------ public/js/edit.js | 51 ++++++------- public/js/flux.js | 40 +++++------ routes/index.js | 11 ++- views/admin/editSlide.twig | 5 +- views/admin/overview.twig | 86 +++++++++++++++++++++- views/liteDisplay.twig | 14 ++-- 14 files changed, 298 insertions(+), 179 deletions(-) create mode 100644 public/favicon.ico diff --git a/config-default.js b/config-default.js index 1079d91..babaa02 100644 --- a/config-default.js +++ b/config-default.js @@ -58,17 +58,14 @@ module.exports = { "displays": [ { - "id": 1, "name": "Big Screen", "bundle": "default" }, { - "id": 2, "name": "Secondary Screen", "bundle": "set1" }, { - "id": 3, "name": "Kiosk", "bundle": "default" } diff --git a/locales/en/translation.json b/locales/en/translation.json index c21026e..186d80b 100644 --- a/locales/en/translation.json +++ b/locales/en/translation.json @@ -23,7 +23,8 @@ "createNew": "Create New", "createNewSlide": "Create New Slide", "addWebPage": "Add Web page", - "announce": "Fast Announce" + "announce": "Fast Announce", + "announceAll": "Global Announce" }, "navs": { "bundle": "bundle", diff --git a/locales/fi/translation.json b/locales/fi/translation.json index e9d98e8..4efe47f 100644 --- a/locales/fi/translation.json +++ b/locales/fi/translation.json @@ -23,7 +23,8 @@ "createNew": "Luo Uusi", "createNewSlide": "Luo uusi dia", "addWebPage": "Lisää Web-sivu", - "announce": "Ilmoita" + "announce": "Ilmoita", + "announceAll": "Ilmoita Kaikille" }, "navs": { "bundle": "DiaPaketti", diff --git a/modules/admin.js b/modules/admin.js index 2bbcb8a..be902e3 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -206,10 +206,16 @@ class admin { // override socket.on('admin.override', function (data) { try { - let view = getView(parseInt(data.displayId)); - view.overrideSlide(data.json, data.png, data.duration); - - view.displayCurrentSlide(); + if (data.displayId === null) { + if (data.duration == null || data.duration <= 5) { + data.duration = 45; + } + dispatcher.emit("all.override", data); + } else { + let view = getView(parseInt(data.displayId)); + view.overrideSlide(data.json, data.png, data.duration); + view.displayCurrentSlide(); + } } catch (err) { cli.error("error, admin.override", err); } @@ -223,9 +229,8 @@ class admin { }); socket.on('admin.dashboard.sync', function (data) { - cli.error("admin.dashboard.sync is deprecated!"); - // syncDashboard(socket, 0); - // updateDashboard(socket, data.displayId); + syncDashboard(socket, data.displayId); + updateDashboard(socket, data.displayId); }); socket.on('admin.setDisplay', function (data) { diff --git a/modules/display.js b/modules/display.js index 5c526b8..b97cd5e 100644 --- a/modules/display.js +++ b/modules/display.js @@ -65,6 +65,12 @@ class display { * @listens event:announce * */ + + dispatcher.on("all.override", function (data) { + self.overrideSlide(data.json, data.png, data.duration); + self.displayCurrentSlide(); + }); + dispatcher.on("announce", function (obj) { // if global announce, ie screens is null if (obj.screens == null) { @@ -109,6 +115,7 @@ class display { init(meta) { + this.io.emit("callback.reload"); this.changeBundle(meta.bundle); } @@ -127,6 +134,7 @@ class display { this.serverOptions.currentId = bundle.enabledSlides.indexOf(this.serverOptions.currentFile); this.serverOptions.transition = bundle.getBundleData().transition; this.serverOptions.loop = true; + this.io.emit("callbackLoad", this.getSlideData()); this.mainLoop(); } diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b481474a8a1efa48372a0a2ee9cdcfc5256d551b GIT binary patch literal 318 zcmb`BF%Ez*2t^->2cV0qj=iN09@N?Q{W}rLjtWMM;_Ms`! htFWW8FD|W(rRB);#!p^*%k!^ha4yNU!5eBm?%vrS8 1) { @@ -446,12 +451,22 @@ function getWebLayer(offset) { return "webLayer" + (layer + offset) % 2; } -function clearIFrame(elementId) { - var frame = document.getElementById(elementId); - - if (frame.contentWindow.location.href !== document.location.origin + "/empty") { - frame.contentWindow.location.href = "/empty"; +function clearIFrame(id) { + if ($('#' + id).attr('src') !== "/empty") { + $('#' + id).attr('src', '/empty'); } } +function getDataUri(url, imageId, callback) { + var image = new Image(); + image.onload = function () { + var canvas = document.createElement('canvas'); + canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size + canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size + + canvas.getContext('2d').drawImage(this, 0, 0); + callback(imageId, canvas.toDataURL('image/png'), this); + }; + image.src = url; +} diff --git a/public/js/displayLite.js b/public/js/displayLite.js index 580c6fa..def0551 100644 --- a/public/js/displayLite.js +++ b/public/js/displayLite.js @@ -26,6 +26,67 @@ $(function () { fixImageSizes(); displayTime(); setInterval(displayTime, 1000); + +// socketio callbacks + /** when connected **/ + socket.on('connect', function () { + socket.emit("sync"); + }); + + socket.on('error', function () { + $("#networkstatus").css("opacity", 1); + }); + + socket.on('disconnect', function () { + $("#networkstatus").css("opacity", 1); + }); + + socket.on('pong', function () { + updateTimeout(); + }); + + socket.on('callback.blackout', function (data) { + serverOptions = data.serverOptions; + checkBlackout(); + }); + + socket.on('callback.time', function (data) { + serverOptions.displayTime = data; + checkTimeDisplay(); + }); + + + /** callback Load **/ + socket.on('callbackLoad', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkBlackout(); + nextSlide(data); + }); + + + /** callback Update **/ + socket.on('callback.update', function (data) { + serverOptions = data.serverOptions; + bundleData = data.bundleData; + checkBlackout(); + nextSlide(data); + }); + + socket.on('callback.reload', function () { + location.reload(true); + }); + + socket.on('callback.announce', function (data) { + checkBlackout(); + nextSlide(data); + }); + + socket.on('callback.forceSlide', function (data) { + checkBlackout(); + nextSlide(data); + }); + }); $(window).bind("resize", function () { @@ -39,68 +100,6 @@ function getLayer(offset) { } -// socketio callbacks -/** when connected **/ -socket.on('connect', function () { - console.log("connect, calling sync!"); - socket.emit("sync"); -}); - -socket.on('error', function () { - $("#networkstatus").css("opacity", 1); -}); - -socket.on('disconnect', function () { - $("#networkstatus").css("opacity", 1); -}); - -socket.on('pong', function () { - updateTimeout(); -}); - -socket.on('callback.blackout', function (data) { - serverOptions = data.serverOptions; - checkBlackout(); -}); - -socket.on('callback.time', function (data) { - serverOptions.displayTime = data; - checkTimeDisplay(); -}); - - -/** callback Load **/ -socket.on('callbackLoad', function (data) { - serverOptions = data.serverOptions; - bundleData = data.bundleData; - checkBlackout(); - nextSlide(data); -}); - - -/** callback Update **/ -socket.on('callback.update', function (data) { - serverOptions = data.serverOptions; - bundleData = data.bundleData; - checkBlackout(); - nextSlide(data); -}); - -socket.on('callback.reload', function () { - location.reload(true); -}); - -socket.on('callback.announce', function (data) { - checkBlackout(); - nextSlide(data); -}); - -socket.on('callback.forceSlide', function (data) { - checkBlackout(); - nextSlide(data); -}); - - /** * Displays the local time for bottom of screen * hh:mm @@ -161,9 +160,9 @@ function nextSlide(data) { $("#" + getWebLayer()).addClass("fadeOut").removeClass("fadeIn"); $("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn"); setTimeout(function () { - clearIFrame(getLayer()); - clearIFrame(getLayer(1)); - }, 1000); + clearIFrame(getWebLayer()); + clearIFrame(getWebLayer(1)); + }, 1500); $("#helperLayer").addClass("announce"); try { @@ -307,9 +306,7 @@ function uuidv4() { var weblayer = 0; function displayWebPage(url) { - var ifr = document.getElementById(getWebLayer()); - ifr.contentWindow.location.href = url; - $("#" + getWebLayer()).addClass("fadeIn").removeClass("fadeOut"); + $("#" + getWebLayer()).attr('src', url).addClass("fadeIn").removeClass("fadeOut"); $("#" + getWebLayer(1)).addClass("fadeOut").removeClass("fadeIn"); weblayer++; if (weblayer > 1) { @@ -323,8 +320,8 @@ function getWebLayer(offset) { } function clearIFrame(id) { - var frame = document.getElementById(id), - frameDoc = frame.contentDocument || frame.contentWindow.document; - frameDoc.documentElement.innerHTML = ""; + if ($('#' + id).attr('src') !== "/empty") { + $('#' + id).attr('src', '/empty'); + } } diff --git a/public/js/edit.js b/public/js/edit.js index 8397056..600ee98 100644 --- a/public/js/edit.js +++ b/public/js/edit.js @@ -546,31 +546,34 @@ function removeSelectedObjects() { } -function cueSlide() { - if (displayId !== null) { - if (confirm('Force display of the current slide?')) { - var duration = null; - if ($.isNumeric($("#duration").val())) { - duration = parseFloat($("#duration").val()); - } - - var objects = canvas.getObjects('line'); - for (let i in objects) { - canvas.remove(objects[i]); - } - - let obj = { - json: canvas.toJSON(['id']), - png: canvas.toDataURL('png'), - displayId: displayId, - duration: duration - }; - socket.emit("admin.override", obj); - - drawGrid(); +function cueSlide(id) { + if (id === null) { + var bool = confirm('You are about to display the current slide for ALL DISPLAYS, are you sure?') + if (bool === false) { + return; } - } else { - alert("Can't find display to announce"); + } + + if (confirm('Force display of the current slide?') && bool) { + var duration = null; + if ($.isNumeric($("#duration").val())) { + duration = parseFloat($("#duration").val()); + } + + var objects = canvas.getObjects('line'); + for (let i in objects) { + canvas.remove(objects[i]); + } + + let obj = { + json: canvas.toJSON(['id']), + png: canvas.toDataURL('png'), + displayId: id, + duration: duration + }; + socket.emit("admin.override", obj); + + drawGrid(); } } diff --git a/public/js/flux.js b/public/js/flux.js index 4d4a0df..12d451e 100644 --- a/public/js/flux.js +++ b/public/js/flux.js @@ -72,6 +72,7 @@ window.flux = { this.options.transitions = newTrans; this.images = []; + this.imageData = []; this.imageLoadedCount = 0; this.currentImageIndex = 0; this.nextImageIndex = 1; @@ -229,20 +230,18 @@ window.flux = { this.setNextIndex(index); // Temporarily stop the transition interval - //clearInterval(this.interval); - //this.interval = null; + // clearInterval(this.interval); + // this.interval = null; this.setupImages(); this.transition(trans, opts); }, showImageById: function (id, trans, opts) { - let i = 0; - for (var img of this.images) { - if (img.id === id) { + for (var i in this.images) { + if (this.images[i].id === id) { this.showImage(i, trans, opts); break; } - i++; } this.clearTempImages(); }, @@ -257,20 +256,21 @@ window.flux = { } }, clearImages: function () { - delete this.images; this.images = []; + this.imageData = []; }, clearTempImages: function () { for (var i in this.images) { if (this.images[i].class === "temp") { this.images.splice(i, 1); + this.imageData.splice(i, 1); } } }, clearImageById: function (id) { for (var i in this.images) { if (this.images[i].id === id) { - + this.imageData.splice(i, 1); this.images.splice(i, 1); } } @@ -400,29 +400,20 @@ window.flux = { this.updateCaption(); }, setupImages: function () { - var img1 = this.getImage(this.currentImageIndex); + + var img1 = this.getImageData(this.currentImageIndex); css1 = { - 'background-image': 'url("' + img1.src + '")', + 'background-image': 'url("' + img1.replace(/(\r\n|\n|\r)/gm, "") + '")', 'z-index': 101, 'cursor': 'auto', 'background-repeat': 'no-repeat', 'background-size': this.options.width + "px " + this.options.height + "px" }; - // Does this image have an associated link? - if ($(img1).data('href')) { - css1.cursor = 'pointer'; - this.image1.addClass('hasLink'); - this.image1.data('href', $(img1).data('href')); - } else { - this.image1.removeClass('hasLink'); - this.image1.data('href', null); - } - this.image1.css(css1).children().remove(); - + var img2 = this.getImageData(this.nextImageIndex); this.image2.css({ - 'background-image': 'url("' + this.getImage(this.nextImageIndex).src + '")', + 'background-image': 'url("' + img2.replace(/(\r\n|\n|\r)/gm, "") + '")', 'z-index': 100, 'background-repeat': 'no-repeat', 'background-size': this.options.width + "px " + this.options.height + "px", @@ -470,6 +461,11 @@ window.flux = { return this.images[index]; }, + getImageData: function (index) { + index = index % this.imageData.length; + + return this.imageData[index]; + }, setNextIndex: function (nextIndex) { if (nextIndex == undefined) nextIndex = this.currentImageIndex + 1; diff --git a/routes/index.js b/routes/index.js index 6842131..bde1ba8 100644 --- a/routes/index.js +++ b/routes/index.js @@ -24,11 +24,20 @@ module.exports = function (websocket, dispatcher) { res.render('index', {config: config}); }); + router.get('/favicon.ico', function (req, res, next) { + res.send("public/favicon.ico"); + }); + router.get('/display/:id/lite', function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); let idx = parseInt(req.params.id); let volume = req.params.videoVolume || 1.; - res.render('liteDisplay', {config: config, display: availableDisplays[idx], displayId: idx, videoVolume: volume}); + res.render('liteDisplay', { + config: config, + display: availableDisplays[idx], + displayId: idx, + videoVolume: volume + }); }); router.get('/display/:id', function (req, res, next) { diff --git a/views/admin/editSlide.twig b/views/admin/editSlide.twig index acd7801..b7a090b 100644 --- a/views/admin/editSlide.twig +++ b/views/admin/editSlide.twig @@ -66,9 +66,10 @@ diff --git a/views/admin/overview.twig b/views/admin/overview.twig index fbbd41c..edcb23e 100644 --- a/views/admin/overview.twig +++ b/views/admin/overview.twig @@ -2,12 +2,18 @@ {% block header %} + {% endblock %} {% block body %}
+

+ {{ t ("infoscreen") }} +

{{ t("index.displays") }}

@@ -18,13 +24,89 @@

{{ display.name }}

- View + + +
+ + + + + + + +
{% endfor %}
-{% endblock %} + + +{% endblock %} \ No newline at end of file diff --git a/views/liteDisplay.twig b/views/liteDisplay.twig index 63a45bd..f64fe36 100644 --- a/views/liteDisplay.twig +++ b/views/liteDisplay.twig @@ -19,13 +19,13 @@
- - + + -
+
-
+
@@ -40,9 +40,13 @@ {% endblock %}