diff --git a/infodisplay/index.html b/infodisplay/index.html new file mode 100644 index 0000000..95c5fce --- /dev/null +++ b/infodisplay/index.html @@ -0,0 +1,38 @@ + + + + + c-flo info display + + + + + + + + + diff --git a/infodisplay/infodisplay.js b/infodisplay/infodisplay.js new file mode 100644 index 0000000..5798241 --- /dev/null +++ b/infodisplay/infodisplay.js @@ -0,0 +1,94 @@ +var msgflo = window.infodisplay.msgflo; +var timeout = null; + +var getRotationUrl = function (urls, current) { + var newUrl = urls[Math.floor(Math.random() * urls.length)]; + if (newUrl === current && urls.length > 1) { + // Flip the coin again + return getRotationUrl(urls, current); + } + return newUrl; +}; + +var DisplayParticipant = function (broker, role, defaultUrls, timer) { + var urls = defaultUrls; + var def = { + component: 'msgflo-browser/infodisplay', + label: 'Browser-based information display', + icon: 'television', + inports: [ + { + id: 'open', + type: 'string' + }, + { + id: 'urls', + type: 'array' + } + ], + outports: [ + { + id: 'opened', + type: 'string' + }, + { + id: 'urls', + type: 'array', + hidden: true + } + ] + }; + var process = function (inport, indata, callback) { + var current = document.getElementById('current'); + var next = document.getElementById('next'); + if (inport === 'urls') { + // Update URL listing + urls = indata; + return callback('urls', null, urls); + } + next.onerror = function (err) { + next.onload = null; + next.onerror = null; + participant.send('open', getRotationUrl(urls, indata)); + } + next.onload = function () { + next.onload = null; + next.onerror = null; + // Cross-fade + next.id = 'current'; + current.id = 'next'; + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(function () { + participant.send('open', getRotationUrl(urls, indata)); + }, timer); + return callback('opened', null, next.getAttribute('src')); + }; + next.setAttribute('src', indata); + // Rotate internal URLs list + }; + var client = new msgflo.mqtt.Client(broker, {}); + var participant = new msgflo.participant.Participant(client, def, process, role); + return participant; +} + +window.addEventListener('load', function () { + var params = msgflo.options({ + broker: 'mqtt://c-beam.cbrp3.c-base.org:1882', + role: 'infodisplay', + urls: [ + 'http://c-beam.cbrp3.c-base.org/he1display', + 'https://c-base.org' + ], + timer: 120000, + }); + var p = DisplayParticipant(params.broker, params.role, params.urls, params.timer); + p.start(function (err) { + if (err) { + console.error(err); + return; + } + p.send('open', getRotationUrl(params.urls)); + }); +}, false); diff --git a/msgflo.js b/msgflo.js new file mode 100644 index 0000000..f0b8dde --- /dev/null +++ b/msgflo.js @@ -0,0 +1,5 @@ +import msgflo from 'msgflo-browser'; + +export { + msgflo, +}; diff --git a/package.json b/package.json index 18186a2..66210ae 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@webcomponents/webcomponentsjs": "^1.0.19", "d3": "^4.12.0", + "msgflo-browser": "^0.2.0", "plotly.js": "^1.31.2", "skatejs": "^5.0.0-beta.4" }, @@ -27,6 +28,7 @@ "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.8.0", "http-server": "^0.10.0", + "msgflo-nodejs": "^0.11.1", "webpack": "^3.8.1" } } diff --git a/webpack.config.js b/webpack.config.js index 0ae7447..64254ac 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,13 +1,19 @@ module.exports = { - entry: './index.js', + entry: { + infoscreens: './index.js', + infodisplay: './msgflo.js', + }, output: { path: __dirname, - filename: 'dist/infoscreens.js' + filename: 'dist/[name].js', + library: '[name]', + libraryTarget: 'umd', }, module: { rules: [ { test: /\.js$/, + exclude: /paho.mqtt.js/, use: { loader: 'babel-loader', options: { @@ -17,5 +23,14 @@ module.exports = { } } ] - } + }, + externals: { + newrelic: 'commonjs newrelic', + tv4: 'commonjs tv4', + 'ampqlib/callback_api': 'commonjs ampqlib/callback_api', + mqtt: 'commonjs mqtt', + }, + node: { + fs: 'empty', + }, };