infoscreens/infodisplay/infodisplay.js

132 lines
3.5 KiB
JavaScript
Raw Normal View History

import msgflo from 'msgflo-browser';
2017-11-28 22:30:37 +01:00
let timeout = null;
2017-11-28 22:21:35 +01:00
2017-11-28 22:30:37 +01:00
function getRotationUrl(urls, current) {
const newUrl = urls[Math.floor(Math.random() * urls.length)];
2017-11-28 22:21:35 +01:00
if (newUrl === current && urls.length > 1) {
// Flip the coin again
return getRotationUrl(urls, current);
}
return newUrl;
2017-11-28 22:30:37 +01:00
}
2017-11-28 22:21:35 +01:00
2017-11-28 22:30:37 +01:00
function DisplayParticipant(broker, role, defaultUrls, timer) {
let urls = defaultUrls;
let participant;
const def = {
2017-11-29 15:14:48 +01:00
component: 'c-base/infodisplay',
2017-11-29 15:12:00 +01:00
label: 'Show URL on a public screen.',
2017-11-28 22:21:35 +01:00
icon: 'television',
inports: [
{
id: 'open',
2017-11-29 15:12:00 +01:00
description: 'URL to be opened',
2017-11-28 22:30:37 +01:00
type: 'string',
2017-11-28 22:21:35 +01:00
},
{
id: 'urls',
2017-11-29 15:12:00 +01:00
description: 'URL list for rotation',
2017-11-28 22:30:37 +01:00
type: 'array',
},
2017-11-28 22:21:35 +01:00
],
outports: [
{
id: 'opened',
2017-11-29 15:12:00 +01:00
description: 'The URL that has been opened and is showing.',
2017-11-28 22:30:37 +01:00
type: 'string',
2017-11-28 22:21:35 +01:00
},
{
id: 'urls',
type: 'array',
2017-11-28 22:30:37 +01:00
hidden: true,
},
],
2017-11-28 22:21:35 +01:00
};
2017-11-28 22:30:37 +01:00
const process = (inport, indata, callback) => {
const current = document.getElementById('current');
const next = document.getElementById('next');
2017-11-28 22:21:35 +01:00
if (inport === 'urls') {
// Update URL listing
urls = indata;
2017-11-28 22:30:37 +01:00
callback('urls', null, urls);
2017-11-29 18:14:37 +01:00
return;
2017-11-28 22:21:35 +01:00
}
if (next.getAttribute('src') === indata) {
// Already open!
next.id = 'current';
current.id = 'next';
2017-12-01 19:51:13 +01:00
timeout = setTimeout(() => {
participant.send('open', getRotationUrl(urls, indata));
}, timer);
callback('opened', null, next.getAttribute('src'));
return;
}
window.onmessage = null;
2017-11-28 22:30:37 +01:00
next.onerror = (err) => {
2017-11-28 22:21:35 +01:00
next.onload = null;
next.onerror = null;
participant.send('open', getRotationUrl(urls, indata));
2017-12-01 19:48:51 +01:00
callback('opened', err);
2017-11-28 22:30:37 +01:00
};
next.onload = () => {
2017-11-28 22:21:35 +01:00
next.onload = null;
next.onerror = null;
// Cross-fade
next.id = 'current';
current.id = 'next';
if (timeout) {
clearTimeout(timeout);
}
2017-11-28 22:30:37 +01:00
timeout = setTimeout(() => {
2017-11-28 22:21:35 +01:00
participant.send('open', getRotationUrl(urls, indata));
}, timer);
window.onmessage = (event) => {
window.onmessage = null;
const now = new Date();
if (!event.data
|| !event.data.waitUntil) {
return;
}
if (timeout) {
clearTimeout(timeout);
}
if (event.data.waitUntil < now.getTime()) {
participant.send('open', getRotationUrl(urls, indata));
return;
}
timeout = setTimeout(() => {
participant.send('open', getRotationUrl(urls, indata));
}, event.data.waitUntil - now.getTime());
};
2017-11-28 22:30:37 +01:00
callback('opened', null, next.getAttribute('src'));
2017-11-28 22:21:35 +01:00
};
next.setAttribute('src', indata);
// Rotate internal URLs list
};
2017-11-28 22:30:37 +01:00
const client = new msgflo.mqtt.Client(broker, {});
participant = new msgflo.participant.Participant(client, def, process, role);
2017-11-28 22:21:35 +01:00
return participant;
}
2017-11-29 18:14:37 +01:00
function onPageReady() {
window.removeEventListener('load', onPageReady, false);
2017-11-28 22:30:37 +01:00
const params = msgflo.options({
2017-11-28 22:21:35 +01:00
broker: 'mqtt://c-beam.cbrp3.c-base.org:1882',
role: 'infodisplay',
urls: [
'http://c-beam.cbrp3.c-base.org/he1display',
2017-11-28 22:30:37 +01:00
'https://c-base.org',
2017-11-28 22:21:35 +01:00
],
2017-12-01 19:32:08 +01:00
timer: 60000,
2017-11-28 22:21:35 +01:00
});
2017-11-28 22:30:37 +01:00
const p = DisplayParticipant(params.broker, params.role, params.urls, params.timer);
p.start((err) => {
2017-11-28 22:21:35 +01:00
if (err) {
2017-11-28 22:46:40 +01:00
throw err;
2017-11-28 22:21:35 +01:00
}
p.send('open', getRotationUrl(params.urls));
});
2017-11-29 18:14:37 +01:00
}
window.addEventListener('load', onPageReady, false);