development
This commit is contained in:
parent
12775a934e
commit
767c4dd73d
44 changed files with 6708 additions and 389 deletions
4
.babelrc
4
.babelrc
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
"presets": ["es2015-node5"],
|
||||
"plugins": [
|
||||
"transform-async-to-generator",
|
||||
"syntax-async-functions"
|
||||
"transform-es2015-modules-commonjs"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ version: 2
|
|||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: docker:17.05.0-ce-git
|
||||
- image: circleci/node:latest
|
||||
working_directory: ~/caspar-sup
|
||||
steps:
|
||||
- checkout
|
||||
|
@ -11,14 +11,15 @@ jobs:
|
|||
name: Build docker image
|
||||
command: docker build -t nfpis/caspar-sup:build_${CIRCLE_BUILD_NUM} -t nfpis/caspar-sup:${CIRCLE_SHA1} -t nfpis/caspar-sup:latest .
|
||||
- run:
|
||||
name: Run test and lint
|
||||
command: |
|
||||
docker run nfpis/recording_control npm run lint
|
||||
docker run nfpis/recording_control npm run test
|
||||
- deploy:
|
||||
name: Push to docker
|
||||
command: |
|
||||
docker login -u $DOCKER_USER -p $DOCKER_PASS
|
||||
docker push nfpis/caspar-sup
|
||||
- deploy:
|
||||
name: Deploy to production
|
||||
command: |
|
||||
echo Not implemented
|
||||
workflows:
|
||||
version: 2
|
||||
build_deploy:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parser": "babel-eslint",
|
||||
"extends": "airbnb/base",
|
||||
"extends": "airbnb-base",
|
||||
"ecmaFeatures": {
|
||||
"modules": false
|
||||
},
|
||||
|
|
|
@ -6,10 +6,6 @@ import config from '../config'
|
|||
import log from '../log'
|
||||
|
||||
let host = config.get('knex:connection')
|
||||
/* istanbul ignore if */
|
||||
if (host.match && host.match(/@[^/]+/)) {
|
||||
host = host.match(/@[^/]+/)[0]
|
||||
}
|
||||
|
||||
log.info(host, 'Connecting to DB')
|
||||
|
||||
|
@ -33,10 +29,26 @@ let shelf = bookshelf(client)
|
|||
shelf.createModel = (attr, opts) => {
|
||||
// Create default attributes to all models
|
||||
let attributes = _.defaults(attr, {
|
||||
/**
|
||||
* Initialize a new instance of model. This does not get called when
|
||||
* relations to this model is being fetched though.
|
||||
*/
|
||||
initialize() {
|
||||
this.on('fetching', this.checkFetching)
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler when fetch() is called. This gets called for both
|
||||
* when getSingle() or just manual fetch() is called as well as
|
||||
* when relation models through belongsTo() resources get fetched.
|
||||
*
|
||||
* @param {Model} model - The model instance if fetch() was used. For
|
||||
* belongsTo this is the relation model thingy.
|
||||
* @param {Array} columns - Array of columns to select if fetch() was used.
|
||||
* Otherwise this is null.
|
||||
* @param {Object} options - Options for the fetch. Includes the query
|
||||
* builder object.
|
||||
*/
|
||||
checkFetching(model, columns, options) {
|
||||
options.query.where({ is_deleted: false })
|
||||
},
|
||||
|
@ -44,6 +56,12 @@ shelf.createModel = (attr, opts) => {
|
|||
|
||||
// Create default options for all models
|
||||
let options = _.defaults(opts, {
|
||||
/**
|
||||
* Create new model object in database.
|
||||
*
|
||||
* @param {Object} data - The values the new model should have
|
||||
* @return {Model} The resulted model
|
||||
*/
|
||||
create(data) {
|
||||
return this.forge(data).save()
|
||||
},
|
||||
|
|
8
api/content/connection.js
Normal file
8
api/content/connection.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { reset, list } from './routes'
|
||||
|
||||
export async function contentConnection(ctx) {
|
||||
ctx.log.info('Got new socket connection')
|
||||
|
||||
list(ctx)
|
||||
reset(ctx)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import bookshelf from '../../bookshelf'
|
||||
import bookshelf from '../bookshelf'
|
||||
|
||||
/* Graphic model:
|
||||
{
|
|
@ -1,17 +1,12 @@
|
|||
import Graphic from './model'
|
||||
|
||||
function getSocket(ctx, all) {
|
||||
if (all === true) return ctx.io
|
||||
return ctx.socket
|
||||
}
|
||||
|
||||
export async function all(ctx, all) {
|
||||
export async function all(ctx) {
|
||||
let data = await Graphic.getAll()
|
||||
|
||||
getSocket(ctx, all).emit('graphic.all', data.toJSON())
|
||||
ctx.io.emit('graphic.all', data.toJSON())
|
||||
}
|
||||
|
||||
export async function single(ctx, data, all) {
|
||||
export async function single(ctx, data) {
|
||||
if (!data || !data.id) {
|
||||
ctx.log.warn('called graphic get single but no id specified')
|
||||
return
|
||||
|
@ -19,7 +14,7 @@ export async function single(ctx, data, all) {
|
|||
|
||||
let graphic = await Graphic.getSingle(data.id)
|
||||
|
||||
getSocket(ctx, all).emit('graphic.single', graphic.toJSON())
|
||||
ctx.io.emit('graphic.single', graphic.toJSON())
|
||||
}
|
||||
|
||||
export async function create(ctx, data) {
|
||||
|
@ -33,7 +28,7 @@ export async function create(ctx, data) {
|
|||
|
||||
await Graphic.create(data)
|
||||
|
||||
await all(ctx, true)
|
||||
await all(ctx)
|
||||
}
|
||||
|
||||
export async function remove(ctx, data) {
|
||||
|
@ -46,7 +41,7 @@ export async function remove(ctx, data) {
|
|||
graphic.set({ is_deleted: true })
|
||||
await graphic.save()
|
||||
|
||||
await all(ctx, true)
|
||||
await all(ctx)
|
||||
}
|
||||
|
||||
export async function update(ctx, data) {
|
||||
|
@ -61,5 +56,5 @@ export async function update(ctx, data) {
|
|||
|
||||
await graphic.save()
|
||||
|
||||
await single(ctx, data, true)
|
||||
await single(ctx, data)
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
import './koa'
|
|
@ -1,7 +1,5 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
import { reset, list } from './content/routes'
|
||||
|
||||
export function register(ctx, name, method) {
|
||||
if (_.isPlainObject(method)) {
|
||||
Object.keys(method).forEach(key => {
|
||||
|
@ -21,10 +19,3 @@ export function register(ctx, name, method) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function newConnection(ctx) {
|
||||
ctx.log.info('Got new socket connection')
|
||||
|
||||
list(ctx)
|
||||
reset(ctx)
|
||||
}
|
20
api/koa.js
20
api/koa.js
|
@ -1,20 +0,0 @@
|
|||
import serve from 'koa-static'
|
||||
import Koa from 'koa'
|
||||
import socket from 'koa-socket'
|
||||
import config from '../config'
|
||||
import log from '../log'
|
||||
import router from './io/router'
|
||||
import { bunyanLogger, errorHandler } from './middlewares'
|
||||
|
||||
const app = new Koa()
|
||||
const io = new socket()
|
||||
|
||||
io.attach(app)
|
||||
|
||||
io.on('connection', router.bind(this, io))
|
||||
|
||||
app.use(bunyanLogger(log))
|
||||
app.use(errorHandler())
|
||||
app.use(serve('public'))
|
||||
|
||||
app.listen(config.get('server:port'))
|
|
@ -1,4 +1,4 @@
|
|||
import bookshelf from '../../bookshelf'
|
||||
import bookshelf from '../bookshelf'
|
||||
|
||||
/* Preset model:
|
||||
{
|
|
@ -1,16 +1,11 @@
|
|||
import Preset from './model'
|
||||
|
||||
function getSocket(ctx, all) {
|
||||
if (all === true) return ctx.io
|
||||
return ctx.socket
|
||||
}
|
||||
|
||||
export async function all(ctx, payload, all) {
|
||||
export async function all(ctx, payload) {
|
||||
let id = Number(payload.graphic_id || payload.id)
|
||||
|
||||
let data = await Preset.getAll({ graphic_id: id })
|
||||
|
||||
getSocket(ctx, all).emit(`preset.all:${id}`, data.toJSON())
|
||||
ctx.io.emit(`preset.all:${id}`, data.toJSON())
|
||||
}
|
||||
|
||||
export async function add(ctx, payload) {
|
||||
|
@ -29,7 +24,7 @@ export async function add(ctx, payload) {
|
|||
|
||||
await Preset.create(payload)
|
||||
|
||||
await all(ctx, payload, true)
|
||||
await all(ctx, payload)
|
||||
}
|
||||
|
||||
export async function remove(ctx, payload) {
|
||||
|
@ -39,5 +34,5 @@ export async function remove(ctx, payload) {
|
|||
|
||||
await preset.save()
|
||||
|
||||
await all(ctx, payload, true)
|
||||
await all(ctx, payload)
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import logger from '../../log'
|
||||
import { register, newConnection } from './connection'
|
||||
import logger from '../log'
|
||||
import { register } from './io/helper'
|
||||
import { contentConnection } from './content/connection'
|
||||
|
||||
import * as content from './content/routes'
|
||||
import * as engine from './engine/routes'
|
||||
|
@ -15,7 +16,7 @@ function onConnection(server, data) {
|
|||
|
||||
let ctx = { io, socket, log }
|
||||
|
||||
newConnection(ctx)
|
||||
contentConnection(ctx)
|
||||
|
||||
register(ctx, 'content', content)
|
||||
register(ctx, 'engine', engine)
|
24
api/server.js
Normal file
24
api/server.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import Koa from 'koa'
|
||||
import serve from 'koa-better-serve'
|
||||
import socket from 'koa-socket'
|
||||
|
||||
import config from '../config'
|
||||
import log from '../log'
|
||||
import onConnection from './routerio'
|
||||
import { bunyanLogger, errorHandler } from './middlewares'
|
||||
|
||||
const app = new Koa()
|
||||
const io = new socket()
|
||||
|
||||
io.attach(app)
|
||||
|
||||
io.on('connection', onConnection.bind(this, io))
|
||||
|
||||
app.use(bunyanLogger(log))
|
||||
app.use(errorHandler())
|
||||
app.use(serve('./public', '/public'))
|
||||
|
||||
app.listen(config.get('server:port'), err => {
|
||||
if (err) return log.critical(err)
|
||||
log.info(`Server is listening on ${config.get('server:port')}`)
|
||||
})
|
|
@ -1,9 +1,9 @@
|
|||
var socket = require('./socket')
|
||||
var socket = require('../socket')
|
||||
|
||||
var engines = {
|
||||
text: require('./frontend/text'),
|
||||
countdown: require('./frontend/countdown'),
|
||||
schedule: require('./frontend/schedule'),
|
||||
text: require('./text'),
|
||||
countdown: require('./countdown'),
|
||||
schedule: require('./schedule'),
|
||||
}
|
||||
|
||||
var current = []
|
|
@ -12,14 +12,15 @@
|
|||
//in the console.
|
||||
window.components = {}
|
||||
|
||||
require('./socket')
|
||||
require('./controller/store')
|
||||
require('../socket')
|
||||
require('./store')
|
||||
|
||||
const m = require('mithril')
|
||||
const Header = require('./controller/header')
|
||||
const Menu = require('./controller/menu')
|
||||
const Add = require('./controller/add')
|
||||
const Graphic = require('./controller/graphic/controller')
|
||||
const Header = require('./header')
|
||||
const Menu = require('./menu')
|
||||
|
||||
const Add = require('./add')
|
||||
const Graphic = require('./graphic')
|
||||
|
||||
m.mount(document.getElementById('header'), Header)
|
||||
m.mount(document.getElementById('menu'), Menu)
|
47
app/styl/client.styl
Normal file
47
app/styl/client.styl
Normal file
|
@ -0,0 +1,47 @@
|
|||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing:border-box; /* This sets all elements to be the actual set dimensions, disregarding padding and borders */
|
||||
/* -webkit-backface-visibility: hidden; /* Hide the backface of elements - useful for 3d effects */
|
||||
-webkit-transition: translate3d(0,0,0); /* Turns on hardware acceleration - not known to be of benefit in CCG, but won't hurt */
|
||||
}
|
||||
html, body {
|
||||
width:1920px; /* Set to your channel's resolution */
|
||||
height:1080px; /* Set to your channel's resolution */
|
||||
margin:0; /* Use all available space */
|
||||
padding:0; /* Use all available space */
|
||||
background:transparent; /* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
|
||||
overflow:hidden; /* Hide any overflowing elements - to disable scollbars */
|
||||
-webkit-font-smoothing:antialiased !important; /* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
|
||||
}
|
||||
body {
|
||||
font-family: Calibri,Arial;
|
||||
font-size: 40px;
|
||||
color: #FFFFFF;
|
||||
/* -webkit-text-stroke-width: 0.5px;
|
||||
-webkit-text-stroke-color: #888888;
|
||||
text-shadow: 2px 2px 1px #000000; */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial;
|
||||
font-weight: normal;
|
||||
text-shadow: 0px 0px 0px #000000;
|
||||
font-size: 22pt;
|
||||
}
|
||||
html {
|
||||
overflow: auto;
|
||||
}
|
||||
body > div
|
||||
{
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.root-element {
|
||||
opacity: 0;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
.root-element-display {
|
||||
opacity: 1;
|
||||
transition: opacity 1s;
|
||||
}
|
241
app/styl/main.styl
Normal file
241
app/styl/main.styl
Normal file
|
@ -0,0 +1,241 @@
|
|||
body {
|
||||
background: #3f3f41;
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
|
||||
.container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.container-header {
|
||||
font-size: 1.5rem;
|
||||
margin-left: 1rem;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
.container-panel {
|
||||
border: 1px solid #3f3f3f;
|
||||
background: #2d2d30;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
|
||||
.header-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-item {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.header-item-hide {
|
||||
float: right;
|
||||
width: 5rem;
|
||||
border-radius: 6px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-item-display {
|
||||
background: #070707;
|
||||
color: #eb6e00;
|
||||
border-radius: 6px;
|
||||
padding: 0.5rem 1rem;
|
||||
margin-right: 5.5rem;
|
||||
}
|
||||
|
||||
/* Menu */
|
||||
|
||||
.menu-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
color: #007acc;
|
||||
display: block;
|
||||
border: 1px solid #2d2d30;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
color: #f1f1f1;
|
||||
border: 1px solid #007acc;
|
||||
}
|
||||
|
||||
.menu-item-add {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
/* Add */
|
||||
|
||||
.panel-add {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-add,
|
||||
.panel-graphic-property-remove {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Graphic */
|
||||
|
||||
.panel-graphic-delete {
|
||||
|
||||
}
|
||||
|
||||
.panel-graphic-settings {
|
||||
float: right;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-item {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-add {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-preset {
|
||||
margin-top: 1rem;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.panel-graphic-preset a {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Components */
|
||||
|
||||
.error-box {
|
||||
margin: 0rem 0rem 2rem 0;
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/* Inputs */
|
||||
|
||||
.panel-graphic-property-item input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
label {
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
textarea {
|
||||
background: #333337;
|
||||
border-color: #3f3f3f;
|
||||
color: #999999;
|
||||
transition-property: none !important;
|
||||
}
|
||||
|
||||
input[type="text"]:hover,
|
||||
textarea:hover {
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
textarea:focus {
|
||||
background: #333337;
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
input[readonly],
|
||||
input[readonly]:hover {
|
||||
background: #2d2d30 !important;
|
||||
border-color: #3f3f3f;
|
||||
}
|
||||
|
||||
select {
|
||||
background: #333337;
|
||||
border-color: #3f3f3f;
|
||||
color: #999999;
|
||||
background-position: right center;
|
||||
background-size: 9px 6px;
|
||||
background-origin: content-box;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>')
|
||||
}
|
||||
|
||||
select:hover {
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
background: #333337;
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
a.button {
|
||||
margin: 0 1rem 0 0;
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
/* Media queries */
|
||||
|
||||
body {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 1280px) {
|
||||
.header-item-hide {
|
||||
width: 9rem;
|
||||
line-height: 0rem;
|
||||
}
|
||||
|
||||
a.button {
|
||||
font-size: 2rem;
|
||||
line-height: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.panel-graphic-preset {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.panel-graphic-display,
|
||||
.panel-graphic-preset-add {
|
||||
margin-bottom: 3rem !important;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-remove {
|
||||
padding-right: 0.5rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-remove.alert {
|
||||
padding-right: 1rem;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-settings {
|
||||
font-size: 1.3rem !important;
|
||||
}
|
||||
|
||||
.header-item-display {
|
||||
font-size: 2rem;
|
||||
margin-right: 12.5rem;
|
||||
padding: 0.2rem 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-item input {
|
||||
font-size: 2rem;
|
||||
height: 3.5rem;
|
||||
}
|
||||
}
|
25
index.js
25
index.js
|
@ -3,35 +3,12 @@ require('babel-register')
|
|||
|
||||
let log = require('./log').default
|
||||
|
||||
function exitHandler(options, err) {
|
||||
if (options.cleanup) {
|
||||
log.warn('Application is shutting down')
|
||||
}
|
||||
if (err) {
|
||||
log.error('An unhandled error occured')
|
||||
log.error(err)
|
||||
}
|
||||
if (options.exit) {
|
||||
log.warn('Application is exiting')
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
// do something when app is closing
|
||||
process.on('exit', exitHandler.bind(null, { cleanup: true }))
|
||||
|
||||
// catches ctrl+c event
|
||||
process.on('SIGINT', exitHandler.bind(null, { exit: true }))
|
||||
|
||||
// catches uncaught exceptions
|
||||
process.on('uncaughtException', exitHandler.bind(null, { exit: true }))
|
||||
|
||||
// Run the database script automatically.
|
||||
log.info('Running database integrity scan.')
|
||||
let setup = require('./script/setup')
|
||||
|
||||
setup().then(() => {
|
||||
require('./api')
|
||||
require('./api/server')
|
||||
}).catch((error) => {
|
||||
log.error(error, 'Error while preparing database')
|
||||
process.exit(1)
|
||||
|
|
6091
package-lock.json
generated
Normal file
6091
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
75
package.json
75
package.json
|
@ -4,15 +4,23 @@
|
|||
"description": "CasparCG superimposed graphics project",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "npm test",
|
||||
"build-main:js": "browserify app/main.js -o public/main.js --debug",
|
||||
"watch-main:js": "watchify app/main.js -o public/main.js --debug",
|
||||
"build-client:js": "browserify app/client.js -o public/client.js --debug",
|
||||
"watch-client:js": "watchify app/client.js -o public/client.js --debug",
|
||||
"build": "npm run build-main:js && npm run build-client:js",
|
||||
"build:watch": "parallelshell \"npm run watch-main:js\" \"npm run watch-client:js\"",
|
||||
"start": "node index.js | bunyan",
|
||||
"start:dev": "nodemon index.js | bunyan"
|
||||
"build:styl": "stylus -m app/styl/main.styl --out public",
|
||||
"watch:styl": "stylus -w -m app/styl/main.styl --out public",
|
||||
"build-client:styl": "stylus -m app/styl/client.styl --out public",
|
||||
"watch-client:styl": "stylus -w -m app/styl/client.styl --out public",
|
||||
"watch:js": "watchify -t babelify app/main.js -o public/main.js --debug",
|
||||
"build:js": "browserify app/main.js -o public/main.js --debug -t [ babelify ]",
|
||||
"watch-client:js": "watchify -t babelify app/client.js -o public/client.js --debug",
|
||||
"build-client:js": "browserify app/client.js -o public/client.js --debug -t [ babelify ]",
|
||||
"watch:server": "nodemon index.js",
|
||||
"start": "node index.js",
|
||||
"dev-run": "run-p watch:js watch-client:js watch:server watch:styl watch-client:styl",
|
||||
"prod-run": "npm run build:js && npm run build-client:js && npm run build:styl && npm run build-client:styl && npm start",
|
||||
"test": "env NODE_ENV=test mocha --require babel-register --recursive --reporter dot",
|
||||
"docker": "docker run -it --rm --name my-running-script -v \"$PWD\":/usr/src/app -w /usr/src/app node:alpine",
|
||||
"docker:test": "npm run docker -- npm install && npm run test",
|
||||
"docker:dev": "npm run docker -- npm install && npm run dev-run",
|
||||
"docker:run": "npm run docker -- npm install && npm run prod-run"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -30,36 +38,27 @@
|
|||
},
|
||||
"homepage": "https://github.com/nfp-projects/caspar-sup#readme",
|
||||
"dependencies": {
|
||||
"app-root-path": "^1.0.0",
|
||||
"babel-plugin-syntax-async-functions": "^6.5.0",
|
||||
"babel-plugin-transform-async-to-generator": "^6.7.0",
|
||||
"babel-preset-es2015-node5": "^1.1.2",
|
||||
"babel-register": "^6.7.2",
|
||||
"bookshelf": "^0.9.2",
|
||||
"browserify": "^13.0.0",
|
||||
"bunyan": "^1.7.1",
|
||||
"knex": "^0.10.0",
|
||||
"koa": "^2.0.0-alpha.3",
|
||||
"koa-socket": "^4.3.0",
|
||||
"koa-static": "^3.0.0",
|
||||
"lodash": "^4.6.1",
|
||||
"mithril": "^0.2.3",
|
||||
"nconf": "^0.8.4",
|
||||
"parallelshell": "^2.0.0",
|
||||
"socket.io": "^1.4.5",
|
||||
"socket.io-client": "^1.4.5",
|
||||
"sqlite3": "^3.1.3"
|
||||
"app-root-path": "^2.0.1",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
|
||||
"babel-register": "^6.26.0",
|
||||
"bookshelf": "^0.11.1",
|
||||
"bunyan": "^1.8.12",
|
||||
"knex": "^0.14.2",
|
||||
"koa": "^2.4.1",
|
||||
"koa-better-serve": "^2.0.7",
|
||||
"koa-socket": "^4.4.0",
|
||||
"mithril": "^1.1.5",
|
||||
"nconf": "^0.9.1",
|
||||
"socket.io": "^2.0.4",
|
||||
"socket.io-client": "^2.0.4",
|
||||
"sqlite3": "^3.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert-extended": "^1.0.1",
|
||||
"babel-eslint": "^5.0.0",
|
||||
"eslint": "^2.2.0",
|
||||
"eslint-config-airbnb": "^6.1.0",
|
||||
"eslint-plugin-mocha": "^2.0.0",
|
||||
"live-reload": "^1.1.0",
|
||||
"mocha": "^2.4.5",
|
||||
"sinon": "^1.17.3",
|
||||
"sinon-as-promised": "^4.0.0",
|
||||
"watchify": "^3.7.0"
|
||||
"babelify": "^8.0.0",
|
||||
"mocha": "^4.0.1",
|
||||
"nodemon": "^1.12.1",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"stylus": "^0.54.5",
|
||||
"watchify": "^3.9.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,53 @@
|
|||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing:border-box; /* This sets all elements to be the actual set dimensions, disregarding padding and borders */
|
||||
/* -webkit-backface-visibility: hidden; /* Hide the backface of elements - useful for 3d effects */
|
||||
-webkit-transition: translate3d(0,0,0); /* Turns on hardware acceleration - not known to be of benefit in CCG, but won't hurt */
|
||||
box-sizing: border-box;
|
||||
/* This sets all elements to be the actual set dimensions, disregarding padding and borders */
|
||||
/* -webkit-backface-visibility: hidden; /* Hide the backface of elements - useful for 3d effects */
|
||||
-webkit-transition: translate3d(0, 0, 0); /* Turns on hardware acceleration - not known to be of benefit in CCG, but won't hurt */
|
||||
}
|
||||
html, body {
|
||||
width:1920px; /* Set to your channel's resolution */
|
||||
height:1080px; /* Set to your channel's resolution */
|
||||
margin:0; /* Use all available space */
|
||||
padding:0; /* Use all available space */
|
||||
background:transparent; /* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
|
||||
overflow:hidden; /* Hide any overflowing elements - to disable scollbars */
|
||||
-webkit-font-smoothing:antialiased !important; /* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
/* Set to your channel's resolution */
|
||||
height: 1080px;
|
||||
/* Set to your channel's resolution */
|
||||
margin: 0;
|
||||
/* Use all available space */
|
||||
padding: 0;
|
||||
/* Use all available space */
|
||||
background: transparent;
|
||||
/* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
|
||||
overflow: hidden;
|
||||
/* Hide any overflowing elements - to disable scollbars */
|
||||
-webkit-font-smoothing: antialiased !important;
|
||||
/* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
|
||||
}
|
||||
body {
|
||||
font-family: Calibri,Arial;
|
||||
font-family: Calibri, Arial;
|
||||
font-size: 40px;
|
||||
color: #FFFFFF;
|
||||
/* -webkit-text-stroke-width: 0.5px;
|
||||
color: #fff;
|
||||
/* -webkit-text-stroke-width: 0.5px;
|
||||
-webkit-text-stroke-color: #888888;
|
||||
text-shadow: 2px 2px 1px #000000; */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial;
|
||||
font-weight: normal;
|
||||
text-shadow: 0px 0px 0px #000000;
|
||||
text-shadow: 0px 0px 0px #000;
|
||||
font-size: 22pt;
|
||||
}
|
||||
html {
|
||||
overflow: auto;
|
||||
}
|
||||
body > div
|
||||
{
|
||||
body > div {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.root-element {
|
||||
opacity: 0;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
.root-element-display {
|
||||
opacity: 1;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
/*# sourceMappingURL=client.css.map */
|
1
public/client.css.map
Normal file
1
public/client.css.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["../app/styl/client.styl"],"names":[],"mappings":"AAAA;EACE,oBAAoB,WAApB;EACA,YAAW,WAAX;AAA4C;AAC7C;EACC,oBAAqC,qBAArC;AAA4C;;AAE9C;AAAM;EACJ,OAAM,OAAN;AAAyD;EACzD,QAAO,OAAP;AAAyD;EACzD,QAAO,EAAP;AAAyD;EACzD,SAAQ,EAAR;AAAyD;EACzD,YAAW,YAAX;AAAyD;EACzD,UAAS,OAAT;AAAyD;EACzD,wBAAuB,uBAAvB;AAAyD;;AAE3D;EACE,aAAoB,eAApB;EACA,WAAW,KAAX;EACA,OAAO,KAAP;AACA;;;;AAKF;EACE,aAAa,MAAb;EACA,aAAa,OAAb;EACA,aAAa,iBAAb;EACA,WAAW,KAAX;;AAEF;EACE,UAAU,KAAV;;AAEF;EAEE,UAAU,SAAV;;AAGF;EACE,SAAS,EAAT;EACA,YAAY,WAAZ;;AAGF;EACE,SAAS,EAAT;EACA,YAAY,WAAZ","file":"client.css"}
|
|
@ -3,8 +3,7 @@
|
|||
<head>
|
||||
<title>CasparCG Controller</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link href="foundation.css" rel="stylesheet" />
|
||||
<link href="main.css" rel="stylesheet" />
|
||||
<link href="/public/main.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="expanded row">
|
||||
|
@ -14,6 +13,6 @@
|
|||
<div class="small-3 columns container" id="menu"></div>
|
||||
<div class="small-9 columns container" id="content"></div>
|
||||
</div>
|
||||
<script src="main.js"></script>
|
||||
<script src="/public/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
197
public/main.css
197
public/main.css
|
@ -2,240 +2,189 @@ body {
|
|||
background: #3f3f41;
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
|
||||
.container {
|
||||
.container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.container-header {
|
||||
}
|
||||
.container-header {
|
||||
font-size: 1.5rem;
|
||||
margin-left: 1rem;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
.container-panel {
|
||||
color: #777;
|
||||
}
|
||||
.container-panel {
|
||||
border: 1px solid #3f3f3f;
|
||||
background: #2d2d30;
|
||||
padding: 1rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
}
|
||||
/* Header */
|
||||
|
||||
.header-list {
|
||||
.header-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-item {
|
||||
}
|
||||
.header-item {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.header-item-hide {
|
||||
}
|
||||
.header-item-hide {
|
||||
float: right;
|
||||
width: 5rem;
|
||||
border-radius: 6px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-item-display {
|
||||
}
|
||||
.header-item-display {
|
||||
background: #070707;
|
||||
color: #eb6e00;
|
||||
border-radius: 6px;
|
||||
padding: 0.5rem 1rem;
|
||||
margin-right: 5.5rem;
|
||||
}
|
||||
|
||||
}
|
||||
/* Menu */
|
||||
|
||||
.menu-list {
|
||||
.menu-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
}
|
||||
.menu a {
|
||||
color: #007acc;
|
||||
display: block;
|
||||
border: 1px solid #2d2d30;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
}
|
||||
.menu a:hover {
|
||||
color: #f1f1f1;
|
||||
border: 1px solid #007acc;
|
||||
}
|
||||
|
||||
.menu-item-add {
|
||||
}
|
||||
.menu-item-add {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
}
|
||||
/* Add */
|
||||
|
||||
.panel-add {
|
||||
.panel-add {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-add,
|
||||
.panel-graphic-property-remove {
|
||||
}
|
||||
.panel-graphic-property-add,
|
||||
.panel-graphic-property-remove {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
/* Graphic */
|
||||
|
||||
.panel-graphic-delete {
|
||||
|
||||
}
|
||||
|
||||
.panel-graphic-settings {
|
||||
.panel-graphic-settings {
|
||||
float: right;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-item {
|
||||
}
|
||||
.panel-graphic-property-item {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-add {
|
||||
}
|
||||
.panel-graphic-preset-add {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-preset {
|
||||
}
|
||||
.panel-graphic-preset {
|
||||
margin-top: 1rem;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.panel-graphic-preset a {
|
||||
}
|
||||
.panel-graphic-preset a {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
/* Components */
|
||||
|
||||
.error-box {
|
||||
.error-box {
|
||||
margin: 0rem 0rem 2rem 0;
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
color: #f00;
|
||||
}
|
||||
/* Inputs */
|
||||
|
||||
.panel-graphic-property-item input {
|
||||
.panel-graphic-property-item input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
label {
|
||||
}
|
||||
label {
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
textarea {
|
||||
}
|
||||
input[type="text"],
|
||||
textarea {
|
||||
background: #333337;
|
||||
border-color: #3f3f3f;
|
||||
color: #999999;
|
||||
color: #999;
|
||||
transition-property: none !important;
|
||||
}
|
||||
|
||||
input[type="text"]:hover,
|
||||
textarea:hover {
|
||||
}
|
||||
input[type="text"]:hover,
|
||||
textarea:hover {
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
textarea:focus {
|
||||
}
|
||||
input[type="text"]:focus,
|
||||
textarea:focus {
|
||||
background: #333337;
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
input[readonly],
|
||||
input[readonly]:hover {
|
||||
}
|
||||
input[readonly],
|
||||
input[readonly]:hover {
|
||||
background: #2d2d30 !important;
|
||||
border-color: #3f3f3f;
|
||||
}
|
||||
|
||||
select {
|
||||
}
|
||||
select {
|
||||
background: #333337;
|
||||
border-color: #3f3f3f;
|
||||
color: #999999;
|
||||
color: #999;
|
||||
background-position: right center;
|
||||
background-size: 9px 6px;
|
||||
background-origin: content-box;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>')
|
||||
}
|
||||
|
||||
select:hover {
|
||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>");
|
||||
}
|
||||
select:hover {
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
}
|
||||
select:focus {
|
||||
background: #333337;
|
||||
color: #f1f1f1;
|
||||
border-color: #007acc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
a.button {
|
||||
}
|
||||
a.button {
|
||||
margin: 0 1rem 0 0;
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
}
|
||||
/* Media queries */
|
||||
|
||||
body {
|
||||
body {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 1280px) {
|
||||
}
|
||||
@media only screen and (max-device-width: 1280px) {
|
||||
.header-item-hide {
|
||||
width: 9rem;
|
||||
line-height: 0rem;
|
||||
}
|
||||
|
||||
a.button {
|
||||
font-size: 2rem;
|
||||
line-height: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.panel-graphic-preset {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.panel-graphic-display,
|
||||
.panel-graphic-preset-add {
|
||||
margin-bottom: 3rem !important;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-remove {
|
||||
padding-right: 0.5rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
.panel-graphic-preset-remove.alert {
|
||||
padding-right: 1rem;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-settings {
|
||||
font-size: 1.3rem !important;
|
||||
}
|
||||
|
||||
.header-item-display {
|
||||
font-size: 2rem;
|
||||
margin-right: 12.5rem;
|
||||
padding: 0.2rem 1rem;
|
||||
}
|
||||
|
||||
.panel-graphic-property-item input {
|
||||
font-size: 2rem;
|
||||
height: 3.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*# sourceMappingURL=main.css.map */
|
1
public/main.css.map
Normal file
1
public/main.css.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["../app/styl/main.styl"],"names":[],"mappings":"AAAA;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;;AAGF;EACE,eAAe,KAAf;;AAGF;AAEE;EACE,SAAS,KAAT;;AAGF;EACE,WAAW,OAAX;EACA,aAAa,KAAb;EACA,OAAO,KAAP;;AAGF;EACE,QAAQ,kBAAR;EACA,YAAY,QAAZ;EACA,SAAS,KAAT;EACA,eAAe,IAAf;;AAGJ;AAEE;EACE,iBAAiB,KAAjB;EACA,QAAQ,EAAR;;AAGF;EACE,eAAe,KAAf;;AAGF;EACE,OAAO,MAAP;EACA,OAAO,KAAP;EACA,eAAe,IAAf;EACA,QAAQ,EAAR;;AAGF;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,eAAe,IAAf;EACA,SAAS,YAAT;EACA,cAAc,OAAd;;AAGJ;AAEE;EACE,iBAAiB,KAAjB;EACA,QAAQ,EAAR;;AAGF;EACE,OAAO,QAAP;EACA,SAAS,MAAT;EACA,QAAQ,kBAAR;EACA,SAAS,cAAT;;AAGF;EACE,OAAO,QAAP;EACA,QAAQ,kBAAR;;AAGF;EACE,YAAY,KAAZ;;AAGJ;AAEE;EACE,SAAS,KAAT;;AAGF;AAA4B;EAE1B,OAAO,KAAP;;AAGJ;AAME;EACE,OAAO,MAAP;EACA,cAAc,KAAd;;AAGF;EACE,cAAc,EAAd;;AAGF;EACE,cAAc,KAAd;;AAGF;EACE,YAAY,KAAZ;EACA,iBAAiB,KAAjB;;AAGF;EACE,OAAO,KAAP;;AAGJ;AAEE;EACE,QAAQ,iBAAR;EACA,OAAO,KAAP;;AAGJ;AAEE;EACE,SAAS,aAAT;;AAGF;EACE,OAAO,QAAP;;AAGF;AAAmB;EAEjB,YAAY,QAAZ;EACA,cAAc,QAAd;EACA,OAAO,KAAP;EACA,qBAAqB,gBAArB;;AAGF;AAAyB;EAEvB,OAAO,QAAP;EACA,cAAc,QAAd;;AAGF;AAAyB;EAEvB,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,cAAc,QAAd;EACA,YAAY,KAAZ;;AAGF;AAAgB;EAEd,YAAY,mBAAZ;EACA,cAAc,QAAd;;AAGF;EACE,YAAY,QAAZ;EACA,cAAc,QAAd;EACA,OAAO,KAAP;EACA,qBAAqB,aAArB;EACA,iBAAiB,QAAjB;EACA,mBAAmB,YAAnB;EACA,mBAAmB,UAAnB;EACA,kBAAuO,uNAAvO;;AAGF;EACE,OAAO,QAAP;EACA,cAAc,QAAd;;AAGF;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,cAAc,QAAd;EACA,YAAY,KAAZ;;AAGF;EACE,QAAQ,WAAR;EACA,OAAO,KAAP;;AAGJ;AAEE;EACE,WAAW,OAAX;;AAG8C;AAC9C;IACE,OAAO,KAAP;IACA,aAAa,KAAb;;AAGF;IACE,WAAW,KAAX;IACA,aAAa,EAAb;IACA,OAAO,KAAP;;AAGF;IACE,QAAQ,EAAR;;AAGF;AAAuB;IAErB,eAAe,gBAAf;;AAGF;IACE,eAAe,OAAf;IACA,cAAc,OAAd;;AAGF;IACE,eAAe,KAAf;IACA,cAAc,KAAd;;AAGF;IACE,WAAW,kBAAX;;AAGF;IACE,WAAW,KAAX;IACA,cAAc,QAAd;IACA,SAAS,YAAT;;AAGF;IACE,WAAW,KAAX;IACA,QAAQ,OAAR","file":"main.css"}
|
1
run.bat
1
run.bat
|
@ -1 +0,0 @@
|
|||
npm run build && npm start
|
|
@ -1,2 +0,0 @@
|
|||
git pull
|
||||
npm install && run
|
Loading…
Reference in a new issue