From 7f3961c2aa1c74d5d19f6bc54c0d74cd227abc62 Mon Sep 17 00:00:00 2001 From: Jonatan Nilsson Date: Thu, 28 Jul 2016 18:21:50 +0000 Subject: [PATCH] Implemented dagskra graphic --- app/client.js | 1 + app/controller/components.js | 39 ++++++ app/controller/graphic/controller.js | 60 +++++--- app/controller/graphic/engine/schedule.js | 162 ++++++++++++++++++++++ app/controller/graphic/engine/text.js | 3 +- app/controller/graphic/view.js | 1 + app/frontend/schedule.js | 20 +++ server/io/engine/routes.js | 2 +- 8 files changed, 267 insertions(+), 21 deletions(-) create mode 100644 app/controller/graphic/engine/schedule.js create mode 100644 app/frontend/schedule.js diff --git a/app/client.js b/app/client.js index 60c7272..e38be1f 100644 --- a/app/client.js +++ b/app/client.js @@ -3,6 +3,7 @@ var socket = require('./socket') var engines = { text: require('./frontend/text'), countdown: require('./frontend/countdown'), + schedule: require('./frontend/schedule'), } var current = [] diff --git a/app/controller/components.js b/app/controller/components.js index c6c7781..2858940 100644 --- a/app/controller/components.js +++ b/app/controller/components.js @@ -6,6 +6,45 @@ exports.error = function(error) { return m('div.error-box', error) } +exports.presetOnlyList = function(vm) { + return [ + m('label', 'Presets'), + m('ul.panel-graphic-preset', vm.presets.map((item, index) => + m('li', { key: index }, [ + m('.row', { key: index }, [ + m('div', { class: 'small-8 columns panel-graphic-property-item' }, + m('input[type=text]', { + readonly: true, + value: item.values[graphic.settings.main], + }) + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-preset-remove.button.success', { + onclick: vm.displayPreset.bind(vm, item), + }, 'Display') + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-preset-remove.button.alert', { + onclick: vm.removePreset.bind(vm, item), + }, 'Remove') + ), + ]) + ]) + )) + ] +} + +exports.presetButtons = function(vm) { + return [ + m('a.panel-graphic-preset-add.button', { + onclick: vm.addPreset.bind(vm), + }, 'Save to preset list'), + m('a.panel-graphic-display.success.button', { + onclick: vm.displayCurrent.bind(vm), + }, 'Display'), + ] +} + exports.presetList = function(vm) { return [ m('a.panel-graphic-preset-add.button', { diff --git a/app/controller/graphic/controller.js b/app/controller/graphic/controller.js index 70fcdae..ebaf9ad 100644 --- a/app/controller/graphic/controller.js +++ b/app/controller/graphic/controller.js @@ -11,6 +11,7 @@ const Graphic = createModule({ this.currentView = 'view' this.current = {} this.newProperty = m.prop('') + this.newTextField = m.prop('') }, updated: function(name, variable, control) { @@ -25,24 +26,51 @@ const Graphic = createModule({ } }, - addProperty: function() { - if (!this.newProperty()) { - this.error = 'Please type in property name' - return - } - if (this.graphic.settings.properties.includes(this.newProperty())) { - this.error = 'A property with that name already exists' - return + addDataField: function(type, name) { + if (!name) { + return 'Please type in proper name' } - this.graphic.settings.properties.push(this.newProperty()) - this.newProperty('') - - if (!this.graphic.settings.main) { - this.graphic.settings.main = this.graphic.settings.properties[0] + if (this.graphic.settings[type].includes(name)) { + return 'A property with that name already exists' } + this.graphic.settings[type].push(name) + socket.emit('graphic.update', this.graphic) + + return null + }, + + addProperty: function() { + this.error = this.addDataField('properties', this.newProperty()) + + if (!this.error) { + this.newProperty('') + + if (!this.graphic.settings.main) { + this.graphic.settings.main = this.graphic.settings.properties[0] + socket.emit('graphic.update', this.graphic) + } + } + }, + + addTextField: function() { + this.error = this.addDataField('textfields', this.newTextField()) + + if (!this.error) { + this.newTextField('') + } + }, + + removeDataField: function(type, name) { + this.graphic.settings[type].splice( + this.graphic.settings[type].indexOf(name), 1) + socket.emit('graphic.update', this.graphic) + }, + + removeProperty: function(prop) { + this.removeDataField('properties', prop) }, cleanCurrent: function() { @@ -116,12 +144,6 @@ const Graphic = createModule({ }) }, - removeProperty: function(prop) { - this.graphic.settings.properties.splice( - this.graphic.settings.properties.indexOf(prop), 1) - socket.emit('graphic.update', this.graphic) - }, - switchView: function() { if (Graphic.vm.currentView === 'view') { Graphic.vm.currentView = 'settings' diff --git a/app/controller/graphic/engine/schedule.js b/app/controller/graphic/engine/schedule.js new file mode 100644 index 0000000..d0dc583 --- /dev/null +++ b/app/controller/graphic/engine/schedule.js @@ -0,0 +1,162 @@ +const m = require('mithril') +const components = require('../../components') + +exports.view = function(ctlr, graphic, vm) { + if (!graphic.settings.properties) { + graphic.settings.properties = [] + } + if (!graphic.settings.textfields) { + graphic.settings.textfields = [] + } + if (graphic.settings.properties.length === 0) { + return [ + m('p', 'No properties have been defined.'), + m('p', 'Click settings to create and define properties to display.'), + ] + } + return [ + components.presetOnlyList(vm), + graphic.settings.properties.map((prop, index) => + m('label', { key: index }, [ + prop, + m('input[type=text]', { + value: vm.current[prop] || '', + oninput: vm.updated.bind(vm, prop, 'current'), + }), + ]) + ), + graphic.settings.textfields.map((prop, index) => + m('label', { key: index }, [ + prop, + m('textarea', { + rows: '6', + oninput: vm.updated.bind(vm, prop, 'current'), + value: vm.current[prop] || '', + }), + ]) + ), + components.presetButtons(vm), + ] +} + +exports.settings = function(cltr, graphic, vm) { + return [ + m('label', [ + 'Name', + m('input[type=text]', { + value: graphic.name, + oninput: vm.updated.bind(vm, 'name'), + }), + ]), + m('label', [ + 'HTML (', + m('a', { href: 'https://lodash.com/docs#template', target: '_blank' }, 'variables'), + ' available: ', + graphic.settings.properties.map(prop => + `<%- ${prop} %>` + ).join(', '), + ', ', + graphic.settings.textfields.map(prop => + `<%- ${prop} %>` + ).join(', '), + ')', + m('p', `
`), + m('textarea', { + rows: '4', + oninput: vm.updated.bind(null, 'settings.html'), + value: graphic.settings.html || '', + }), + m('p', `
`), + ]), + m('label', [ + 'CSS', + m('textarea', { + rows: '4', + oninput: vm.updated.bind(null, 'settings.css'), + value: graphic.settings.css || '', + }) + ]), + /* -------- Simple Properties -------- */ + m('label', 'Simple Properties'), + m('label', [ + 'Main', + m('select', { + onchange: vm.updated.bind(vm, 'settings.main'), + }, graphic.settings.properties.map((prop, index) => + m('option', { + key: 'prop-list-' + index, + value: prop, + selected: prop === graphic.settings.main, + }, prop) + )) + ]), + /* -------- Simple Properties List -------- */ + m('label', 'List'), + m('div', [ + graphic.settings.properties.map((prop, index) => + m('.row', { key: 'add-prop-' + index }, [ + m('div', { class: 'small-10 columns panel-graphic-property-item' }, + m('input[type=text]', { + readonly: true, + value: prop, + }) + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-property-remove.button.alert', { + onclick: vm.removeProperty.bind(vm, prop), + }, 'Remove') + ) + ]) + ), + ]), + m('.row', [ + m('div', { class: 'small-10 columns panel-graphic-property-item' }, + m('input[type=text]', { + value: vm.newProperty(), + oninput: m.withAttr('value', vm.newProperty), + }) + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-property-add.button', { + onclick: vm.addProperty.bind(vm), + }, 'Add') + ), + ]), + /* -------- Text Properties -------- */ + m('label', 'Text Fields'), + m('div', [ + graphic.settings.textfields.map((prop, index) => + m('.row', { key: 'add-prop-' + index }, [ + m('div', { class: 'small-10 columns panel-graphic-property-item' }, + m('input[type=text]', { + readonly: true, + value: prop, + }) + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-property-remove.button.alert', { + onclick: vm.removeDataField.bind(vm, 'textfields', prop), + }, 'Remove') + ) + ]) + ), + ]), + m('.row', [ + m('div', { class: 'small-10 columns panel-graphic-property-item' }, + m('input[type=text]', { + value: vm.newTextField(), + oninput: m.withAttr('value', vm.newTextField), + }) + ), + m('div', { class: 'small-2 columns' }, + m('a.panel-graphic-property-add.button', { + onclick: vm.addTextField.bind(vm), + }, 'Add') + ), + ]), + /* -------- Delete -------- */ + m('a.panel-graphic-delete.button.alert', { + onclick: vm.remove.bind(vm), + }, 'Delete graphic'), + ] +} diff --git a/app/controller/graphic/engine/text.js b/app/controller/graphic/engine/text.js index d2a6d16..29e0e0d 100644 --- a/app/controller/graphic/engine/text.js +++ b/app/controller/graphic/engine/text.js @@ -12,6 +12,7 @@ exports.view = function(ctlr, graphic, vm) { ] } return [ + components.presetOnlyList(vm), graphic.settings.properties.map((prop, index) => m('label', { key: index }, [ prop, @@ -21,7 +22,7 @@ exports.view = function(ctlr, graphic, vm) { }), ]) ), - components.presetList(vm), + components.presetButtons(vm), ] } diff --git a/app/controller/graphic/view.js b/app/controller/graphic/view.js index 9376c7e..dae9e69 100644 --- a/app/controller/graphic/view.js +++ b/app/controller/graphic/view.js @@ -5,6 +5,7 @@ const components = require('../components') const engines = { text: require('./engine/text'), countdown: require('./engine/countdown'), + schedule: require('./engine/schedule'), } Graphic.view = function(ctrl) { diff --git a/app/frontend/schedule.js b/app/frontend/schedule.js new file mode 100644 index 0000000..0fb2e92 --- /dev/null +++ b/app/frontend/schedule.js @@ -0,0 +1,20 @@ + +module.exports = function(data) { + var element = document.createElement('div') + element.innerHTML = data.html + element.id = data.graphic.name + element.classList.add('root-element') + + var styleElement = document.createElement('style') + styleElement.setAttribute('type', 'text/css') + styleElement.innerHTML = data.css + + element.tag = styleElement + + document.body.appendChild(element) + document.head.appendChild(styleElement) + + window.setTimeout(function (){ + element.classList.add('root-element-display') + }, 100) +} diff --git a/server/io/engine/routes.js b/server/io/engine/routes.js index 9b3f709..2adaaaf 100644 --- a/server/io/engine/routes.js +++ b/server/io/engine/routes.js @@ -1,4 +1,4 @@ export function all(ctx) { - ctx.socket.emit('engine.all', ['text', 'countdown']) + ctx.socket.emit('engine.all', ['text', 'countdown', 'schedule']) }