Init WebCG
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX - PREVIEW</title>
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_renderpopups.css">
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script>
|
||||
var socket = io();
|
||||
|
||||
socket.on('connect', function () {
|
||||
data={};
|
||||
data.name = 'SPX_PREVIEW'; // <---- Name of this socket connection
|
||||
data.spxcmd = 'identifyClient';
|
||||
socket.emit('SPXMessage2Server', data);
|
||||
});
|
||||
|
||||
socket.on('SPXMessage2Client', function (data) {
|
||||
// Handles messages coming from server to this client.
|
||||
// All comms using 'SPXMessage2Client' as a conduit with data object and
|
||||
// data.spxcmd as function identifier. Additional object values are payload.
|
||||
// console.log('SPXMessage2Client received', data)
|
||||
switch (data.spxcmd) {
|
||||
case 'closepreview':
|
||||
// console.log('Close preview window request received from Controller');
|
||||
window.close();
|
||||
break;
|
||||
|
||||
default:
|
||||
// console.log('Unknown SPXMessage2Client command: ' + data.command);
|
||||
}
|
||||
}); // end SPXMessage2Client
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body onresize="resizePreview();" onunload="return windowClosing();">
|
||||
|
||||
<!-- maybe in the future
|
||||
<div id="toolbar">
|
||||
<div>PREVIEW</div>
|
||||
<div>Clear</div>
|
||||
<div>Layers</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="watermark prev"></div>
|
||||
<div id="previewBG" style="background-color: rgb(0, 0, 0); overflow: hidden;">
|
||||
<iframe id="previewIF"
|
||||
src="/renderer?preview=true"
|
||||
class="renderer"
|
||||
style="width: {{width}}px; height: {{height}}px;"></iframe>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function windowClosing() {
|
||||
console.log('========= Closing ============');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function resizePreview() {
|
||||
// Preview renderer size set by SPX to {{width}}x{{height}}
|
||||
let DefaultX = 1920; // Math always defaults to 16:9
|
||||
let DefaultY = 1080;
|
||||
|
||||
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
|
||||
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
|
||||
|
||||
if (DefaultX.includes('vw')) {
|
||||
// Responsive settings, use window size! Added in v1.3.0
|
||||
DefaultX = vw;
|
||||
DefaultY = vy;
|
||||
}
|
||||
|
||||
let Wpx = vw// document.getElementById('previewWidthRuler').offsetWidth;
|
||||
let Sca = Wpx/DefaultX;
|
||||
let Hpx = parseInt(DefaultY * Sca);
|
||||
document.getElementById('previewBG').style.width=Wpx+'px';
|
||||
document.getElementById('previewBG').style.height=Hpx+'px';
|
||||
document.getElementById('previewIF').style.transform="scale("+Sca+")";
|
||||
document.getElementById('previewBG').style.display='block';
|
||||
// console.log('Resized to ' + Wpx + ' x ' + Hpx + ' px, scale multiplier: ' + Sca);
|
||||
}
|
||||
|
||||
resizePreview();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX - PROGRAM EMULATOR</title>
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_renderpopups.css">
|
||||
<style>
|
||||
.renderer {
|
||||
/* rendererscalable hardcoded to 1920x1080 */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0px;
|
||||
outline: 0px;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
background-size: 10vw;
|
||||
transform-origin: top left;
|
||||
background-image: url('/img/checker60.png'); /* bgimage for local preview */
|
||||
}
|
||||
|
||||
</style>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script>
|
||||
var socket = io();
|
||||
|
||||
socket.on('connect', function () {
|
||||
data={};
|
||||
data.name = 'SPX_PROGRAM'; // <---- Name of this socket connection
|
||||
data.spxcmd = 'identifyClient';
|
||||
socket.emit('SPXMessage2Server', data);
|
||||
});
|
||||
|
||||
socket.on('SPXMessage2Client', function (data) {
|
||||
// Handles messages coming from server to this client.
|
||||
// All comms using 'SPXMessage2Client' as a conduit with data object and
|
||||
// data.spxcmd as function identifier. Additional object values are payload.
|
||||
// console.log('SPXMessage2Client received', data)
|
||||
switch (data.spxcmd) {
|
||||
case 'closeprogram':
|
||||
// console.log('Close program window request received from Controller');
|
||||
window.close();
|
||||
break;
|
||||
|
||||
default:
|
||||
// console.log('Unknown SPXMessage2Client command: ' + data.command);
|
||||
}
|
||||
}); // end SPXMessage2Client
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onresize="resizePreview();" > <!-- onunload="sendWinClosedMessage('unload');" onload="sendWinClosedMessage('load');" -->
|
||||
<!-- maybe in the future
|
||||
<div id="toolbar">
|
||||
<div>PROGRAM</div>
|
||||
<div>Clear</div>
|
||||
<div>Layers</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="watermark prog"></div>
|
||||
<div id="previewBG" style="background-color: rgb(0, 0, 0); overflow: hidden;">
|
||||
<iframe id="previewIF"
|
||||
src="/renderer"
|
||||
class="renderer"
|
||||
ZZstyle="width: {{width}}; height: {{height}}; aspect-ratio: {{aspect}}; border: 1px solid purple;"
|
||||
></iframe>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function resizePreview() {
|
||||
return
|
||||
// Program renderer size set by SPX to {{width}}x{{height}}
|
||||
let DefaultX = 1920; // Math always defaults to 16:9
|
||||
let DefaultY = 1080;
|
||||
|
||||
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
|
||||
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
|
||||
|
||||
if (DefaultX.includes('vw')) {
|
||||
// Responsive settings, use window size! Added in v1.3.0
|
||||
DefaultX = vw;
|
||||
DefaultY = vy;
|
||||
}
|
||||
|
||||
let Wpx = vw// document.getElementById('previewWidthRuler').offsetWidth;
|
||||
let Sca = Wpx/DefaultX;
|
||||
let Hpx = parseInt(DefaultY * Sca);
|
||||
document.getElementById('previewBG').style.width=Wpx+'px';
|
||||
document.getElementById('previewBG').style.height=Hpx+'px';
|
||||
document.getElementById('previewIF').style.transform="scale("+Sca+")";
|
||||
document.getElementById('previewBG').style.display='block';
|
||||
// console.log('Resized to ' + Wpx + ' x ' + Hpx + ' px, scale multiplier: ' + Sca);
|
||||
}
|
||||
|
||||
resizePreview();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,68 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Example App</title>
|
||||
|
||||
<style>
|
||||
.itemrow {
|
||||
border: 0px solid green;
|
||||
border-radius: 0px;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-bottom: 1px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.itemrow:nth-child(odd) {
|
||||
background: rgb(75, 75, 75);
|
||||
}
|
||||
|
||||
.itemrow:nth-child(even) {
|
||||
background: rgb(46, 43, 43);
|
||||
}
|
||||
|
||||
.list {
|
||||
border: 0px solid red;
|
||||
width: 500px;
|
||||
padding: 2px
|
||||
}
|
||||
|
||||
.spx_input {
|
||||
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
|
||||
font-size: 1.2rem;
|
||||
line-height: 12px;
|
||||
border: 0px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
width: 47%;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
|
||||
.input_active {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: rgb(236, 224, 171);
|
||||
outline: blue 2px;
|
||||
}
|
||||
|
||||
.input_deactive {
|
||||
background-color: rgba(1, 1, 1, 0);
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{>navi}}
|
||||
|
||||
|
||||
{{{body}}}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Choose a file</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #444;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
font-size: 1.6vw;
|
||||
}
|
||||
|
||||
.spxMainPanel {
|
||||
height: 55vw;
|
||||
display: table;
|
||||
width: 100%;
|
||||
max-width: 2000px;
|
||||
text-align: center;
|
||||
border: 0px solid yellow;
|
||||
border-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.spxTopRow {
|
||||
display: table-row;
|
||||
height: 4em;
|
||||
color: white;
|
||||
border: 1px solid yellowgreen;
|
||||
}
|
||||
|
||||
.spxBottomRow {
|
||||
display: table-row;
|
||||
height: 12.5em;
|
||||
/* background: rgb(9, 36, 9); */
|
||||
color: beige;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.spxMainSection {
|
||||
height: 100%;
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
border: 2px solid green;
|
||||
}
|
||||
|
||||
.spxCell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
margin: 10px !important;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.spxPanelL {
|
||||
width: 50%;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spxPanelC {
|
||||
width: 0.1em;
|
||||
/* background: red; */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spxPanelR {
|
||||
color: white;
|
||||
border-left: 2px solid grey;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.headlineArea {
|
||||
border-top: 2px solid grey;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.btn {
|
||||
padding: 0.5em 1.0em;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
color: white;
|
||||
border: 2px solid rgb(255, 255, 255, 0.0);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
border: 2px solid black;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
|
||||
.darkBg {
|
||||
background-color: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
|
||||
.bg_green {
|
||||
background-color: #54af3c;
|
||||
}
|
||||
|
||||
.bg_yellow {
|
||||
background-color: #e5c310;
|
||||
}
|
||||
|
||||
.bg_blue {
|
||||
background-color: #375ea3;
|
||||
}
|
||||
|
||||
.bg_red {
|
||||
background-color: #c80019;
|
||||
}
|
||||
|
||||
.bg_black {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.bg_white {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.bg_grey60 {
|
||||
background-color: #2f303e;
|
||||
}
|
||||
|
||||
.bg_grey40 {
|
||||
background-color: #444758;
|
||||
}
|
||||
|
||||
.bg_grey15 {
|
||||
background-color: #706e83;
|
||||
}
|
||||
|
||||
.headlineinput {
|
||||
padding: 0.2em;
|
||||
background-color: inherit;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-size: 1.4em;
|
||||
margin: 0px;
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg_black">
|
||||
<div class="spxMainPanel bg_grey60">
|
||||
|
||||
<H1></H1>
|
||||
|
||||
{{{body}}}
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ SPX GRAPHICS CONTROLLER ║
|
||||
╟───────────────────────────────────────────────────────────╢
|
||||
║ (c) 2020- SPX Graphics ║
|
||||
║ https://spxgraphics.com ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
╭───────────────────────────────────────────────────────────╮
|
||||
│ Painstakingly hand coded, no frameworks. │
|
||||
│ "Some extract of vanilla, enough to feed Godzilla." │
|
||||
╰───────────────────────────────────────────────────────────╯
|
||||
Made in 🇫🇮
|
||||
-->
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
<!-- footer start -->
|
||||
<div class="footerTable footer" style="background-color: rgba(0,0,0,0.2); padding:0 10 0 10px;">
|
||||
<table class="wide footerTable" style="border: 0px solid green;" cellpadding=0 cellspacing=0>
|
||||
<tr class="footerTable">
|
||||
<td class="footerTable">
|
||||
<span id="statusbar" class="footerTable statusbar"></span> <span id="working" class="working" style="display:none;"></span>
|
||||
</td>
|
||||
<td class="footerTable aright">
|
||||
|
||||
<!--
|
||||
style="padding: 2px 10px;
|
||||
background-color: rgb(39, 95, 58);
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
font-size: 90%;
|
||||
cursor: pointer;
|
||||
display: inline;
|
||||
"
|
||||
-->
|
||||
|
||||
<a id="upgradeBubble"
|
||||
href="https://spxgc.tawk.help/article/latest-changes"
|
||||
class="newVersionBubble"
|
||||
title="{{lang 'hover.newversavailable'}}"
|
||||
onmouseover="hvr('{{lang 'hover.newversavailable'}}')";
|
||||
onmouseout="hvr('')";
|
||||
>
|
||||
<i class="fas fa-bullhorn"></i> <span id="upgradeVersion">v.X.X.X</span> <span id="upg"></span></a></span>
|
||||
{{!-- </span> --}}
|
||||
<span class="footerTable statusbar" style="opacity:0.53;">
|
||||
SPX Solo v.<span id="footerVerDisplay">
|
||||
<span ondblclick="forceWM()" title="Click click!">{{{ShowVersion}}}</span>
|
||||
{{#ifValue width '3840px'}}
|
||||
<span style="color: #f80;"><B> 4K </B></span>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue width '100vw'}}
|
||||
<span style="color: #f80;"><B> AUTO </B></span>
|
||||
{{/ifValue}}
|
||||
|
||||
<!-- add a link to register -->
|
||||
{{#if config.registration.updated }}
|
||||
<!-- Reg ok -->
|
||||
{{else}}
|
||||
<A class="footerRegister" HREF="/register"><i class="fas fa-crown"></i> Register</A>
|
||||
{{/if}}
|
||||
|
||||
|
||||
</span>
|
||||
|
||||
{{#if easteregg}}
|
||||
{{{easterText}}}
|
||||
{{else}}
|
||||
<A href="http://spxgraphics.com" target="_spxgccom">spxgraphics.com</A></span>
|
||||
<span class="footerTable statusbar" style="opacity:0.33;"> | 💡 <A href="https://spxgraphics.com/contact" target="_feedback">Contact us</A></span>
|
||||
{{/if}}
|
||||
<!-- <span class="beta">beta</span> -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><!-- footer end -->
|
||||
|
||||
|
||||
<script>
|
||||
// show upgrade bubble if stored
|
||||
if (localStorage.getItem('SPX-GC-NewVersion')){
|
||||
document.getElementById('upgradeBubble').style.display="inline";
|
||||
document.getElementById('upgradeVersion').innerText=localStorage.getItem('SPX-GC-NewVersion');
|
||||
document.getElementById('newVersionMenuItem').style.display="block"; // Added in 1.1.0
|
||||
} else {
|
||||
document.getElementById('upgradeBubble').style.display="none"; // none
|
||||
document.getElementById('newVersionMenuItem').style.display="none"; // none
|
||||
}
|
||||
|
||||
function hvr(msg){
|
||||
document.getElementById('upg').innerText=msg;
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
<div id="messageSlider" style="opacity:0;"></div>
|
||||
|
||||
<div class="headerRow">
|
||||
<div id="logoZone" class="dropdown">
|
||||
<img src="/img/spx_offline.png" style="position: absolute; display:none;" id="logo_off">
|
||||
<img src="/img/spx_online.png" style="position: absolute; display:none;" id="logo_on">
|
||||
<img src="/img/spx_online.png" id="logo" style="cursor: pointer;">
|
||||
<div class="scrollingMenuArea scroller">
|
||||
<div class="dropdown-content">
|
||||
<A HREF="/"><i class="fas fa-home"></i> {{lang 'pagetitle.home'}}</A><br>
|
||||
<A HREF="/shows/"><i class="fas fa-folder"></i> {{lang 'pagetitle.shows'}}...</A><BR>
|
||||
<div style="font-size: 0.8em; padding-left: 1.0em; border-left: 10px solid rgba(0, 0, 0, 0.205);">
|
||||
{{#each recents}}
|
||||
<div id="recent{{@index}}"><i class="fas fa-file-alt"></i><A id="recent{{@index}}link" HREF="/gc/{{this}}"> {{this}}</A></div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
{{#ifValue disableConfigUI true}}
|
||||
<!-- disableConfigUI:true -->
|
||||
{{else}}
|
||||
<HR class="menuDivider">
|
||||
<A HREF="/config"><i class="fas fa-wrench"></i> {{lang 'pagetitle.configapp'}}...</A><BR>
|
||||
<A HREF="/api/v1" target="apiWin"><i class="fas fa-file-code"></i> API {{lang 'button.docs'}}...</A><BR>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue page "controller"}}
|
||||
<A HREF="" onClick="ModalOn('overlayHelp');return false;"><i class="far fa-keyboard"></i> {{lang 'button.shortcuts'}}...</A>
|
||||
{{/ifValue}}
|
||||
|
||||
<HR class="menuDivider">
|
||||
<A HREF="" onClick="spx_system('openWebRenderer');return false;"><i class="far fa-window-maximize"></i> {{lang 'button.showwebrenderer'}}</A><BR>
|
||||
<A HREF="" onClick="spx_system('OPENWEBRENDERER_SCALABLE');return false;"><i class="far fa-window-maximize"></i> {{lang 'button.showwebrenderer'}} (scalable)</A>
|
||||
{{{GenerateOpenFolderCommands}}}
|
||||
|
||||
{{#ifValue user "default"}}
|
||||
<!--default user -->
|
||||
{{else}}
|
||||
<HR class="menuDivider">
|
||||
<A HREF="/logout">Logout {{{user}}}...</A>
|
||||
{{/ifValue}}
|
||||
|
||||
<HR class="menuDivider">
|
||||
<A HREF="" onClick="spx_system('restartServer');return false;"><i class="fas fa-power-off"></i> Kill (restart SPX-server)</A>
|
||||
|
||||
<HR class="menuDivider">
|
||||
<A HREF="https://html.graphics" target="_new"><i class="fas fa-shopping-cart"></i> html.graphics/store</A><BR>
|
||||
<A HREF="https://bit.ly/joinspx" target="_new"><i class="fab fa-discord"></i> Join SPX Discord</A><br>
|
||||
<A HREF="https://spxcloud.app" target="_new"><i class="fas fa-cloud"></i> Run SPX in the Cloud</A><br>
|
||||
<A id="newVersionMenuItem" class="newVersionBubble" HREF="https://spxgc.tawk.help/article/latest-changes" target="_new"><i class="fas fa-bullhorn"></i> New version available!</A>
|
||||
|
||||
<!-- add a link to register -->
|
||||
{{#if config.registration.updated }}
|
||||
<!-- Reg ok -->
|
||||
{{else}}
|
||||
<A style="display: block;" class="newVersionBubble" HREF="/register"><i class="fas fa-crown"></i> Register for free...</A>
|
||||
{{!-- <div class="registrationDiv">
|
||||
<A HREF="/register/"><i class="fas fa-crown"></i> Register for free...</A><BR>
|
||||
</div> --}}
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="breadCrumsZone">
|
||||
{{#ifValue page "appconfig"}}
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs">SPX Solo - {{lang 'pagetitle.configapp'}}</span>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue page "shows"}}
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs">{{lang 'pagetitle.shows'}}</span>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue page "showconfig"}}
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs"><A HREF="/shows" onmouseover="tip('{{lang 'hover.navishows'}}');">{{lang 'pagetitle.shows'}}</A></span>
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs"><a href="/show/{{folder}}" onmouseover="tip('{{lang 'hover.navishow'}}');">{{prettyfyBreadcrumb folder}}</a></span>
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs">{{lang 'pagetitle.configshow'}}</span>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue page "episodes"}}
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs"><A HREF="/shows" onmouseover="tip('{{lang 'hover.navishows'}}');">{{lang 'pagetitle.shows'}}</A></span>
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs">{{prettyfyBreadcrumb folder}}</span>
|
||||
|
||||
<div class="breadIcon">
|
||||
<span onClick="projectSettings();" class="breadcrumbGear" title="Project settings"><i class="fas fa-cog"></i></span>
|
||||
</div>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue page "controller"}}
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs"><A HREF="/shows" onmouseover="tip('{{lang 'hover.navishows'}}');">{{lang 'pagetitle.shows'}}</A></span>
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs"><a href="/show/{{folder}}" onmouseover="tip('{{lang 'hover.navishow'}}');">{{prettyfyBreadcrumb folder}}</a></span>
|
||||
<div class="breadIcon">
|
||||
<a class="breadcrumbGear"
|
||||
href="/show/{{folder}}/config"
|
||||
onmouseover="tip('{{lang 'button.settings'}}');"
|
||||
title="{{lang 'button.settings'}}"><i class="fa fa-cog"></i></a>
|
||||
</div>
|
||||
|
||||
<span class="caret-icon">▶</span>
|
||||
<span class="breadcrumbs">{{prettyfyBreadcrumb filebasename}}</span>
|
||||
<div class="breadIcon">
|
||||
<a class="breadcrumbGear" href="#" onClick="toggleRundownSettings(); return false;" title="Rundown options"><i class="fa fa-bars"></i></a>
|
||||
</div>
|
||||
{{/ifValue}}
|
||||
|
||||
{{{DetectCustomContentPackages}}}
|
||||
|
||||
<!-- What is DetectCustomContentPackages?
|
||||
|
||||
You probably don't need to worry about this, but:
|
||||
|
||||
For development purposes we can have custom "content repositories"
|
||||
that are not part of the standard SPX installation. These repositories
|
||||
consists of complete ASSETS and DATAROOT subfolders and both of them
|
||||
will need to have a file "spx-content-repo.txt" in the root of the
|
||||
folders. This file will contain the name of the repository.
|
||||
|
||||
The spx-content-repo.txt textfile in the "normal" content repository
|
||||
should contain "CONTENT_FULL". This is used to distinguish the standard
|
||||
SPX content repository from custom ones.
|
||||
|
||||
There is a utility batch file "SWITCH_CONTENT.BAT" that can be used
|
||||
to switch between the standard SPX content repository and a custom one
|
||||
while developing. When using this utility the custom content repositories
|
||||
are kept in a folder called "CONTENT_REPOSITORIES" in the root of SPX
|
||||
installation. Each custom repository is kept in a subfolder of this
|
||||
folder and the name of the subfolder is the name of the repository and
|
||||
it should also be the content of the spx-content-repo.txt text files.
|
||||
|
||||
When a custom content repository is detected the name of the repository
|
||||
is shown in the header of the SPX UI.
|
||||
|
||||
Fun eh?
|
||||
|
||||
-->
|
||||
|
||||
</div>
|
||||
<div id="CasparZone" class="serverButtons">
|
||||
{{#ifValue page "controller"}}
|
||||
{{{ServerStatus}}}
|
||||
{{/ifValue}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!-- This is the file browser modal overlay (used by view-showconfig) -->
|
||||
<div class="overlay" id="filebrowserModal">
|
||||
<div class="modal wrapper">
|
||||
<div class="modal_top height4">
|
||||
<table class="wide" style="height:50%; border: 0px solid white; border-spacing: 0px;">
|
||||
<tr style="background-color: rgba(255,255,255,0.2);">
|
||||
<td valign="middle" style="font-size: 0.8em;">
|
||||
{{lang 'pagetitle.selectfile'}}
|
||||
</td>
|
||||
<td valign="middle" class="aright">
|
||||
<i style="font-size: 1.5em; cursor: pointer;" class="fas fa-window-close" onClick="ModalOff('filebrowserModal')"></i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="curfolder" id="curfolder"></div>
|
||||
</div>
|
||||
|
||||
<div class="modal_content content scroller">
|
||||
<div id="treeview" class="filebrowser">
|
||||
<UL>
|
||||
<LI style="user-select: none;" id="homefolder" class="filebrowser_up" onDblClick="goHome();"><SPAN class="icon home"></i>{{lang 'general.home'}}</SPAN></LI>
|
||||
<LI style="user-select: none;" id="prefolder" class="filebrowser_up" onDblClick="goUp();"><SPAN class="icon back">{{lang 'general.up'}}</SPAN></LI>
|
||||
</UL>
|
||||
<UL id="folderList">
|
||||
</UL>
|
||||
<UL id="fileList">
|
||||
</UL>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal_bottom">
|
||||
<table class="wide">
|
||||
<tr>
|
||||
<td width="10%">
|
||||
<a href="https://spxgraphics.com/store" target="_blank"><img border="0" alt="Template Store" title="SPX Store" src="/img/storeicon.png"></a></span>
|
||||
|
||||
</td>
|
||||
<td width="60%" valign="middle">
|
||||
<span id="browserMessage" class="browserMessage"></span>
|
||||
</td>
|
||||
<td class="spxFlexContainer aright" >
|
||||
<button style="width:25%;" class="spxformtext btn spxFlexItem bg_grey15 ripple" onClick="ModalOff('filebrowserModal')">{{lang 'button.cancel'}}</button>
|
||||
<button style="width:25%; opacity:0.2;" id="btnChooseTemplate" class="spxformtext btn spxFlexItem bg_blue ripple" onClick="openSelectedCSVFile();">{{lang 'button.selectemplate'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- overlay ended-->
|
||||
@@ -0,0 +1,53 @@
|
||||
<style>
|
||||
#extrabrowserHeaderBar {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Make the DIV element draggable:
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
dragElement(document.getElementById("extrabrowser"));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<!-- This is the file browser modal overlay (used by view-showconfig) -->
|
||||
<div class="overlay" id="extraoverlay" id="extrabrowserModal">
|
||||
<div class="modal wrapper" id="extrabrowser">
|
||||
<div class="modal_top height4" id="extrabrowserHeaderBar">
|
||||
<table class="wide" style="height:50%; border: 0px solid white; border-spacing: 0px;">
|
||||
<tr style="background-color: rgba(255,255,255,0.2);">
|
||||
<td valign="middle" style="font-size: 0.8em;">
|
||||
{{lang 'pagetitle.selectshowextra'}}
|
||||
</td>
|
||||
<td valign="middle" class="aright">
|
||||
<i style="font-size: 1.5em; cursor: pointer;" class="fas fa-window-close" onClick="ModalOff('extraoverlay');"></i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="modal_content content scroller">
|
||||
<div class="addTemplateItem row_accentExtras">
|
||||
<button type="button" class="addbtn bg_blue ripple" onClick="addExtra('button');" style="float:right;">+</button>
|
||||
<span class="templateName">{{lang 'config.extrabutton'}}</span><BR>
|
||||
<span class="templateDesc">{{lang 'config.extrabuttondescription'}}</span>
|
||||
</div>
|
||||
|
||||
<div class="addTemplateItem row_accentExtras">
|
||||
<button type="button" class="addbtn bg_blue ripple" onClick="addExtra('togglebutton');" style="float:right;">+</button>
|
||||
<span class="templateName">{{lang 'config.extratoggle'}}</span><BR>
|
||||
<span class="templateDesc">{{lang 'config.extratoggledescription'}}</span>
|
||||
</div>
|
||||
|
||||
<div class="addTemplateItem row_accentExtras">
|
||||
<button type="button" class="addbtn bg_blue ripple" onClick="addExtra('selectbutton');" style="float:right;">+</button>
|
||||
<span class="templateName">{{lang 'config.extraselectbutton'}}</span><BR>
|
||||
<span class="templateDesc">{{lang 'config.extraselectdescription'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div><!-- overlay ended-->
|
||||
@@ -0,0 +1,201 @@
|
||||
<style>
|
||||
.modal{
|
||||
left: 55%;
|
||||
}
|
||||
|
||||
.dialogHeaderBar {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Make the DIV element draggable:
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
dragElement(document.getElementById("dialog"));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<!-- This is the file browser modal overlay (used by view-showconfig) -->
|
||||
<div class="overlay" id="fileoverlay" idzzz="filebrowserModal">
|
||||
|
||||
<div class="modal wrapper">
|
||||
|
||||
<div class="dialogHeaderBar" >
|
||||
<div>{{lang 'pagetitle.selectemplate'}} ({{showconfig.projectFormat}})</div>
|
||||
<div class="dialogHeaderBarClose">
|
||||
<i class="fas fa-window-close dialogCloseButton" onClick="ModalOff('fileoverlay')"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabButtonRow" id="AddTemplatesTabBar">
|
||||
<button onclick="AddTemplatesTab(1)" id="tabBtn1" class="tablinks tabSelected" >Installed templates</button>
|
||||
<button id="formatSPX" class="tablinks {{#ifValue showconfig.projectFormat "SPX"}}tabSelected{{/ifValue}}">SPX</button>
|
||||
<button id="formatOGRAF" class="tablinks {{#ifValue showconfig.projectFormat "OGRAF"}}tabSelected{{/ifValue}}">OGRAF</button>
|
||||
|
||||
<div>
|
||||
<button onclick="AddTemplatesTab(2)" id="tabBtn2" class="tablinks">SPX Store</button>
|
||||
<button onclick="AddTemplatesTab(3)" id="tabBtn3" class="tablinks">Loopic</button>
|
||||
<button onclick="AddTemplatesTab(4)" id="tabBtn4" class="tablinks">Ferryman</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab1">
|
||||
<div class="modal_top">
|
||||
<div class="curfolder" id="curfolder"></div>
|
||||
</div>
|
||||
|
||||
<div class="scroller filebrowser">
|
||||
<UL>
|
||||
<LI style="user-select: none;" id="homefolder" class="filebrowser_up" onDblClick="goHome();"><SPAN class="icon home"></i>{{lang 'general.home'}}</SPAN></LI>
|
||||
<LI style="user-select: none;" id="prefolder" class="filebrowser_up" onDblClick="goUp();"><SPAN class="icon back">{{lang 'general.up'}}</SPAN></LI>
|
||||
</UL>
|
||||
<UL id="folderList">
|
||||
</UL>
|
||||
<UL id="fileList">
|
||||
</UL>
|
||||
</div>
|
||||
|
||||
<div class="modal_bottom">
|
||||
<div class="storeIcon"
|
||||
onmouseover="showMessage('Visit SPX Store for more templates')"
|
||||
onclick="window.open('https://spxgraphics.com/store', '_blank');"
|
||||
></div>
|
||||
<div style="flex-grow: 1;" >
|
||||
<span id="browserMessage" class="browserMessage"></span>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn bg_grey15 ripple" onClick="ModalOff('fileoverlay')">{{lang 'button.cancel'}}</button>
|
||||
<button style="opacity:0.2;" id="btnChooseTemplate" class="btn bg_blue ripple" onClick="openSelectedFiles();">{{lang 'button.selectemplate'}}</button>
|
||||
<button class="spxformtext btn bg_blue ripple"
|
||||
onClick="toggleAll();"
|
||||
id="allToggle"
|
||||
data-all-label={{lang 'general.all'}}
|
||||
data-none-label={{lang 'general.none'}}
|
||||
>{{lang 'general.all'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="display: none;" id="tab2">
|
||||
<div class="promoBox">
|
||||
<div class="promoBoxCols">
|
||||
<div class="promoLeft">
|
||||
<div class="promoBoxHead">More graphics and plugins</div>
|
||||
<p>
|
||||
SPX Store is SPX Graphics' official Store for free and premium SPX
|
||||
templates and application extensions.</p>
|
||||
<br>
|
||||
▶ <a href="https://spxgraphics.com/store" target="store">spxgraphics.com/store</a>
|
||||
<br>
|
||||
<h2>Creative Services</h2>
|
||||
<p>
|
||||
SPX Graphics offers creative services for businesses.
|
||||
Our team of designers and developers
|
||||
can help you with your next project.
|
||||
</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li>Custom templates and Extensions</li>
|
||||
<li>Workflow development</li>
|
||||
<li>System integrations</li>
|
||||
<li>SLA and Support</li>
|
||||
</ul>
|
||||
<br>
|
||||
▶ <a href="https://spxgraphics.com/contact" target="_blank">Get in touch</a>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="promoRight">
|
||||
<img src="/img/SPXstore600_2023_240px.png" alt="SPX Store" title="SPX Store">
|
||||
<a href="/img/promo-store.png" target="_blank">
|
||||
<img src="/img/promo-store.png"
|
||||
alt="SPX Store screenshot"
|
||||
border=0>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: none;" id="tab3">
|
||||
<div class="promoBox">
|
||||
<div class="promoBoxCols">
|
||||
<div class="promoLeft">
|
||||
<div class="promoBoxHead">HTML animation tool</div>
|
||||
<p>
|
||||
Create SPX templates with a browser based animation tool.
|
||||
</p>
|
||||
<p>
|
||||
Loopic supports SPX template definition and generated templates
|
||||
are stored straight into SPX template folder, so you can go
|
||||
on-air instantly.
|
||||
</p>
|
||||
<br>
|
||||
▶ <a href="https://app.loopic.io" target="loopic">Start Loopic</a>
|
||||
<br>
|
||||
<br>
|
||||
<p>
|
||||
Resources:<br>
|
||||
▶ <a href="https://docs.loopic.io/user-guide" target="ldocs">User Guide</a><br>
|
||||
▶ <a href="https://docs.spxgraphics.com/Guides/Tutorials/How+to+create+HTML+graphics+using+Loopic" target="ldocs">SPX templates using Loopic</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="promoRight">
|
||||
|
||||
<img src="/img/LoopicLogov2White.svg" alt="Loopic logo">
|
||||
<br><br>
|
||||
<a href="/img/LoopicSPXScreenshot.png" target="_blank">
|
||||
<img src="/img/LoopicSPXScreenshot.png"
|
||||
alt="Loopic screenshot"
|
||||
border=0>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: none;" id="tab4">
|
||||
<div class="promoBox">
|
||||
<div class="promoBoxCols">
|
||||
<div class="promoLeft">
|
||||
<div class="promoBoxHead">SPX templates from After Effects</div>
|
||||
<p>
|
||||
StreamShapers' Ferryman enables graphic designers to transform their creative
|
||||
ideas from animated Lottie files from Adobe After Effects into dynamic HTML templates
|
||||
without any need for HTML, CSS, or JavaScript development.
|
||||
</p>
|
||||
<p>
|
||||
Ferryman supports SPX template definition, allowing the generated templates to be
|
||||
seamlessly integrated into SPX for instant playback!</p>
|
||||
<br>
|
||||
▶ <a href="https://www.ferryman.streamshapers.com/" target="ferryman">ferryman.streamshapers.com</a>
|
||||
<br>
|
||||
<br>
|
||||
<p>
|
||||
Resources<br>
|
||||
▶ <a href="https://www.streamshapers.com/docs/streamshapers-converter/tutorial" target="fdocs">Ferryman tutorial</a><br>
|
||||
▶ <a href="https://docs.spxgraphics.com/Guides/Tutorials/How+to+create+HTML+graphics+in+After+Effects" target="fdocs">SPX templates using Ferryman</a>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
</div>
|
||||
<div class="promoRight">
|
||||
<img src="/img/promo-converter-logo.png" alt="StreamShapers logo">
|
||||
<br><br>
|
||||
<a href="/img/snap-ferryman.png" target="_blank">
|
||||
<img src="/img/snap-ferryman.png"
|
||||
alt="Ferryman screenshot"
|
||||
border=0
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div><!-- overlay ended-->
|
||||
@@ -0,0 +1,145 @@
|
||||
<!-- This is the file browser modal overlay (used by view-showconfig) -->
|
||||
<style>
|
||||
#projectWrapper {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
border-radius: 0.4em;
|
||||
border: 0px solid #ccc;
|
||||
width: clamp(300px, 50vw, 800px);
|
||||
height: clamp(250px, 25vh, 500px);
|
||||
height: fit-content;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#projectWrapperHeaderBar {
|
||||
width: 100%;
|
||||
cursor: move;
|
||||
color: white;
|
||||
padding: 0.8em;
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: relative;
|
||||
}
|
||||
.formTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
padding: 0.5em;
|
||||
border: 0px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.formTable tr td {
|
||||
padding: 0.75em;
|
||||
vertical-align: top;
|
||||
border: 0px solid #ccc;
|
||||
}
|
||||
|
||||
.infoTD {
|
||||
width: 10%;
|
||||
text-align: left;
|
||||
padding: 1.5em 1.5em;
|
||||
font-size: 0.8em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#projectName{
|
||||
width: 100%;
|
||||
padding: 0.2em 0.5em;
|
||||
font-family: 'UI-Regular';
|
||||
font-size: 1.0em;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
accent-color: #43c748; /* Change the color of the radio button */
|
||||
height: 1.2em;
|
||||
width: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#radios {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
gap: 0.4em;
|
||||
}
|
||||
|
||||
.thisBtns {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#helpBtn {
|
||||
right: 0.5em;
|
||||
border: none;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#helpBtn:hover {
|
||||
color: #43c748;
|
||||
}
|
||||
|
||||
label{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vcenter {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// Make the DIV element draggable:
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
dragElement(document.getElementById("projectWrapper"));
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="overlay" id="projectFormOverlay">
|
||||
<div class="modal wrapper" id="projectWrapper">
|
||||
<div id="projectWrapperHeaderBar">
|
||||
<span>{{lang 'hover.addshow'}}</span>
|
||||
<button id="helpBtn" title="{{lang 'general.help'}}" onClick="help('projects');"><i class="far fa-question-circle"></i> </button>
|
||||
</div>
|
||||
<form id="projectForm">
|
||||
<table class="formTable" >
|
||||
<tr>
|
||||
<td class="infoTD vcenter">Project name</td>
|
||||
<td>
|
||||
<input type="text" class="gcinput" id="projectName" name="projectName" required placeholder="Name of the project"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="infoTD">Format</td>
|
||||
<td>
|
||||
<div id="radios">
|
||||
<div>
|
||||
<input type="radio" id="formatSPX" name="projectFormat" value="SPX" checked>
|
||||
<label for="formatSPX">SPX Template</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="formatOGRAF" name="projectFormat" value="OGRAF">
|
||||
<label for="formatOGRAF">OGraf</label>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: right;">
|
||||
<button type="button" class="thisBtns btn ripple bg_grey" id="cancelForm">{{lang 'button.cancel'}}</button>
|
||||
<button type="submit" class="thisBtns btn ripple bg_green">Create</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div><!-- overlay ended-->
|
||||
@@ -0,0 +1,70 @@
|
||||
<div id="commentRow"
|
||||
class = "commentrow row_accent0"
|
||||
ondblclick = "ToggleExpand(this);"
|
||||
onmouseover = "tip('{{lang 'hover.item'}}');">
|
||||
|
||||
<form name="comment" id="comment" method="post" action="/gc/saveItemChanges">
|
||||
|
||||
<div class="handle wide" id="commentItem" style="padding: 6px; padding-left:12px;">
|
||||
|
||||
<!-- COLLAPSED to small line-->
|
||||
<div id="Collapsed" style="position:relative;">
|
||||
<div class="vmid spxTableHeadsmall" style="text-transform:uppercase;">Rundown comment</div>
|
||||
</div>
|
||||
|
||||
<!-- EXPANDED to an editor -->
|
||||
<div id="Expanded" style="display: none;">
|
||||
<table class="wide" style="border-spacing: 2px; margin-top:2px;">
|
||||
<TR>
|
||||
<TD colspan="3" class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">
|
||||
<span>Opened comment</span>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD width="65%" class="vtop">
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr>
|
||||
<td class="aright">ftype</td>
|
||||
<td>
|
||||
<input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="textarea"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<textarea rows="8"
|
||||
name="commentContent"
|
||||
ondblclick="event.stopPropagation();"
|
||||
class="gcinput"> {{content}}</textarea><BR>
|
||||
</TD>
|
||||
|
||||
<TD class="vtop">
|
||||
<table class="wide" style="border-spacing: 5px; margin-top:0px;">
|
||||
<tr>
|
||||
<td colspan="2" class="vtop">
|
||||
<button type="button"
|
||||
onClick="saveTemplateItemChangesByElement(this.closest('.itemrow'));"
|
||||
class="wide spxFlexItem btnsmall bg_grey15 ripple"
|
||||
onmouseover="tip('{{lang 'hover.submitthis'}}');"
|
||||
>{{lang 'button.save'}} </button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Foo
|
||||
</td>
|
||||
<td>
|
||||
Bar
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TD>
|
||||
<TD class="vtop center">
|
||||
<i id="deleteLarge{{@index}}" class="l-icon far fa-trash-alt" data-spx-name="deletelarge" onClick="removeItemFromRundown(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.deletethis'}}');"></i><BR>
|
||||
</TD>
|
||||
</TR>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<!-- This is the file browser modal overlay (used by view-showconfig) -->
|
||||
<style>
|
||||
#rundownWrapper {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
border-radius: 0.4em;
|
||||
border: 0px solid #ccc;
|
||||
width: clamp(300px, 50vw, 800px);
|
||||
height: clamp(250px, 25vh, 500px);
|
||||
height: fit-content;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#rundownWrapperHeaderBar {
|
||||
width: 100%;
|
||||
cursor: move;
|
||||
color: white;
|
||||
padding: 0.8em;
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: relative;
|
||||
}
|
||||
.formTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
padding: 0.5em;
|
||||
border: 0px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.formTable tr td {
|
||||
padding: 0.75em;
|
||||
vertical-align: top;
|
||||
border: 0px solid #ccc;
|
||||
}
|
||||
|
||||
.infoTD {
|
||||
width: 10%;
|
||||
text-align: left;
|
||||
padding: 1.5em 1.5em;
|
||||
font-size: 0.8em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#rundownName{
|
||||
width: 100%;
|
||||
padding: 0.2em 0.5em;
|
||||
font-family: 'UI-Regular';
|
||||
font-size: 1.0em;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
accent-color: #43c748; /* Change the color of the radio button */
|
||||
height: 1.2em;
|
||||
width: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#radios {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
gap: 0.4em;
|
||||
}
|
||||
|
||||
.thisBtns {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#helpBtn {
|
||||
right: 0.5em;
|
||||
border: none;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#helpBtn:hover {
|
||||
color: #43c748;
|
||||
}
|
||||
|
||||
label{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vcenter {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
// Make the DIV element draggable:
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
dragElement(document.getElementById("rundownWrapper"));
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="overlay" id="rundownFormOverlay">
|
||||
<div class="modal wrapper" id="rundownWrapper">
|
||||
<div id="rundownWrapperHeaderBar">
|
||||
<span>{{lang 'hover.addrundown'}}</span>
|
||||
<button id="helpBtn" title="{{lang 'general.help'}}" onClick="help('projects');"><i class="far fa-question-circle"></i> </button>
|
||||
</div>
|
||||
<form id="rundownForm">
|
||||
<table class="formTable" >
|
||||
<tr>
|
||||
<td class="infoTD vcenter">Rundown name</td>
|
||||
<td>
|
||||
<input type="text" class="gcinput" id="rundownName" name="rundownName" required placeholder="Name of the rundown"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: right;">
|
||||
<button type="button" class="thisBtns btn ripple bg_grey" id="cancelForm">{{lang 'button.cancel'}}</button>
|
||||
<button type="submit" class="thisBtns btn ripple bg_green">{{lang 'button.addplaylist'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div><!-- overlay ended-->
|
||||
@@ -0,0 +1,50 @@
|
||||
<div id="rdOptionsCollapsible">
|
||||
<div style="padding: 1.0rem; font-size: 0.9rem;">
|
||||
|
||||
<table style="width: 100%;" cellspacing="12" border="0">
|
||||
<tr>
|
||||
<td width="20%" style="vertical-align: top;">
|
||||
<span class="spxConfigHead">Comment</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 RDoptionsText" value="{{comment}}" placeholder="Experimental feature" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20%" style="vertical-align: top;">
|
||||
<span class="spxConfigHead inlineHelp"
|
||||
onClick="help('lightmode');"
|
||||
onmouseover="tip('{{lang 'hover.help'}}');"
|
||||
>Light mode <i class="far fa-question-circle"></i></span>
|
||||
</td>
|
||||
<td class="spxConfigBody">
|
||||
Light mode is an experimental, simplified version of the rundown, with less features
|
||||
and it can be used for example on mobile devices or as a custom dock in OBS.<br>
|
||||
<button class="btn ripple bg_blue"
|
||||
style="margin-top: 0.5em; padding: 0.2em 1em;"
|
||||
onClick="openLightModePanel();"
|
||||
>Open panel</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td width="30%">
|
||||
<span class="spxConfigHead">Lock rundown from</span>
|
||||
</td>
|
||||
<td class="spxConfigHead">
|
||||
[X] Content editing [X] Sorting [X] Adding and removing
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="30%">
|
||||
<span class="spxConfigHead">Static background</span>
|
||||
</td>
|
||||
<td class="spxConfigHead">
|
||||
Dropdown [V]
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script>
|
||||
var serverAddress = 'ws://{{ getServerAddress }}';
|
||||
var socket = io(serverAddress);
|
||||
</script>
|
||||
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | {{lang 'pagetitle.admin'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<style>
|
||||
.l:link, .l:visited{color:#000000}
|
||||
.l:link:hover{color:#ffd000}
|
||||
|
||||
.login {
|
||||
width: 60%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 1em;
|
||||
transform: translate(-50%, 0%);
|
||||
padding: 0.5em;
|
||||
background-color: #414C5A;
|
||||
color: white;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body class="bg_body">
|
||||
<form name="login" id="login" method="post" action="/">
|
||||
<div class="login" style="width: 80%; border:0px solid yellow; border-radius:0.6em; padding:10px;">
|
||||
<table style="width: 100%;" cellspacing="20" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<h1 style="padding:0px; margin:0px;">SPX</h1>
|
||||
SPX Graphics Controller Admin Panel<BR><BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0.5em; background-color: #ffffff11; padding:0.4em; margin-bottom:0.7em;" cellspacing="5" border="1">
|
||||
<tr style="background-color:#00000020;">
|
||||
<td colspan="2" style="padding:0.4em;">LOG</td></tr>
|
||||
<tr>
|
||||
<td style="padding:0.4em; width:20%;" class="vtop">Last 10 logins</td>
|
||||
<td style="padding:0.4em;">
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0.5em; background-color: #ffffff11; padding:0.4em; margin-bottom:0.7em;" cellspacing="5" border="1">
|
||||
<tr style="background-color:#00000020;">
|
||||
<td colspan="2" style="padding:0.4em;">RESET</td></tr>
|
||||
<tr>
|
||||
<td style="padding:0.4em; width:20%;" class="vtop">Last 10 logins</td>
|
||||
<td style="padding:0.4em;">
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
12.12.2020 klo 12.22 - Windows<BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,340 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX API v1 Documentation</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
function toggleCheckbox() {
|
||||
const checkbox = document.getElementById("useLocalhost");
|
||||
checkbox.checked = !checkbox.checked; // Toggle the checkbox status
|
||||
localhostToggle(); // Call the existing localhostToggle function
|
||||
}
|
||||
|
||||
function localhostToggle() {
|
||||
if (document.getElementById("useLocalhost").checked) {
|
||||
ipAddess = "localhost:" + document.getElementById("currServerAddress").value.split(":")[1];
|
||||
} else {
|
||||
ipAddess = document.getElementById("currServerAddress").value;
|
||||
}
|
||||
document.querySelectorAll('.apiLink').forEach(function (el) {
|
||||
el.innerHTML = el.innerHTML.replace(/http:\/\/[^\/]+/, "http://" + ipAddess);
|
||||
let link = el.firstChild;
|
||||
link.textContent = link.textContent.replace(/http:\/\/[^\/]+/, "http://" + ipAddess);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
font-family: "UI-Regular", Arial, sans-serif;
|
||||
background-color: #e6e6e6;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-family: "UI-Bold", Arial, sans-serif;
|
||||
}
|
||||
|
||||
button:focus, .accordion-button:focus, .accordion-button:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
a,
|
||||
.text-primary {
|
||||
/* color: #295aaf !important; */
|
||||
color: rgb(46, 126, 65) !important;
|
||||
/* color: #54af3c !important; */
|
||||
}
|
||||
|
||||
a {
|
||||
transition: all 0.1s ease;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
transition: all 0.1s ease;
|
||||
color: rgb(0, 0, 0) !important;
|
||||
text-underline-offset: 6px;
|
||||
}
|
||||
|
||||
.localhost-check {
|
||||
margin-top: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
background-color: transparent;
|
||||
font-family: "UI-Regular", Arial, sans-serif;
|
||||
font-size: 1em;
|
||||
padding: 0.5em 1em;
|
||||
border: 1px solid #00000000;
|
||||
border-radius: 0.5rem;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
width: fit-content;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.localhost-check:hover {
|
||||
/* background-color: #e9ecef; */
|
||||
}
|
||||
|
||||
.localhost-check input[type="checkbox"] {
|
||||
pointer-events: none; /* Prevents direct interaction with the checkbox */
|
||||
accent-color: #295aaf;
|
||||
}
|
||||
|
||||
.spx-host-id {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
font-family: "UI-Regular", Arial, sans-serif;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.strong {
|
||||
font-family: "UI-Bold", Arial, sans-serif;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
font-family: 'UI-Regular', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.section-description {
|
||||
font-size: 1rem;
|
||||
color: rgb(33, 37, 41, 0.65) !important;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.accordion-item .accordion-button {
|
||||
border-radius: 0.5em !important;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
border-radius: 0.5em !important;
|
||||
border: 1px solid #dee2e6;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.accordion-item:not(:first-of-type) {
|
||||
border-top: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.accordion-item:not(:last-child) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.accordion-button:not(.collapsed) {
|
||||
background-color: transparent;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.message-info {
|
||||
/* border-left-color: #295aaf !important; */
|
||||
border-left-color: rgb(42, 107, 57) !important;
|
||||
/* border-left-color: #54af3c !important; */
|
||||
border-left: 8px solid rgb(42, 107, 57);
|
||||
}
|
||||
|
||||
.accordion-button {
|
||||
font-size: 1.2rem;
|
||||
padding: 1.5em 1em;
|
||||
font-weight: bold;
|
||||
font-family: "UI-Bold", Arial, sans-serif;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.api-card {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.api-card .method {
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
color: #fff;
|
||||
font-family: "UI-Bold", Arial, sans-serif;
|
||||
}
|
||||
|
||||
.api-card .method.GET {
|
||||
background-color: #295aaf;
|
||||
}
|
||||
|
||||
.api-card .method.POST {
|
||||
background-color: #e57010;
|
||||
}
|
||||
|
||||
.api-card .method.DELETE {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
.api-card .method.PUT {
|
||||
background-color: #ffc107;
|
||||
}
|
||||
|
||||
.api-card pre {
|
||||
background-color: #f8f9fa;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
font-family: "UI-Light", Arial, sans-serif;
|
||||
}
|
||||
|
||||
.api-card a {
|
||||
text-decoration: none;
|
||||
color: #007bff;
|
||||
font-size: 0.9em;
|
||||
font-family: "UI-Regular", Arial, sans-serif;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.api-card a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
footer {
|
||||
font-family: "UI-Light", Arial, sans-serif;
|
||||
}
|
||||
|
||||
.back, .back a {
|
||||
position: absolute;
|
||||
transform: translateX(-1.0em);
|
||||
font-family: 'UI-Regular', Arial, sans-serif;
|
||||
text-decoration: none;
|
||||
color: rgb(42, 107, 57);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.back:hover {
|
||||
transition: all 0.3s ease;
|
||||
transform: translateX(-1.1em);
|
||||
color: rgb(204, 135, 6) !important;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: monospace;
|
||||
background-color: hsla(214, 29%, 64%, 0.301);
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 0.1em;
|
||||
color: #000;
|
||||
font-size: 1.05em;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#titleCont {
|
||||
padding-bottom: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#restrictionCont {
|
||||
color: white;
|
||||
display: flex;
|
||||
font-size: 0.75em;
|
||||
margin-left: 1em;
|
||||
align-items: center;
|
||||
padding: 0.2em 0.8em;
|
||||
border-radius: 1000px;
|
||||
justify-content: center;
|
||||
background-color: rgba(228, 112, 16);
|
||||
text-shadow: 0 0.1em 0.2em rgba(0, 0, 0, 0.5);
|
||||
font-family: 'UI-Regular', Arial, sans-serif;
|
||||
}
|
||||
|
||||
#linkCont {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="hidden" id="currServerAddress" value="{{{getServerAddress}}}">
|
||||
<div class="container">
|
||||
<header class="mb-4">
|
||||
<h1 class="text-primary"><a class="back" href="/"><</a>SPX API v1</h1>
|
||||
<p class="text-muted">Explore the available API endpoints provided by this SPX Graphics instance. Use the expandable sections below to find the endpoints you need. See <a href="https://docs.spxgraphics.com/" target="_blank">SPX Docs</a> for an introduction to the Control API.</p>
|
||||
<small class="spx-host-id">{{license.productName}} HOST-ID: <span class="strong">{{{getHostID}}}</span></small><BR>
|
||||
<div class="localhost-check" onclick="toggleCheckbox()"><input class="checkbox" type="checkbox" id="useLocalhost" onchange="localhostToggle()"> Use "localhost" addresses in examples</div>
|
||||
</header>
|
||||
|
||||
<div class="accordion" id="apiAccordion">
|
||||
{{#each functionList.sections}}
|
||||
<div class="accordion-item message-info">
|
||||
<h2 class="accordion-header" id="heading-{{@index}}">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-{{@index}}" aria-expanded="false" aria-controls="collapse-{{@index}}">
|
||||
<span class="d-flex flex-column">
|
||||
<div id="titleCont">
|
||||
<div class="fw-bold">{{section}}</div>
|
||||
{{#if restriction}}<div id="restrictionCont"><div>{{restriction}}</div></div>{{/if}}
|
||||
</div>
|
||||
<p class="text-muted section-description">{{info}}</p>
|
||||
</span>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapse-{{@index}}" class="accordion-collapse collapse" aria-labelledby="heading-{{@index}}" data-bs-parent="#apiAccordion">
|
||||
<div class="accordion-body">
|
||||
|
||||
{{#each commands}}
|
||||
<div class="api-card">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="method {{method}}">{{method}}</span>
|
||||
<span class="badge bg-secondary">{{vers}}</span>
|
||||
</div>
|
||||
<h5 class="mt-2">
|
||||
<td class="apiLink" colspan="3">
|
||||
<div id="linkCont">
|
||||
{{#ifValue active false}}
|
||||
<div>🔒</div>
|
||||
{{/ifValue}}
|
||||
<A class="apiLink" HREF="http://{{{getServerAddress}}}{{../endpoint}}{{param}}">
|
||||
http://{{{getServerAddress}}}{{../endpoint}}{{param}}
|
||||
</A>
|
||||
</div></td>
|
||||
</h5>
|
||||
<p class="text-muted">{{{info}}}</p>
|
||||
|
||||
{{#if code}}
|
||||
<pre><code>{{myStringify code}}</code></pre>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<footer class="mt-5">
|
||||
<p class="text-center text-muted">
|
||||
Need custom development or system integration?<BR>
|
||||
<a href="https://spxgraphics.com/contact" target="_blank">Contact us</a>.<BR><BR>
|
||||
<small>© 2021- SPX Graphics</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,651 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/Sortable.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
<title>SPX | {{lang 'pagetitle.configapp'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
|
||||
<style>
|
||||
.locked {
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#locked {
|
||||
padding: 1em;
|
||||
display: block;
|
||||
font-size: 0.7em;
|
||||
text-align: center;
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: rgb(85, 3, 3);
|
||||
}
|
||||
|
||||
.soloInfo {
|
||||
color: #aaa;
|
||||
padding: 0.6em;
|
||||
border-radius: 0.4em;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: inset 0 0 0.5em rgba(0, 0, 0, 0.5);
|
||||
background-image: linear-gradient(
|
||||
178deg,
|
||||
transparent 30%,
|
||||
rgba(0, 0, 0, 0.1) 55%
|
||||
);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.soloInfo h1 {
|
||||
margin: 0;
|
||||
font-size: 0.7em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.soloInfo p {
|
||||
font-size: clamp(11px, 1vw, 20px);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<body onload="pageInit();" class="bg_body" onmouseover="tip('');">
|
||||
|
||||
{{#ifValue config.general.disableConfigUI true}}
|
||||
<div id="locked">Configuration locked by admin.</div>
|
||||
{{/ifValue}}
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
{{>header page="appconfig"}}
|
||||
</div><!-- header ended -->
|
||||
{{#ifValue config.general.disableConfigUI true}}
|
||||
<div class="content locked">
|
||||
{{else}}
|
||||
<div class="content">
|
||||
{{/ifValue}}
|
||||
<div class="centerColumn pM wrapper ">
|
||||
<div id="itemList" class="content pM scroller" style="border: 0px solid yellow;">
|
||||
|
||||
{{#if message}}
|
||||
<div class="message">{{message}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if error}}
|
||||
<div class="messagerror">{{error}}</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<form name="config" id="config" method="post">
|
||||
|
||||
<input type="hidden" name="general[username]" value="{{config.general.username}}">
|
||||
<input type="hidden" name="general[password]" value="{{config.general.password}}">
|
||||
<input type="hidden" name="general[hostname]" value="{{config.general.hostname}}">
|
||||
<input type="hidden" name="general[greeting]" value="{{config.general.greeting}}">
|
||||
<input type="hidden" name="general[showusercommapass]" value="{{config.general.showusercommapass}}">
|
||||
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td colspan="2">
|
||||
<div class="soloInfo" >
|
||||
<h1>SPX Solo</h1>
|
||||
<p>
|
||||
This SPX Solo v.{{{ShowVersion}}} is a limited version of SPX Graphics for personal use and light productions. For more advanced professional features and capabilities, consider SPX Production or SPX Broadcast.
|
||||
<a href="https://spxgraphics.com/software/#compare">Read more</a>
|
||||
</div>
|
||||
<br>
|
||||
</td>
|
||||
</TR>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.general'}} </td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('config');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="10" border="0">
|
||||
<!--
|
||||
<tr onmouseover="tip('{{lang 'hover.openbrowser'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.openchrome'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{{ OpenChromeCheck }}}
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">Config file</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="spxConfigHead">{{configfile}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.lang'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.language'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="general[langfile]">
|
||||
{{{ DropdownOptionsLANG }}}
|
||||
</select>
|
||||
<BR>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.loglevel'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.loglevel'}} *</span>
|
||||
</td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="general[loglevel]">
|
||||
<!-- error, warn, info, verbose, debug -->
|
||||
{{#ifValue config.general.loglevel "error"}}
|
||||
<option selected>error</option>
|
||||
{{else}}
|
||||
<option>error</option>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue config.general.loglevel "warn"}}
|
||||
<option selected>warn</option>
|
||||
{{else}}
|
||||
<option>warn</option>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue config.general.loglevel "info"}}
|
||||
<option selected>info</option>
|
||||
{{else}}
|
||||
<option>info</option>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue config.general.loglevel "verbose"}}
|
||||
<option selected>verbose</option>
|
||||
{{else}}
|
||||
<option>verbose</option>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue config.general.loglevel "debug"}}
|
||||
<option selected>debug</option>
|
||||
{{else}}
|
||||
<option>debug</option>
|
||||
{{/ifValue}}
|
||||
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.logfolder'}}');">
|
||||
<td>
|
||||
<span class="spxConfigHead">{{lang 'config.logfolder'}} *</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Log folder" name="general[logfolder]" value="{{config.general.logfolder}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.port'}}');">
|
||||
<td>
|
||||
<span class="spxConfigHead">{{lang 'config.serverport'}} * <i style="color:rgba(255, 166, 0, 0.472);" class="fas fa-exclamation-triangle" title="URL port must be changed after reload, otherwise this page will not load!"></i></span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="port" name="general[port]" value="{{config.general.port}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.dataroot'}}');">
|
||||
<td>
|
||||
<span class="spxConfigHead">{{lang 'config.dataroot'}} *</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Dataroot folder" name="general[dataroot]" value="{{config.general.dataroot}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.preview'}}');">
|
||||
<td class="vtop">
|
||||
<span class="spxConfigHead">{{lang 'config.preview'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="general[preview]">
|
||||
<!-- error, warn, info, verbose, debug -->
|
||||
<option value="next" disabled {{#ifValue config.general.preview "next" }}selected{{/ifValue}}>Preview next item on play</option>
|
||||
<option value="selected" {{#ifValue config.general.preview "selected"}}selected{{/ifValue}}>Preview selected item on focus</option><!-- this is the default -->
|
||||
<option value="none" {{#ifValue config.general.preview "none"}}selected{{/ifValue}}>Disable preview</option>
|
||||
</select>
|
||||
</P>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('Should local renderer play items to match the rundown state?');">
|
||||
<td class="vtop">
|
||||
<span class="spxConfigHead">Local renderer autoplay</span>
|
||||
</td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="general[autoplayLocalRenderer]">
|
||||
<option value="true" {{#ifValue config.general.autoplayLocalRenderer "true"}}selected{{/ifValue}}>Play (if saved state is playing)</option>
|
||||
<option value="false" {{#ifValue config.general.autoplayLocalRenderer "false"}}selected{{/ifValue}}>Do nothing</option>
|
||||
</select>
|
||||
</P>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.resolution'}}');">
|
||||
<td class="vtop">
|
||||
<span class="spxConfigHead">{{lang 'config.resolution'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="general[resolution]">
|
||||
{{{generateResolutionOptions config.general.resolution}}}
|
||||
</select>
|
||||
<P class="spxConfigHead" style="white-space: normal; line-height: 100%; opacity:0.5; margin-top: 0.2em; margin-bottom: 0.6em;">
|
||||
<small>
|
||||
{{lang 'config.resolutioninfo'}}
|
||||
</small>
|
||||
</P>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- external audio player is disabled:
|
||||
<tr onmouseover="tip('{{lang 'hover.dataroot'}}');">
|
||||
<td>
|
||||
<span class="spxConfigHead">{{lang 'config.audioplayer'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Audioplayer path" name="general[audioplayer]" value="{{config.general.audioplayer}}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr onmouseover="tip('{{lang 'hover.htmlfolder'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.playerflags'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Audioplayer arguments (%FILE%)" name="general[playerflags]" value="{{config.general.playerflags}}">
|
||||
</td>
|
||||
</tr>
|
||||
audio player -->
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<BR><BR>
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.webplayout'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('webplayout');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="5" border="0">
|
||||
<tr onmouseover="tip('{{lang 'hover.playouturl'}}');">
|
||||
<td width="40%">
|
||||
<a href="/renderer/" target="_player"><span style="border-bottom: 1px dashed rgb(0, 140, 255);" class="spxConfigHead">{{lang 'config.webplayurl'}} *</span></a>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" style="border: 1px dashed rgba(0, 140, 255, 0.507); background-color: #575757;" placeholder="URL for OBS / vMIX" id="rendererLink" value="">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!--
|
||||
<tr onmouseover="tip('{{lang 'hover.remoteplayouturl'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">DEMO RemoteRenderer</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" style="border: 1px dashed rgba(0, 140, 255, 0.507); background-color: #575757;" placeholder="URL for OBS / vMIX" value="remoteserver.address.com/webrenderer/index.html?gc={{{ getServerAddress }}}">
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
</table>
|
||||
|
||||
<BR><BR>
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">API</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('api');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="5" border="0">
|
||||
<tr onmouseover="tip('API Commands');">
|
||||
<td width="40%">
|
||||
<a href="/api/v1/" target="_api"><span style="border-bottom: 1px dashed rgb(0, 140, 255);" class="spxConfigHead">API endpoints</span></a>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" style="border: 1px dashed rgba(0, 140, 255, 0.507); background-color: #575757;" placeholder="List of API endpoints" id="apiLink" value="">
|
||||
</P>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<BR><BR>
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.casparcg'}} *</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('casparcg');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="5" border="0">
|
||||
|
||||
|
||||
<!-- THIS NOT NEEDED, HUH?
|
||||
<tr onmouseover="tip('{{lang 'hover.ccgtemplatepath'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.ccgtemplates'}}*</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="From casparcg.config" name="casparcg[relativeTemplateFolder]" value="{{config.casparcg.relativeTemplateFolder}}">
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
{{#each config.casparcg.servers}}
|
||||
<tr>
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">
|
||||
{{#ifValue @index 0}}
|
||||
{{lang 'config.ccgservers'}}
|
||||
{{else}}
|
||||
|
||||
{{/ifValue}}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="spxFlexContainer" style="padding:0px; margin:0px;" >
|
||||
<span class="spxConfigHead">{{@index}}</span>
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 4px 0px 0px; width:30%;" name="casparcg[servers][{{@index}}][name]" onmouseover="tip('{{lang 'hover.ccgserver'}}');" placeholder="Server name" value="{{name}}">
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 4px 0px 0px; width:30%;" name="casparcg[servers][{{@index}}][host]" onmouseover="tip('{{lang 'hover.ccghost'}}');" placeholder="ip" value="{{host}}">
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 0px 0px 0px; width:30%;" name="casparcg[servers][{{@index}}][port]" onmouseover="tip('{{lang 'hover.ccgport'}}');" placeholder="port" value="{{port}}">
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
<tr>
|
||||
<td width="40%">
|
||||
|
||||
</td>
|
||||
<td class="spxFlexContainer" style="padding:0px; margin:0px;" onmouseover="tip('{{lang 'hover.addccgserver'}}');">
|
||||
<span class="spxConfigHead">+</span>
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 0px 0px 0px; width:30%;" name="NewName" placeholder="Server name" value="">
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 0px 0px 5px; width:30%;" name="NewHost" placeholder="ip" value="">
|
||||
<input type="text" class="bg_grey15 cfg" style="margin:0px 0px 0px 5px; width:30%;" name="NewPort" placeholder="port" value="">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%">
|
||||
|
||||
</td>
|
||||
<td class="spxFlexContainer" style="padding:0px; margin:0px;" onmouseover="tip('{{lang 'hover.addccgserver'}}');">
|
||||
<P class="spxConfigHead"
|
||||
style="white-space: normal; line-height: 100%; opacity:0.5;">
|
||||
<small><br>{{lang 'config.restartinfo'}}</small>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<BR>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- /////////////// extras starts ///////////////// -->
|
||||
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.globalbuttons'}} *</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('globalextras');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- script linker -->
|
||||
<table style="width: 100%;" cellspacing="5" border="0">
|
||||
<tr onmouseover="tip('{{lang 'hover.confjsfile'}}');">
|
||||
<td width="40%">
|
||||
<span class="spxConfigHead">{{lang 'config.functionlibrary'}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="/path/in/ASSETS/filename.js" name="globalExtras[customscript]" value="{{config.globalExtras.customscript}}">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%;" cellspacing="5" border="0">
|
||||
<tr>
|
||||
<td width="40%" class="vtop">
|
||||
<span class="spxConfigHead">{{lang 'config.globalbuttons'}}</span>
|
||||
</td>
|
||||
<td><!-- button list starts -->
|
||||
|
||||
|
||||
{{#each config.globalExtras.CustomControls}}
|
||||
<!-- each extra button -->
|
||||
<div id="extra{{@index}}">
|
||||
<button class="collapsible globalCollapsible bg_grey15 row_accentExtras" type="button">{{description}}</button>
|
||||
<div class="collapsiblecontent spxConfigHead" >
|
||||
<input type="hidden" name="globalExtras[CustomControls][{{@index}}][ftype]" value="{{ftype}}">
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr onmouseover="tip('{{lang 'hover.buttontype'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontype'}}</span></td>
|
||||
<td><span class="spxConfigHead">{{ftype}}</span></td>
|
||||
</tr>
|
||||
<tr onmouseover="tip('{{lang 'hover.colors'}}');">
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.buttoncolor'}}</span></td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="globalExtras[CustomControls][{{@index}}][bgclass]">
|
||||
{{{generateButtonColorClasses bgclass}}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
{{#ifValue ftype "button"}}
|
||||
<!-- something like click here -->
|
||||
<tr onmouseover="tip('{{lang 'hover.text'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontext'}}</span></td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Caption" name="globalExtras[CustomControls][{{@index}}][text]" value="{{text}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="clickHandler()" name="globalExtras[CustomControls][{{@index}}][fcall]" value="{{fcall}}"></td>
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue ftype "selectbutton"}}
|
||||
<!-- something like choose an item here -->
|
||||
<tr onmouseover="tip('{{lang 'hover.text'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontext'}}</span></td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Caption" name="globalExtras[CustomControls][{{@index}}][text]" value="{{text}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="clickHandler()" name="globalExtras[CustomControls][{{@index}}][fcall]" value="{{fcall}}"></td>
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "togglebutton"}}
|
||||
<!-- something like turn it on or off -->
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontexts'}}</span></td>
|
||||
<td>
|
||||
<input onmouseover="tip('{{lang 'hover.text'}}');" type="text" style="width: 49%;" class="bg_grey15 cfg" placeholder="ON" name="globalExtras[CustomControls][{{@index}}][text0]" value="{{text0}}">
|
||||
<input onmouseover="tip('{{lang 'hover.text1'}}');" type="text" style="width: 49%;" class="bg_grey15 cfg" placeholder="OFF" name="globalExtras[CustomControls][{{@index}}][text1]" value="{{text1}}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="toggleHandler()" name="globalExtras[CustomControls][{{@index}}][fcall]" value="{{fcall}}"></td>
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.extradescr'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functiondescription'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="Description" name="globalExtras[CustomControls][{{@index}}][description]" value="{{description}}"></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<table class="wide" style="padding: 10px; margin-bottom:10px;">
|
||||
<tr>
|
||||
<td width="25%">
|
||||
<button type="button" onmouseover="tip('{{lang 'hover.removeglobalextra'}}');" class="wide spxFlexItem btnsmall bg_grey10 ripple black" onClick="notImplemented();">{{lang 'button.deletebutton'}}</button>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td width="25%" class="center">
|
||||
<!-- <button type="button" class="wide spxFlexItem btnsmall bg_grey10 ripple black" onClick="alert('Not implemented. Modify config.json manually.');">{{lang 'button.save'}}</button> -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</div><!--ended extra item -->
|
||||
</div><!-- extra index ended -->
|
||||
|
||||
|
||||
|
||||
<!-- //each extra button -->
|
||||
{{/each}}
|
||||
|
||||
|
||||
<div class="wide" style="text-align: center; padding:0.5rem;">
|
||||
<button type="button" class="addbtn bg_blue ripple" onmouseover="tip('{{lang 'hover.browseglobalextras'}}');" onClick="notImplemented();">+</button>
|
||||
</div>
|
||||
|
||||
</td><!-- button list ended -->
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- /////////////// extras ended ///////////////// -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<HR><!-- save / cancel buttons -->
|
||||
<center>
|
||||
<span class="spxConfigHead">* {{lang 'config.restartinfo'}}</span>
|
||||
</center>
|
||||
<BR>
|
||||
<div class="spxFlexContainer">
|
||||
<button onmouseover="tip('{{lang 'hover.saveconfig'}}');" class="wide spxFlexItem btn bg_green ripple" type="submit" form="config">{{lang 'button.save'}}</button>
|
||||
<button type="button" onmouseover="tip('{{lang 'hover.cancelconfig'}}');" class="wide spxFlexItem btn bg_red ripple" onClick="location.href='/';">{{lang 'button.cancel'}}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div><!-- itemlist ended -->
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
|
||||
|
||||
{{>footer}}
|
||||
|
||||
|
||||
</div><!-- MAINwrapper ended -->
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var RendererUrl = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '') + '/renderer/';
|
||||
document.getElementById('rendererLink').value = RendererUrl;
|
||||
|
||||
var APIUrl = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '') + '/api/v1/';
|
||||
document.getElementById('apiLink').value = APIUrl;
|
||||
|
||||
// COLLAPSIPLE HANDLERS
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("active");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.maxHeight){
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function notImplemented() {
|
||||
// request .....
|
||||
// returns .....
|
||||
// Describe the function here
|
||||
alert('Not implemented yet.\n\nPlease modify config.json manually. Read help for additional information.');
|
||||
} // NotImplemented ed
|
||||
|
||||
|
||||
|
||||
|
||||
// See spx_gc.js
|
||||
function pageInit(){
|
||||
heartbeat(203); // page identifier
|
||||
spxInit('');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | {{lang 'pagetitle.authpolicy'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<style>
|
||||
.l:link, .l:visited{color:#000000}
|
||||
.l:link:hover{color:#ffd000}
|
||||
|
||||
.login {
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
transform: translate(-50%, -40%);
|
||||
z-index: 20;
|
||||
padding: 0.3em;
|
||||
background-color: #414C5A;
|
||||
color: white;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
function validate(){
|
||||
uField = document.getElementById('user');
|
||||
pField = document.getElementById('pass');
|
||||
rField = document.getElementById('radio1');
|
||||
if (rField.checked){
|
||||
if (uField.value=="" || pField.value==""){
|
||||
alert('To use login, both username and password must be given. Please try again.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body class="bg_body">
|
||||
<form name="login" id="login" method="post" action="/saveauthpolicy" onsubmit="return validate()">
|
||||
<div>
|
||||
<div>
|
||||
<div class="login" style="border-radius:0.6em;">
|
||||
<table style="width: 100%; height:100%; border:0px solid yellow;" cellspacing="20" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
SPX Graphics Controller Config<BR><BR>
|
||||
<span class="spxInfotext">
|
||||
{{lang 'config.authpolicy'}}
|
||||
</span>
|
||||
<BR>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; border:0px solid yellow;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxInfotext" style="width: 30%;">
|
||||
<label class="radiocontainer">{{lang 'general.yes'}}
|
||||
<input type="radio" name="policy" value="1" id="radio1">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td class="vmid spxInfotext">
|
||||
<input type="text" class="wide gcinput" name="username" id="user" value="{{user}}">
|
||||
<input type="password" class="wide gcinput" name="password" id="pass" value="">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; border:0px solid yellow; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxInfotext" style="width: 30%;">
|
||||
<label class="radiocontainer">{{lang 'general.no'}}
|
||||
<input type="radio" checked="checked" name="policy" value="0">
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</td>
|
||||
<td class="vmid spxInfotext">
|
||||
{{lang 'config.authnone' }}
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; border:0px solid yellow; margin-top: 0.2em;" cellspacing="25" border="0">
|
||||
<tr>
|
||||
<td class="vmid">
|
||||
<div class="wide spxInfotext center" style="font-size: 0.55em;">
|
||||
{{lang 'config.authinfo' }}
|
||||
<BR>
|
||||
<BR>
|
||||
<input type="submit" class="spxformtext btn w50 bg_green ripple" value="{{lang 'button.save'}}" style="margin:0.0em 0em 0.4em; font-size:1.2em;">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<span style="font-size: 0.55em; opacity:0.9; color:#000000;">
|
||||
v.{{{ShowVersion}}} | <a class="l" href="https://spxgraphics.com">© 2020- SPX Graphics</a></span>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
</div><!-- MAINwrapper ended -->
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,822 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<!-- <script src="/js/Sortable.min.js"></script> Not in LIGHT -->
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/vanilla-js-tooltip.js"></script>
|
||||
<!-- <script src="/js/spx_controllerImportFunctions.js"></script> -->
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/lib/vanilla-picker.csp.min.js"></script> <!-- added in 1.1.1 -->
|
||||
<script>
|
||||
var socket = io();
|
||||
|
||||
function toggle(btn) {
|
||||
btn.classList.toggle("toggled");
|
||||
|
||||
if (btn.id == "btnPrv") {
|
||||
if ( btn.classList.contains("toggled")) {
|
||||
document.getElementById("previewBG").style.display = "block";
|
||||
document.getElementById("previewIF").src = "/renderer?preview=true";
|
||||
} else {
|
||||
document.getElementById("previewBG").style.display = "none";
|
||||
document.getElementById("previewIF").src = "/templates/empty.html";
|
||||
}
|
||||
}
|
||||
|
||||
if (btn.id == "btnRun") {
|
||||
if ( btn.classList.contains("toggled")) {
|
||||
document.getElementById("rundownElements").style.display = "block";
|
||||
} else {
|
||||
document.getElementById("rundownElements").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
if (btn.id == "btnPlu") {
|
||||
if ( btn.classList.contains("toggled")) {
|
||||
document.getElementById("controllerPluginButtons").style.display = "block";
|
||||
} else {
|
||||
document.getElementById("controllerPluginButtons").style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadRundown(element) {
|
||||
let rundown = element.value;
|
||||
let url = "/gc/" + rundown + "/light";
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<title>SPX Light | {{lang 'pagetitle.controller'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout-mini.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_accents.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/vanilla-js-tooltip.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/vanilla-picker.csp.css" >
|
||||
<link rel="stylesheet" type="text/css" href="/css/toggle2.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/toggle.css">
|
||||
|
||||
<style>
|
||||
|
||||
.headlineRow {
|
||||
display: flex;
|
||||
font-size: 1.1em;
|
||||
padding: 0.4em;
|
||||
gap: 0.3em;
|
||||
font-family: 'UI-Regular';
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.headlineRow > * {
|
||||
height:90%;
|
||||
}
|
||||
|
||||
#logo {
|
||||
border: 0px solid yellow;
|
||||
}
|
||||
|
||||
.headlineRow > button {
|
||||
font-size: 0.6em;
|
||||
padding: 0.1em 0.7em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255, 255, 255, 0.479);
|
||||
font-family: 'UI-Light';
|
||||
border: 0;
|
||||
opacity: 0.8;
|
||||
border-radius: 0.3em;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.headlineRow > button:hover {
|
||||
cursor: pointer;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
|
||||
.toggled {
|
||||
border: 0 !important;
|
||||
color: #fff !important;
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
|
||||
background-color: rgba(22, 150, 22, 0.2)!important;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.25) !important;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
#previewWidthRuler {
|
||||
border: 0;
|
||||
opacity: 0 !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#footer > button {
|
||||
flex-basis: 50%;
|
||||
margin: 0.2em;
|
||||
}
|
||||
|
||||
|
||||
#rundownSelector {
|
||||
flex-grow: 1;
|
||||
margin: 0.1em;
|
||||
padding: 0.1em;
|
||||
font-size: 0.9em;
|
||||
background-color: #0008;
|
||||
color: white;
|
||||
font-family: 'UI-Regular';
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#controllerPluginButtons {
|
||||
display: none;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
select option:disabled {
|
||||
color:rgb(246, 246, 243);
|
||||
font-weight:bold;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
option.optionProject {
|
||||
|
||||
font-family: 'UI-Bold';
|
||||
color: white;
|
||||
}
|
||||
|
||||
option.optionRundown {
|
||||
color: #fff !important;
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
|
||||
option.optionEmpty {
|
||||
{{!-- user-select: none;
|
||||
color: #00f !important; --}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onresize="resizePreview();" class="bg_body">
|
||||
|
||||
<input type="hidden" id="foldername" value="{{folder}}"> <!-- just the foldername "showname" -->
|
||||
<input type="hidden" id="filebasename" value="{{filebasename}}"> <!-- just the filename "listname" -->
|
||||
<input type="hidden" id="datafile" value="{{datafile}}"> <!-- full file path "C:/dataroot/showname/listname.json" -->
|
||||
<input type="hidden" id="profiledata" value="{{profiledata}}"> <!-- full contents of the "gc_list.json" profilefile as stringified json -->
|
||||
<input type="hidden" id="background" value="{{background}}"> <!-- background.png -->
|
||||
<input type="hidden" id="csvlist" value="{{csvFileList}}"> <!-- tree data from ASSETS/csv -->
|
||||
<input type="hidden" id="previewMode" value="{{previewMode}}"> <!-- previewMode (next/selected) -->
|
||||
<input type="hidden" id="assetsroot" value="{{assetsFolder}}"> <!-- used by file browser -->
|
||||
<input type="hidden" id="templaterootmassage" value="{{lang 'error.preventBrowseUp'}}">
|
||||
|
||||
<div id="messageSlider" style="opacity:0;"></div>
|
||||
|
||||
<div class="wrapper" onmouseover="tip('');">
|
||||
|
||||
<div class="headlineRow">
|
||||
|
||||
<img src="/img/spx_offline.png" style="position: absolute; display:none;" id="logo_off">
|
||||
<img src="/img/spx_online.png" style="position: absolute; display:none;" id="logo_on">
|
||||
|
||||
<a href="" onClick="loadController">
|
||||
<img src="/img/spx_online.png" id="logo">
|
||||
</a>
|
||||
|
||||
<select id="rundownSelector" onChange="loadRundown(this)">
|
||||
</select>
|
||||
<button id="btnPrv"onclick="toggle(this);" class="toggled">Preview</button>
|
||||
<button id="btnRun"onclick="toggle(this);" class="toggled">Rundown</button>
|
||||
<button id="btnPlu"onclick="toggle(this);" class="">Plugins</button>
|
||||
</div>
|
||||
|
||||
<div class="viewer">
|
||||
<HR id="previewWidthRuler"> <!-- =========================================================== -->
|
||||
<div id="previewBG"
|
||||
style="background-color: rgb(0, 0, 0);
|
||||
width:100%;
|
||||
height:27%;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
opacity:1.0;">
|
||||
<iframe
|
||||
width="{{{localPreviewSize width}}}"
|
||||
height="{{{localPreviewSize height}}}"
|
||||
id="previewIF"
|
||||
src="/renderer?preview=true"
|
||||
class="rendererMini"
|
||||
></iframe>
|
||||
</div>
|
||||
</div><!-- viewer -->
|
||||
|
||||
<div id="itemList" class="minicontent scroller">
|
||||
<div id="rundownElements">
|
||||
|
||||
{{#if filedata.templates}}
|
||||
<!-- // -->
|
||||
{{else}}
|
||||
<div style="margin: 3%; padding: 2%; font-size: 0.7em; background-color: rgba(0,0,0,0.2); border-radius: 1em; text-align: center; opacity: 0.5;" >
|
||||
<h2>Empty rundown</h2><BR>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<!-- RUNDOWN ITEMS aka TEMPLATES -->
|
||||
{{#each filedata.templates}}
|
||||
|
||||
{{#if DataFields}}
|
||||
|
||||
<div id="playlistitem{{@index}}"
|
||||
class = "itemrow row_accent{{uicolor}}"
|
||||
data-spx-epoch = {{itemID}}
|
||||
data-spx-index = {{@index}}
|
||||
data-spx-changed = "false"
|
||||
data-spx-onair = "{{onair}}"
|
||||
data-spx-timerid = ""
|
||||
data-spx-stepsleft = "{{steps}}"
|
||||
onClick = "focusRow(this);"
|
||||
ondblclick = "ToggleExpand(this);"
|
||||
old-ondblclick = "ToggleExpand({{@index}});"
|
||||
onmouseover = "tip('{{lang 'hover.item'}}');">
|
||||
|
||||
<form name="templates[{{@index}}]" id="form{{@index}}" method="post" action="/gc/saveItemChanges">
|
||||
<input type="hidden" name="foldername" value="{{../folder}}">
|
||||
<input type="hidden" name="listname" value="{{../filebasename}}">
|
||||
<input type="hidden" name="rundownfile" value="{{../datafile}}">
|
||||
<input type="hidden" name="TemplIndex" value="{{@index}}">
|
||||
|
||||
<div class="handle wide" id="item{{@index}}" style="padding: 6px; margin-bottom:5px; padding-left:12px; padding-bottom:12px;">
|
||||
|
||||
<!-- COLLAPSED to small line-->
|
||||
<div id="Collapsed" style="position:relative;">
|
||||
<div style="position:absolute; right:10px; z-index:50; font-size:1.5em; top:0.6em;">
|
||||
|
||||
<i id="playIcon{{@index}}" data-spx-name="icon" class="fas fa-play {{{playIconClass onair}}}"></i>
|
||||
<!-- Normal play="fas fa-play", Auto play="far fa-play-circle" -->
|
||||
</div>
|
||||
<table class="wide" style="border-spacing: 2px; margin-top: 2px;">
|
||||
<TR>
|
||||
<TD class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">
|
||||
<span><!--item {{@index}} · -->{{{ nameFromTemplatePath relpath }}}
|
||||
{{#if description}}
|
||||
<span class="delim"></span> <span style="opacity:0.5;">{{description}}</span>
|
||||
{{/if}}
|
||||
</span>
|
||||
</TD>
|
||||
<TD class="vtop aright spxTableHeadsmall">
|
||||
|
||||
<!-- hide delete in LIGHT MODE
|
||||
<i id="deleteSmall{{@index}}" data-spx-name="deletesmall" class="fas fa-times" onClick="removeItemFromRundown(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.delete'}}');"></i>
|
||||
-->
|
||||
</TD>
|
||||
</TR>
|
||||
</table>
|
||||
<div style="width:100%; " class="truncate">
|
||||
|
||||
{{{ generateCollapsedHeadline DataFields }}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EXPANDED to an editor -->
|
||||
<div id="Expanded" style="display: none;">
|
||||
<table class="wide" style="border-spacing: 2px; margin-top:2px;">
|
||||
<TR>
|
||||
<TD colspan="3" class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">
|
||||
<span>{{{nameFromTemplatePath relpath}}}</span>
|
||||
<i class="l-icon fas fa-edit" onClick="openRelpathFolder(this.closest('.itemrow'));" onmouseover="tip('{{lang 'button.edit'}}');"></i>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD width="65%" class="vtop">
|
||||
|
||||
{{#each DataFields}}
|
||||
|
||||
<!-- COMMON FIELD DATA -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">field</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][field]" value="{{field}}" ></td></tr>
|
||||
<tr><td class="aright">title</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][title]" value="{{title}}" ></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{#ifValue ftype "spacer"}}
|
||||
<br><br>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue ftype "number"}}
|
||||
<!-- "NUMBER" TYPE OF TEMPLATE FIELD (added in 1.0.7) -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="number"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<input type="number" data-tooltip="{{title}}" data-position="right center" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" value="{{value}}" placeholder="{{title}}" ondblclick="event.stopPropagation();" onkeypress="javascript:applyTextEditChanges(event,this);" class="gcinput"><BR>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "instruction"}}
|
||||
<!-- "INSTRUCTION" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="instruction"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="instruction">{{value}}</div>
|
||||
<input type="hidden" name="RundownItem[DataFields][{{@index}}][value]" value="{{value}}">
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "caption"}}
|
||||
<!-- "CAPTION" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="caption"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<span class="caption">{{value}}</span><BR>
|
||||
<input type="hidden" name="RundownItem[DataFields][{{@index}}][value]" value="{{value}}">
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "hidden"}}
|
||||
<!-- "HIDDEN" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="hidden"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<span class="caption">{{title}}<BR><BR>{{field}} value:<BR>{{value}}</span><BR>
|
||||
<input type="hidden" name="RundownItem[DataFields][{{@index}}][value]" value="{{value}}">
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "textfield"}}
|
||||
<!-- "TEXTFIELD" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="textfield"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<input type="text" data-tooltip="{{title}}" data-position="right center" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" value="{{value}}" placeholder="{{title}}" ondblclick="event.stopPropagation();" onkeypress="javascript:applyTextEditChanges(event,this);" class="gcinput"><BR>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "checkbox"}}
|
||||
<!-- "CHECKBOX" TYPE OF TEMPLATE FIELD (added in 1.0.10) -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="checkbox"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="gccheckboxdiv" style="white-space: nowrap;">
|
||||
|
||||
|
||||
|
||||
<label class="gccheckcontainer">{{title}}
|
||||
<BR>
|
||||
{{#ifValue value "1"}}
|
||||
<input type="checkbox" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" class="gccheckbox" checked>
|
||||
{{else}}
|
||||
<input type="checkbox" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" class="gccheckbox">
|
||||
{{/ifValue}}
|
||||
<span class="gccheckmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
<!--<div style="white-space: nowrap;">
|
||||
<label for="checkbox{{@index}}">{{title}}</label><br>
|
||||
</div> -->
|
||||
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "button"}}
|
||||
<!-- "BUTTON" TYPE OF TEMPLATE FIELD (added in 1.0.11) -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="button"></td></tr>
|
||||
<tr><td class="aright">fcall</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][fcall]" value="{{fcall}}"></td></tr>
|
||||
<tr><td class="aright">title</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][title]" value="{{title}}"></td></tr>
|
||||
<tr><td class="aright">descr</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][descr]" value="{{descr}}"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="gcpluginbuttondiv" style="white-space: nowrap;">
|
||||
<button type="button"
|
||||
onClick="{{fcall}}"
|
||||
class="btnsmall ripple bg_grey15"
|
||||
>{{title}}</button> <span class="gcplugindescription">{{descr}}</span>
|
||||
</div>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue ftype "filebrowser"}}
|
||||
<!-- "FILEBROWSER" TYPE OF TEMPLATE FIELD (added in 1.1.1) -->
|
||||
<div class="wide HIDE" >
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="filebrowser"></td></tr>
|
||||
<tr><td class="aright">title</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][title]" value="{{title}}"></td></tr>
|
||||
<tr><td class="aright">assetfolder</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][assetfolder]" value="{{assetfolder}}"></td></tr>
|
||||
<tr><td class="aright">extension</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][extension]" value="{{extension}}"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="gcpluginbuttondiv" style="white-space: nowrap;">
|
||||
{{title}}
|
||||
<input type="text" data-position="right center" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" value="{{value}}" placeholder="{{title}}" ondblclick="event.stopPropagation();" onkeypress="javascript:applyTextEditChanges(event,this);" class="gcinput"><BR>
|
||||
<button type="button"
|
||||
onClick="alert('{{assetfolder}} {{extension}} {{value}}')";
|
||||
class="btnsmall ripple bg_grey15"
|
||||
>Browse</button>
|
||||
</div>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "textarea"}}
|
||||
<!-- "TEXTAREA" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="textarea"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<textarea rows="8" data-tooltip="{{title}}" data-position="right center" name="RundownItem[DataFields][{{@index}}][value]" data-update="{{field}}" data-role="userEditable" ondblclick="event.stopPropagation();" class="gcinput">{{injectNewlines value}}</textarea><BR>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "dropdown"}}
|
||||
<!-- "DROPDOWN" TYPE OF TEMPLATE FIELD -->
|
||||
<!-- first, hidden fields -->
|
||||
<table class="HIDE wide brd spxTableHeadsmall">
|
||||
<tr><td class="aright">fType</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="dropdown"><BR><BR></td></tr>
|
||||
</table>
|
||||
<!-- then visible DOM elements -->
|
||||
<select data-update="{{field}}" data-role="userEditable" class="gcinput select" name="DropdownValues[{{field}}]" data-tooltip="{{title}}" data-position="right center">
|
||||
<option disabled>{{title}}:</option>
|
||||
{{#each items}}
|
||||
{{#ifValue value ../value}}
|
||||
<option selected value="{{value}}">{{text}}</option>
|
||||
{{else}}
|
||||
<option value="{{value}}">{{text}}</option>
|
||||
{{/ifValue}}
|
||||
{{/each}}
|
||||
</select>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "filelist"}}
|
||||
<!-- "FILELIST" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="textfield"></td></tr>
|
||||
<tr><td class="aright">assetfolder</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][assetfolder]" value="{{assetfolder}}"></td></tr>
|
||||
<tr><td class="aright">extension</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][extension]" value="{{extension}}"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- then render visible DOM elements with a helper-->
|
||||
<!-- value set as fField value {{value}} -->
|
||||
<select data-update="{{field}}" data-role="userEditable" class="gcinput select" name="FilelistValues[{{field}}]" data-tooltip="{{title}} {{lang 'general.fromFolder'}}: {{assetfolder}}" data-position="right center">
|
||||
<option disabled>{{title}} {{lang 'general.fromFolder'}}:</option>
|
||||
<option disabled>{{assetfolder}}</option>
|
||||
<option disabled></option>
|
||||
<option value="none">-</option>
|
||||
{{{ PopulateFilelistOptions assetfolder extension value ../relpath }}}
|
||||
</select>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "divider"}}
|
||||
<!-- "DIVIDER" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="divider"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="divider">{{title}}</div>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "color"}}
|
||||
<!-- "COLOR PICKER" TYPE OF TEMPLATE FIELD -->
|
||||
<div class="colorRoot">
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">ftype</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][ftype]" value="color"></td></tr>
|
||||
<tr><td class="aright">value</td> <td><input type="text" class="wide" name="RundownItem[DataFields][{{@index}}][value]" id="colorvalue" value="{{value}}" data-role="userEditable" data-update="{{field}}"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="gcpluginbuttondiv wide" style="white-space: nowrap; position:relative;">
|
||||
<span class="gcplugindescription">{{title}}</span>
|
||||
<!--see handler at the bottom of file -->
|
||||
<button type="button"
|
||||
onClick="colorPicker(this,'{{value}}')";
|
||||
class="colorbtnsmall ripple"
|
||||
style="background-color: {{value}}; right:0;">{{value}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/ifValue}}
|
||||
{{/each}} <!-- ftype check ended -->
|
||||
|
||||
|
||||
|
||||
|
||||
</TD>
|
||||
|
||||
|
||||
|
||||
<TD class="vtop">
|
||||
<table class="wide" style="border-spacing: 5px; margin-top:0px;">
|
||||
<tr>
|
||||
<td colspan="2" class="vtop">
|
||||
<!-- SAVE CHANGES BUTTON -->
|
||||
<!-- onClick="saveTemplateItemChanges({{@index}});" -->
|
||||
|
||||
<button type="button"
|
||||
onClick="saveTemplateItemChangesByElement(this.closest('.itemrow'));"
|
||||
class="wide spxFlexItem btnsmall bg_grey15 ripple"
|
||||
onmouseover="tip('{{lang 'hover.submitthis'}}');"
|
||||
>{{lang 'button.save'}} </button><!-- FORM SUBMIT MODEL -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<!-- PLAY BUTTON -->
|
||||
<button type="button"
|
||||
style="display: none;"
|
||||
onClick="playItem(this.closest('.itemrow'));"
|
||||
id="tplay{{@index}}"
|
||||
class="wide spxFlexItem btnsmall ripple {{{playButtonClass onair}}}"
|
||||
data-spx-stoptext="{{lang 'button.stop'}}"
|
||||
data-spx-playtext="{{lang 'button.play'}}"
|
||||
data-spx-name="playbutton"
|
||||
onmouseover="tip('{{lang 'hover.playthis'}}');"
|
||||
>{{{playButtonText onair}}}</button>
|
||||
</td>
|
||||
<td>
|
||||
<!-- UPDATE BUTTON -->
|
||||
<button type="button"
|
||||
onClick="updateItem(this.closest('.itemrow'));"
|
||||
class="wide spxFlexItem btnsmall bg_blue ripple disabled"
|
||||
data-spx-name="updatebutton"
|
||||
onmouseover="tip('{{lang 'hover.updatethis'}}');"
|
||||
>{{lang 'button.update'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TD>
|
||||
<!-- Not in LIGHT MODE
|
||||
<TD class="vtop center">
|
||||
<i id="deleteLarge{{@index}}" class="l-icon far fa-trash-alt" data-spx-name="deletelarge" onClick="removeItemFromRundown(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.deletethis'}}');"></i><BR>
|
||||
<i id="duplicLarge{{@index}}" class="l-icon far fa-clone" onClick="duplicateRundownItem(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.duplicateitem'}}');"></i><BR>
|
||||
<i id="exportCSV{{@index}}" class="l-icon fas fa-file-export" onClick="exportItemAsCSV(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.exportitem'}}');"></i><BR>
|
||||
<i id="importCSV{{@index}}" class="l-icon fas fa-file-import" onClick="appendItemsFromCSV();" onmouseover="tip('{{lang 'hover.importitems'}}');"></i>
|
||||
</TD>
|
||||
-->
|
||||
</TR>
|
||||
<TR>
|
||||
<TD colspan="2" class="aright spxTableHeadsmall">
|
||||
{{{GeneratePlayoutInfo playserver playchannel playlayer webplayout out itemID}}}
|
||||
</TD>
|
||||
<TD>
|
||||
|
||||
</TD>
|
||||
</TR>
|
||||
</table>
|
||||
<div class="wide HIDE">
|
||||
<table class="wide spxTableHeadsmall">
|
||||
<tr><td class="aright">relpath</td> <td><input style="width: 100%;" type="text" id="relpath{{@index}}" name="RundownItem[relpath]" value="{{relpath}}"></td></tr>
|
||||
<tr><td class="aright">description</td> <td><input style="width: 100%;" type="text" id="description{{@index}}" name="RundownItem[description]" value="{{description}}"></td></tr>
|
||||
<tr><td class="aright">playserver</td> <td><input style="width: 100%;" type="text" id="playserver{{@index}}" name="RundownItem[playserver]" value="{{playserver}}"></td></tr>
|
||||
<tr><td class="aright">playchannel</td> <td><input style="width: 100%;" type="text" id="playchannel{{@index}}" name="RundownItem[playchannel]" value="{{playchannel}}"></td></tr>
|
||||
<tr><td class="aright">playlayer</td> <td><input style="width: 100%;" type="text" id="playlayer{{@index}}" name="RundownItem[playlayer]" value="{{playlayer}}"></td></tr>
|
||||
<tr><td class="aright">dataformat</td> <td><input style="width: 100%;" type="text" id="dataformat{{@index}}" name="RundownItem[dataformat]" value="{{dataformat}}"></td></tr>
|
||||
<tr><td class="aright">webplayout</td> <td><input style="width: 100%;" type="text" id="webplayout{{@index}}" name="RundownItem[webplayout]" value="{{webplayout}}"></td></tr>
|
||||
<tr><td class="aright">onair</td> <td><input style="width: 100%;" type="text" id="onair{{@index}}" name="RundownItem[onair]" value="{{onair}}"></td></tr>
|
||||
<tr><td class="aright">out</td> <td><input style="width: 100%;" type="text" id="out{{@index}}" name="RundownItem[out]" value="{{out}}"></td></tr>
|
||||
<tr><td class="aright">uicolor</td> <td><input style="width: 100%;" type="text" id="uicolor{{@index}}" name="RundownItem[uicolor]" value="{{uicolor}}"></td></tr>
|
||||
<tr><td class="aright">steps</td> <td><input style="width: 100%;" type="text" id="steps{{@index}}" name="RundownItem[steps]" value="{{steps}}"></td></tr>
|
||||
<tr><td class="aright">imported</td> <td><input style="width: 100%;" type="text" id="imported{{@index}}" name="RundownItem[imported]" value="{{imported}}"></td></tr>
|
||||
|
||||
<!-- special event triggers -->
|
||||
<tr><td class="aright">onPlay</td> <td><input style="width: 100%;" type="text" id="onPlay{{@index}}" name="RundownItem[function_onPlay]" value="{{function_onPlay}}"></td></tr>
|
||||
<tr><td class="aright">onNext</td> <td><input style="width: 100%;" type="text" id="onNext{{@index}}" name="RundownItem[function_onNext]" value="{{function_onNext}}"></td></tr>
|
||||
<tr><td class="aright">onStop</td> <td><input style="width: 100%;" type="text" id="onStop{{@index}}" name="RundownItem[function_onStop]" value="{{function_onStop}}"></td></tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{else}}
|
||||
<!-- object had no DataFields, so it as skipped. NULL item? -->
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
<!-- GC ITEMS ENDED -->
|
||||
|
||||
|
||||
<!-- No ADD button in LIGHT mode
|
||||
<div class="wide" style="text-align: center; padding: 0.5em 1.0em;">
|
||||
<button type="button"
|
||||
data-tooltip="{{lang 'hover.addrundownitem'}}"
|
||||
data-position="right center"
|
||||
class="addbtn bg_blue ripple"
|
||||
onClick="ModalOn('overlayTemplatePicker');"
|
||||
style="padding: 0.05em 0.75em; border-radius: 0.2em;"
|
||||
onmouseover="tip('{{lang 'hover.addrundownitem'}}');">+</button>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
<div id="controllerPluginButtons">
|
||||
|
||||
{{{ hookLoadControllerPlugins }}}
|
||||
|
||||
</div>
|
||||
|
||||
</div><!-- itemList end -->
|
||||
|
||||
<div class="footerAndInfo">
|
||||
<div id="footer">
|
||||
<button
|
||||
id="MasterTOGGLE"
|
||||
class="btn bg_green ripple disabled"
|
||||
data-spx-graphic="name_left"
|
||||
data-spx-playtext="{{lang 'button.playmaster'}}"
|
||||
data-spx-stoptext="{{lang 'button.stopmaster'}}"
|
||||
onClick="playItem();"
|
||||
onmouseover="tip('{{lang 'hover.masterplay'}}');"
|
||||
>{{lang 'button.playmaster'}}</button>
|
||||
|
||||
<button
|
||||
id="MasterCONTINUE"
|
||||
class="btn bg_green ripple disabled"
|
||||
onClick="nextItem();"
|
||||
onmouseover="tip('{{lang 'hover.mastercontinue'}}');"
|
||||
>{{lang 'button.continue'}}</button>
|
||||
</div><!-- footer end -->
|
||||
<div class="experimentalInfo">
|
||||
Light mode is an experimental feature. Please report any issues.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- wrapper end -->
|
||||
|
||||
|
||||
<script>
|
||||
// See spx_gc.js
|
||||
|
||||
// console.log('Init tooltip');
|
||||
var tooltip = new Tooltip();
|
||||
|
||||
function colorPicker(sourceButton, initialColor) {
|
||||
// Color picker
|
||||
// alert('Picker to ' + initialColor)
|
||||
sourceButton.textContent = '...';
|
||||
var picker = new Picker({
|
||||
color: initialColor,
|
||||
parent: sourceButton,
|
||||
popup: 'bottom',
|
||||
editorFormat: 'rgb'
|
||||
});
|
||||
picker.onChange = function(color) {
|
||||
sourceButton.style.backgroundColor = color.rgbaString;
|
||||
sourceButton.closest('.colorRoot').querySelector('#colorvalue').value=String(color.rgbaString);
|
||||
}
|
||||
|
||||
picker.onDone = function(color) {
|
||||
sourceButton.textContent = color.rgbaString;
|
||||
sourceButton.style.backgroundColor = color.rgbaString;
|
||||
sourceButton.closest('.colorRoot').querySelector('#colorvalue').value=String(color.rgbaString);
|
||||
};
|
||||
}
|
||||
|
||||
function pageInit() {
|
||||
// COLLAPSIPLE HANDLERS
|
||||
var coll = document.getElementsByClassName("collapsibleZone");
|
||||
var i;
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("activeZone");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.maxHeight){
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check msg from URL
|
||||
var url = new URL(window.location.href);
|
||||
var msg = url.searchParams.get("msg");
|
||||
if (msg) {
|
||||
showMessageSlider(msg) // msg, info|warn|error
|
||||
}
|
||||
|
||||
// POPULATE RUNDOWN LIST
|
||||
let projects = fetch('/api/v1/allrundowns')
|
||||
.then(response => response.json())
|
||||
.then(projects => {
|
||||
document.getElementById('rundownSelector').innerHTML = '';
|
||||
projects.forEach(function(project, index) {
|
||||
let option = document.createElement('option');
|
||||
option.value = project.project;
|
||||
option.innerHTML = project.project;
|
||||
option.disabled = true;
|
||||
option.classList.add("optionProject");
|
||||
document.getElementById('rundownSelector').appendChild(option);
|
||||
project.rundowns.forEach(function(rundown, index) {
|
||||
let rd = document.createElement('option');
|
||||
|
||||
let CurrentRD = '{{folder}}/{{filebasename}}';
|
||||
if (CurrentRD == project.project + '/' + rundown) {
|
||||
rd.selected = true;
|
||||
}
|
||||
rd.value = project.project + '/' + rundown;
|
||||
rd.innerHTML = " " + rundown;
|
||||
rd.classList.add("optionRundown");
|
||||
document.getElementById('rundownSelector').appendChild(rd);
|
||||
});
|
||||
let empty = document.createElement('option');
|
||||
empty.value = "none";
|
||||
empty.innerHTML = '';
|
||||
empty.disabled = true;
|
||||
empty.classList.add("optionEmpty");
|
||||
document.getElementById('rundownSelector').appendChild(empty);
|
||||
});
|
||||
});
|
||||
|
||||
resizePreview();
|
||||
heartbeat(212); // page identifier
|
||||
spxInit('');
|
||||
|
||||
}
|
||||
|
||||
function resizePreview() {
|
||||
|
||||
// let DefaultX = 1920 // LightMode HD by default;
|
||||
// let DefaultY = 1080 //
|
||||
// let Wpx = document.getElementById('previewWidthRuler').offsetWidth;
|
||||
// let Sca = Wpx/DefaultX;
|
||||
// let Hpx = parseInt(DefaultY * Sca);
|
||||
// document.getElementById('previewBG').style.width=Wpx+'px';
|
||||
// document.getElementById('previewBG').style.height=Hpx+'px';
|
||||
// document.getElementById('previewIF').style.transform="scale("+Sca+")";
|
||||
// Controller preview resize
|
||||
|
||||
let DefaultX = '{{width}}'; // 1920 by default;
|
||||
let DefaultY = '{{height}}'; // 1080 by default;
|
||||
|
||||
if (DefaultX.includes('vw')) {
|
||||
// Responsive settings, use window size! Added in v1.3.0
|
||||
// console.log('Responsive settings, but forcing 16:9 in Controller');
|
||||
DefaultX = '1920px';
|
||||
DefaultY = '1080px';
|
||||
}
|
||||
|
||||
let Wpx = document.getElementById('previewWidthRuler').offsetWidth;
|
||||
let Sca = Wpx/parseInt(DefaultX);
|
||||
let Hpx = parseInt(parseInt(DefaultY) * Sca);
|
||||
document.getElementById('previewBG').style.width=Wpx+'px';
|
||||
document.getElementById('previewBG').style.height=Hpx+'px';
|
||||
document.getElementById('previewIF').style.transform="scale("+Sca+")";
|
||||
document.getElementById('previewBG').style.opacity=1;
|
||||
// document.getElementById('controllerFunctionsZone').style.opacity=1;
|
||||
// console.log('Resized to ' + Wpx + ' x ' + Hpx + ' px, scale multiplier: ' + Sca);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
pageInit();
|
||||
})
|
||||
|
||||
socket.on('connect', function () {
|
||||
data={};
|
||||
data.spxcmd = 'identifyClient';
|
||||
data.name = 'SPX_CONTROLLER_MINI'; // <---- Name of this socket connection
|
||||
socket.emit('SPXMessage2Server', data);
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- empty -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Empty</title>
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function play() { emptyMessage('play') }
|
||||
function stop() { emptyMessage('stop') }
|
||||
function invoke() { emptyMessage('invoke') }
|
||||
function update() { emptyMessage('update') }
|
||||
function data() { emptyMessage('data') }
|
||||
function preview() { emptyMessage('preview') }
|
||||
function emptyMessage(cmd) {
|
||||
// console.log('Empty layer received command "' + cmd + '", which is ignored');
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- nothing here -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX{{SPX.title}} | {{lang 'pagetitle.select'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
background: rgba(255, 255, 255, 0.671);
|
||||
padding: 0.6em 1em;
|
||||
text-align: center;
|
||||
color: rgba(0, 0, 0, 0.842);
|
||||
bottom: 2px;
|
||||
left: 50px;
|
||||
font-size: 0.7em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.sb4:before {
|
||||
content: "";
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
position: absolute;
|
||||
border-right: 10px solid transparent;
|
||||
border-left: 10px solid rgba(255, 255, 255, 0.671);;
|
||||
border-top: 10px solid rgba(255, 255, 255, 0.671);;
|
||||
border-bottom: 10px solid transparent;
|
||||
left: 40px;
|
||||
bottom: -20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
{{>rundownForm}}
|
||||
|
||||
<body onload="pageInit();" class="bg_body" onmouseover="tip('');">
|
||||
|
||||
<input type="hidden" id="hidden_folder" value="{{folder}}">
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
{{>header page="episodes"}}
|
||||
</div><!-- header ended -->
|
||||
|
||||
|
||||
<div class="content">
|
||||
<div class="centerColumn pM wrapper ">
|
||||
|
||||
|
||||
<div id="itemList" class="content pM scroller" style="border: 0px solid yellow;">
|
||||
|
||||
{{#if message}}
|
||||
<div class="message">{{message}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if error}}
|
||||
<div class="messagerror">{{error}}</div>
|
||||
{{/if}}
|
||||
<div style="display: flex;">
|
||||
<div style="flex-grow: 1" class="vmidTD tableheaderText">{{lang 'headline.selectfile'}}</div>
|
||||
<div class="tableheaderHelp">
|
||||
{{#ifValue showconfig.projectFormat 'OGRAF'}}
|
||||
<a onClick="help('ograf');" onmouseenter="tip('What is OGraf?');" onmouseleave="tip('');">
|
||||
<img src="/img/ograf-logo-mono-white.svg" style="width: 5vw;">
|
||||
</a>
|
||||
{{/ifValue}}
|
||||
|
||||
</div>
|
||||
<div class="tableheaderHelp"><a title="{{lang 'general.help'}}" onClick="help('playlists');">
|
||||
<i class="far fa-question-circle"></i>
|
||||
</a></div>
|
||||
</div>
|
||||
|
||||
|
||||
{{!-- <table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'headline.selectfile'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('playlists');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table> --}}
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="10" border="0">
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<select id="lists" size=14 class="spxformtext bg_grey40"
|
||||
style="width: 100%; height:100%; color:white; border:0px; padding:0.2em; line-height:3;"
|
||||
onmouseover="tip('{{lang 'hover.epslist'}}');"
|
||||
ondblclick="cas();" autofocus>
|
||||
{{#each files}}
|
||||
<option>{{this}}</option>
|
||||
{{/each}}
|
||||
</select><BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<HR>
|
||||
|
||||
{{#if files}}
|
||||
<!-- // -->
|
||||
{{else}}
|
||||
<div class="box sb4">{{lang 'headline.createrundowntip'}}</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
<table style="width: 100%;" cellspacing="10" border="0">
|
||||
<tr>
|
||||
<td valign="top" width="50%">
|
||||
<button onmouseover="tip('{{lang 'hover.addrundown'}}');" class="spxformtext btn bg_blue ripple" style="margin:2px; width: 48%;" onClick="add('rundownFormOverlay');">{{lang 'button.addplaylist'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.duplicaterundown'}}');" class="spxformtext btn bg_blue ripple" style="margin:2px; width: 48%;" onClick="duplicateRundown();">{{lang 'button.duplicate'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.renameepisode'}}');" class="spxformtext btn bg_blue ripple" style="margin:2px; width: 48%;" onClick="renameRundown();">{{lang 'button.rename'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.deletepisode'}}');" class="spxformtext btn bg_blue ripple" style="margin:2px; width: 48%;" onClick="del();">{{lang 'button.delete'}}...</button>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<button onmouseover="tip('{{lang 'hover.openrundown'}}');" class="spxformtext btn wide bg_orange ripple" style="margin:2px;" onClick="cas();">{{lang 'button.open'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.profile'}}');" class="spxformtext btn wide bg_grey15 ripple" style="margin:2px;" onClick="cfg();"><i class="fas fa-cog"></i> {{lang 'button.settings'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</div><!-- itemlist ended -->
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
|
||||
|
||||
{{>footer}}
|
||||
</div><!-- MAINwrapper ended -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
window.onload = function () {
|
||||
document.getElementById('lists').selectedIndex = "0";
|
||||
heartbeat(208); // page identifier
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Filebrowser</title>
|
||||
|
||||
<!-- local -->
|
||||
<script src="/js/lib/luxon.min.js"></script>
|
||||
<script src="/js/lib/lodash.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_filebrowser.css">
|
||||
|
||||
<!-- from SPX -->
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/Sortable.min.js"></script>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_accents.css">
|
||||
</head>
|
||||
|
||||
<body style="background-color: #2A3641;">
|
||||
<div id="messageSlider" style="opacity:0;"></div>
|
||||
<div class="page">
|
||||
<div class="page-content">
|
||||
<div class="well darken skroll filebrowser">
|
||||
<div id="navipath">
|
||||
<!-- path generated here-->
|
||||
</div>
|
||||
<div class="filebrowser">
|
||||
<UL>
|
||||
<LI style="user-select: none;" id="homefolder" class="filebrowser_up" onDblClick="goHome();"><SPAN class="icon home"></i>ROOT</SPAN></LI>
|
||||
<LI style="user-select: none;" id="prefolder" class="filebrowser_up" onDblClick="goUp();"><SPAN class="icon back">UP</SPAN></LI>
|
||||
</UL>
|
||||
</div>
|
||||
<div id="folderinbox">
|
||||
<!-- folder items generated here -->
|
||||
</div>
|
||||
<div id="fileinbox">
|
||||
<!-- folder items generated here -->
|
||||
</div>
|
||||
<div >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-footer">
|
||||
<div class="footitem1">
|
||||
<button
|
||||
id="playButton"
|
||||
class="btn bg_grey ripple disable"
|
||||
style="width:80%; margin-bottom:0.5em;"
|
||||
onClick="playItem();">
|
||||
SELECT
|
||||
</button>
|
||||
</div>
|
||||
<div class="footitem1">
|
||||
<button
|
||||
id="stopButton"
|
||||
class="btn bg_grey ripple"
|
||||
style="width:80%; margin-bottom:0.5em;"
|
||||
onClick="stopItem();">
|
||||
CANCEL
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<script defer src="/js/spx_fileBrowser.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | {{lang 'pagetitle.home'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script>
|
||||
function website() {
|
||||
window.open('https://spxgraphics.com', '_spx');
|
||||
}
|
||||
|
||||
function start() {
|
||||
document.location = '/shows';
|
||||
}
|
||||
|
||||
function appconfig() {
|
||||
document.location = '/config';
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.auto-resizable-iframe {
|
||||
max-width: 100%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
.auto-resizable-iframe > div {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%;
|
||||
height: 0px;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.auto-resizable-iframe iframe {
|
||||
position: absolute;
|
||||
background-color: #000000;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.box {
|
||||
/* width: 150px; */
|
||||
margin-right: 10px;
|
||||
background: #00000088;
|
||||
padding: 0.6em 1em;
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.671);
|
||||
position: absolute;
|
||||
bottom: 60px;
|
||||
right: 50px;
|
||||
font-size: 0.7em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.sb4:before {
|
||||
content: "";
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
position: absolute;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid #00000088;
|
||||
border-top: 10px solid #00000088;
|
||||
border-bottom: 10px solid transparent;
|
||||
right: 19px;
|
||||
bottom: -19px;
|
||||
}
|
||||
|
||||
|
||||
#upgradeinfo, #messageinfo {
|
||||
display: block;
|
||||
margin: 2.0em 0em 1.5em 0em;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
padding: 0.8em 2.5em 1.6em 2.0em;
|
||||
border-radius: 0.5em;
|
||||
font-size: 0.8em;
|
||||
background-color: #ffffff17;
|
||||
box-shadow: rgba(0, 0, 0, 0.418) 0px 0px 10px;
|
||||
border-left: 8px solid rgba(229, 16, 16, 0)
|
||||
}
|
||||
|
||||
|
||||
.messagedate {
|
||||
color: rgba(255, 255, 255, 0.493);
|
||||
font-size: 0.8em;
|
||||
margin-top: 0.4em;
|
||||
margin-bottom: 0.0em;
|
||||
}
|
||||
|
||||
.messageheadline {
|
||||
color: #fff;
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 1.0em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.messagebody {
|
||||
font-size: 0.7;
|
||||
color: rgba(255, 255, 255, 0.685);
|
||||
}
|
||||
|
||||
#messagelink, #notificationlink{
|
||||
display: inline-block;
|
||||
margin-top: 1em;
|
||||
padding: 0.5em 1.2em;
|
||||
border-radius: 0.0em;
|
||||
font-size: 1.0em;
|
||||
background-color: #00000081;
|
||||
border-left: 4px solid #00000000;
|
||||
color: rgba(255, 255, 255, 0.76);
|
||||
}
|
||||
|
||||
#messagelink > a:link, #notificationlink > a:link {
|
||||
font-size: 1.2em;
|
||||
color: rgb(255, 255, 255);
|
||||
margin: 0.5em 1.2em;
|
||||
text-shadow: 0;
|
||||
}
|
||||
|
||||
#messagelink > a:hover, #notificationlink> a:hover{
|
||||
color: #e6dfd4;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* none | upgrade | info | warning */
|
||||
.message-upgrade { border-left-color: #e57010a6 !important; }
|
||||
.message-info { border-left-color: #106ce5b4 !important; }
|
||||
.message-warn { border-left-color: #e51010a9 !important; }
|
||||
.message-none { border-left-color: #106ce5b4 !important; }
|
||||
|
||||
.greeting {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
display: block;
|
||||
padding: 12px;
|
||||
background-color: rgba(72, 128, 212, 0.2);
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
font-size: 1.0em;
|
||||
text-shadow: rgba(0, 0, 0, 0.7) 1px 1px 4px;
|
||||
{{!-- border: 1px solid rgba(0, 0, 0, 0.384); --}}
|
||||
border-left: 8px solid rgba(0, 140, 255, 0.76);
|
||||
box-shadow: rgba(0, 0, 0, 0.267) 0px 0px 6px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body class="bg_body">
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
{{>header page="home"}}
|
||||
</div><!-- header ended -->
|
||||
|
||||
<div class="content">
|
||||
<div class="centerColumn pM wrapper ">
|
||||
<div id="itemList" class="content pM scroller" style="border: 0px solid yellow;">
|
||||
{{#if message}}
|
||||
<div class="message">{{message}}</div>
|
||||
{{/if}}
|
||||
{{#if error}}
|
||||
<div class="messagerror">{{error}}</div>
|
||||
{{/if}}
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">
|
||||
{{lang 'pagetitle.home'}}
|
||||
{{#ifValue user "default"}}
|
||||
<!--default user -->
|
||||
{{else}}
|
||||
{{user}}
|
||||
{{/ifValue}}
|
||||
</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('intro');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="10" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<img src="/img/SPX_glossy_255_Transparent_Shadow.png" style="height: 4.0em; float:right; margin-right: 1em;">
|
||||
<h1 style="padding:0px; margin:0px; font-size: 1.0em;">SPX Graphics </h1>
|
||||
<span class="spxInfotext" style="font-size: 0.8em; opacity:0.5;">
|
||||
{{lang 'general.slogan'}}<BR>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="clear:both;"> </div>
|
||||
|
||||
{{#if greeting}}
|
||||
<div class="greeting" id="greeting">{{greeting}}</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="spxFlexContainer">
|
||||
<button onmouseover="tip('{{lang 'hover.navishows'}}');" class="spxformtext btn spxFlexItem bg_orange ripple" onclick="start();">{{lang 'button.launch'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.config'}}');" class="spxformtext btn spxFlexItem bg_grey15 ripple" onclick="appconfig()"><i class="fas fa-wrench"></i> {{lang 'button.config'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.docs'}}');" class="spxformtext btn spxFlexItem bg_blue ripple" onclick="help('/')">{{lang 'button.help'}}</button>
|
||||
<button onmouseover="tip('spxgraphics.com');" class="spxformtext btn spxFlexItem bg_blue ripple" onclick="website()">website</button>
|
||||
</div>
|
||||
|
||||
<!-- Notifications from the SPX messaging service: -->
|
||||
<div class="message-upgrade" id="upgradeinfo" style="display:none">
|
||||
<div class="messagedate" id="upgrade_date"></div>
|
||||
<div class="messageheadline" id="upgrade_head"></div>
|
||||
<div class="messagebody" id="upgrade_body"></div><BR>
|
||||
<div id="notificationlink" class="message-upgrade"><span id="upgrade_call"></span><a href="" id="upgrade_link"></a></div>
|
||||
</div>
|
||||
|
||||
<div class="message-info" id="messageinfo" style="display:none">
|
||||
<div class="messagedate" id="message_date"></div>
|
||||
<div class="messageheadline" id="message_head"></div>
|
||||
<div class="messagebody" id="message_body"></div><BR>
|
||||
<div id="messagelink" class="message-info"><span id="message_call"></span><a href="" id="message_link"></a></div>
|
||||
</div>
|
||||
|
||||
<BR>
|
||||
|
||||
<!-- server / msgsrvs / notifications -->
|
||||
<div id="promo" style="opacity: 0;">
|
||||
<A id="homepagepromolink" href="https://spxgraphics.com/software" target="_mothership">
|
||||
<img id="homepagepromopict" class="auto-resizable-iframe" SRC="/img/welcome-splash-tiers.png" alt="Splash screen promo">
|
||||
</A>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
</div><!-- itemlist ended -->
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
|
||||
|
||||
{{>footer}}
|
||||
|
||||
<div class="box sb4">Questions or comments?</div>
|
||||
</div><!-- MAINwrapper ended -->
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
const css1 =
|
||||
"box-sizing: border-box;" +
|
||||
"font-size: 12px;" +
|
||||
"background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 50%, rgba(0, 0, 0, 0.3) 50%), linear-gradient(160deg, rgba(238, 255, 238, 0.5) 0%, #00aa00 20%, #112233 70%);" +
|
||||
"border-bottom: 2px solid rgba(0,0,0,0.5);" +
|
||||
"border-top: 2px solid rgba(255,255,255,0.5);" +
|
||||
"border-left: 4px solid rgba(0,0,0,0.5);" +
|
||||
"border-right: 2px solid rgba(255,255,255,0.2);" +
|
||||
"margin: 2em 0;" +
|
||||
"text-shadow: 0 2px 4px black;" +
|
||||
"font-family: Arial;" +
|
||||
"color: white;" +
|
||||
"text-align: center;" +
|
||||
"padding: 0.3em 2em;" +
|
||||
"width: 300px;" +
|
||||
"letter-spacing: 0.1em;" +
|
||||
"border-radius: 1em;";
|
||||
let YYYY = new Date().getFullYear();
|
||||
const txt1 = "%c© " + YYYY + " SPX Graphics 👋 All Rights Reserved.";
|
||||
console.log(txt1, css1);
|
||||
|
||||
// check for upgrade
|
||||
document.getElementById('upgradeBubble').style.display="none";
|
||||
heartbeat(202); // page identifier
|
||||
|
||||
{{#ifValue config.general.allowstats false}}
|
||||
console.log('No version checking.');
|
||||
{{else}}
|
||||
// console.log('stats permitted');
|
||||
getMessages('{{{curVerInfo}}}');
|
||||
{{/ifValue}}
|
||||
|
||||
// fade in promo after a little delay
|
||||
anime({
|
||||
targets: '#promo',
|
||||
easing: 'linear',
|
||||
opacity: 1,
|
||||
duration: 300,
|
||||
delay: 200
|
||||
});
|
||||
|
||||
|
||||
// show message when page loaded
|
||||
window.addEventListener('load', (event) => {
|
||||
if ('{{showMessage}}'!='') {
|
||||
hideMessageSlider();
|
||||
setTimeout(function(){
|
||||
showMessageSlider('{{showMessage}}','happy');
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
|
||||
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | {{lang 'pagetitle.login'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<style>
|
||||
.l:link, .l:visited{color:#000000}
|
||||
.l:link:hover{color:#ffd000}
|
||||
|
||||
.login {
|
||||
width: 60%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
transform: translate(-50%, -40%);
|
||||
z-index: 20;
|
||||
padding: 0.3em;
|
||||
background-color: #414C5A;
|
||||
color: white;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body class="bg_body">
|
||||
<form name="login" id="login" method="post" action="/">
|
||||
<div class="">
|
||||
<div class="contentXX">
|
||||
<div class="login" style="width: 40%; border:0px solid yellow; border-radius:0.8em;">
|
||||
<table style="width: 100%; height:100%; border:0px solid yellow;" cellspacing="20" border="0">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://spxgraphics.com" target="_blank"><img src="/img/SPX_glossy_255_Transparent_Shadow.png" style="height: 7.0em;"></a>
|
||||
{{!-- <h1 style="padding:0px; margin:0px;">SPX Graphics</h1> --}}
|
||||
<BR>
|
||||
<div class="spxTableHeadsmall" style="margin: 1em; font-size: 0.7em; opacity:0.6; line-height: 1.2em; width:80%;">
|
||||
{{lang 'general.slogan'}}<BR>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table style="width: 90%; border-radius:1em; background-color: #ffffff11;" cellspacing="25" border="1">
|
||||
{{{ShowDemoLoginInfo}}}
|
||||
<tr>
|
||||
<td class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">Username</td>
|
||||
<td ><input type="text" class="wide gcinput" name="username" autofocus value=""></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">password</td>
|
||||
<td ><input type="password" class="wide gcinput" name="password" value=""></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="vmid center">
|
||||
<div class="spxFlexContainer">
|
||||
<input type="submit" class="spxformtext btn spxFlexItem bg_blue ripple" value="Login" style="margin:0.0em 0em 0.7em;">
|
||||
{{!-- <button class="spxformtext btn spxFlexItem bg_blue ripple" onclick="github()">Github</button> --}}
|
||||
</div>
|
||||
<span style="font-size: 0.55em; opacity:0.9; color:#000000;">
|
||||
v.{{{ShowVersion}}} | <a class="l" href="https://spxgraphics.com/contact">© 2020- SPX Graphics</a></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
</div><!-- MAINwrapper ended -->
|
||||
</form>
|
||||
<!--
|
||||
|
||||
BUG! BUG! BUG!
|
||||
|
||||
If you are seeing this text in SPX terminal / console, you
|
||||
are facing a bug in action. This is not a normal behavior.
|
||||
The reason is mosty likely that SPX has been configured to
|
||||
only work when a user is logged in. If you are seeing this
|
||||
text, it means that SPX is trying to show you the login page
|
||||
but in an incorrect way.
|
||||
|
||||
This will be fixed in a future release. In the meantime,
|
||||
disable logging (remove config) and restart the server.
|
||||
|
||||
### SORRY! YOU ARE WITNESSING A BUG!! ###
|
||||
### Please read the text above here.. ###
|
||||
-->
|
||||
</body></html>
|
||||
@@ -0,0 +1,513 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | Register</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<style>
|
||||
a,
|
||||
a:visited{color:inherit}
|
||||
a:hover{color:#ff8c00}
|
||||
|
||||
.login {
|
||||
left: 50%;
|
||||
width: 60%;
|
||||
z-index: 20;
|
||||
color: white;
|
||||
padding: 0.3em;
|
||||
margin-top: 1em;
|
||||
position: absolute;
|
||||
vertical-align: top;
|
||||
transform: translateX(-50%);
|
||||
background-color: #495666;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
#email,
|
||||
#freetext {
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
#email::placeholder,
|
||||
#freetext::placeholder {
|
||||
color: #ffffff5b;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
function checkEmail(e) {
|
||||
if (e.value=='') {
|
||||
document.getElementById('newsletter').disabled=true;
|
||||
document.getElementById('inviteDiscord').disabled=true;
|
||||
document.getElementById('checks').style.opacity=0.3;
|
||||
} else {
|
||||
document.getElementById('newsletter').disabled=false;
|
||||
document.getElementById('inviteDiscord').disabled=false;
|
||||
document.getElementById('checks').style.opacity=1;
|
||||
}
|
||||
}
|
||||
|
||||
function skip() {
|
||||
msg = "Really?\n\nRegistration is an important " +
|
||||
"feedback mechanism for us to understand who is using SPX " +
|
||||
"and we would like encourage to help us by submitting some " +
|
||||
"info about you. Everything is optional. All help is highly appreciated!\n\n" +
|
||||
"Click OK to skip registration.";
|
||||
if (confirm(msg)) {
|
||||
document.location = '/';
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body class="bg_body">
|
||||
<form name="login" id="login" method="post">
|
||||
<input type="hidden" name="task" value="spxSoloAppRegistration">
|
||||
<input type="hidden" name="platform" id="platform">
|
||||
<div>
|
||||
<div class="login" style="border-radius:0.6em;">
|
||||
<table style="width: 100%; height:100%; border:0px solid yellow;" cellspacing="20" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
SPX Graphics Registration<BR><BR>
|
||||
<div class="spxInfoRegtext">
|
||||
<!--{{lang 'config.authpolicy'}} -->
|
||||
Registration is completely voluntary but helps us to keep track of the number of users
|
||||
and give some insight into the usage of SPX. This information is <b>anonymous</b> and
|
||||
<b>non-identifiable</b>. You can leave any field empty.
|
||||
<a href="https://docs.spxgraphics.com/Guides/Getting+Started/Registeration#Registration+feature">Read more about registration and related policies</a>.</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Country
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
Where are you located?
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<select class="wide drop bg_grey" name="country">
|
||||
<option value=""></option>
|
||||
<option selected value="{{config.registration.country}}">{{config.registration.country}}</option>
|
||||
<option value="" disabled></option>
|
||||
<option value="Afganistan">Afghanistan</option>
|
||||
<option value="Albania">Albania</option>
|
||||
<option value="Algeria">Algeria</option>
|
||||
<option value="American Samoa">American Samoa</option>
|
||||
<option value="Andorra">Andorra</option>
|
||||
<option value="Angola">Angola</option>
|
||||
<option value="Anguilla">Anguilla</option>
|
||||
<option value="Antigua & Barbuda">Antigua & Barbuda</option>
|
||||
<option value="Argentina">Argentina</option>
|
||||
<option value="Armenia">Armenia</option>
|
||||
<option value="Aruba">Aruba</option>
|
||||
<option value="Australia">Australia</option>
|
||||
<option value="Austria">Austria</option>
|
||||
<option value="Azerbaijan">Azerbaijan</option>
|
||||
<option value="Bahamas">Bahamas</option>
|
||||
<option value="Bahrain">Bahrain</option>
|
||||
<option value="Bangladesh">Bangladesh</option>
|
||||
<option value="Barbados">Barbados</option>
|
||||
<option value="Belarus">Belarus</option>
|
||||
<option value="Belgium">Belgium</option>
|
||||
<option value="Belize">Belize</option>
|
||||
<option value="Benin">Benin</option>
|
||||
<option value="Bermuda">Bermuda</option>
|
||||
<option value="Bhutan">Bhutan</option>
|
||||
<option value="Bolivia">Bolivia</option>
|
||||
<option value="Bonaire">Bonaire</option>
|
||||
<option value="Bosnia & Herzegovina">Bosnia & Herzegovina</option>
|
||||
<option value="Botswana">Botswana</option>
|
||||
<option value="Brazil">Brazil</option>
|
||||
<option value="British Indian Ocean Ter">British Indian Ocean Ter</option>
|
||||
<option value="Brunei">Brunei</option>
|
||||
<option value="Bulgaria">Bulgaria</option>
|
||||
<option value="Burkina Faso">Burkina Faso</option>
|
||||
<option value="Burundi">Burundi</option>
|
||||
<option value="Cambodia">Cambodia</option>
|
||||
<option value="Cameroon">Cameroon</option>
|
||||
<option value="Canada">Canada</option>
|
||||
<option value="Canary Islands">Canary Islands</option>
|
||||
<option value="Cape Verde">Cape Verde</option>
|
||||
<option value="Cayman Islands">Cayman Islands</option>
|
||||
<option value="Central African Republic">Central African Republic</option>
|
||||
<option value="Chad">Chad</option>
|
||||
<option value="Channel Islands">Channel Islands</option>
|
||||
<option value="Chile">Chile</option>
|
||||
<option value="China">China</option>
|
||||
<option value="Christmas Island">Christmas Island</option>
|
||||
<option value="Cocos Island">Cocos Island</option>
|
||||
<option value="Colombia">Colombia</option>
|
||||
<option value="Comoros">Comoros</option>
|
||||
<option value="Congo">Congo</option>
|
||||
<option value="Cook Islands">Cook Islands</option>
|
||||
<option value="Costa Rica">Costa Rica</option>
|
||||
<option value="Cote DIvoire">Cote DIvoire</option>
|
||||
<option value="Croatia">Croatia</option>
|
||||
<option value="Cuba">Cuba</option>
|
||||
<option value="Curaco">Curacao</option>
|
||||
<option value="Cyprus">Cyprus</option>
|
||||
<option value="Czech Republic">Czech Republic</option>
|
||||
<option value="Denmark">Denmark</option>
|
||||
<option value="Djibouti">Djibouti</option>
|
||||
<option value="Dominica">Dominica</option>
|
||||
<option value="Dominican Republic">Dominican Republic</option>
|
||||
<option value="East Timor">East Timor</option>
|
||||
<option value="Ecuador">Ecuador</option>
|
||||
<option value="Egypt">Egypt</option>
|
||||
<option value="El Salvador">El Salvador</option>
|
||||
<option value="Equatorial Guinea">Equatorial Guinea</option>
|
||||
<option value="Eritrea">Eritrea</option>
|
||||
<option value="Estonia">Estonia</option>
|
||||
<option value="Ethiopia">Ethiopia</option>
|
||||
<option value="Falkland Islands">Falkland Islands</option>
|
||||
<option value="Faroe Islands">Faroe Islands</option>
|
||||
<option value="Fiji">Fiji</option>
|
||||
<option value="Finland">Finland</option>
|
||||
<option value="France">France</option>
|
||||
<option value="French Guiana">French Guiana</option>
|
||||
<option value="French Polynesia">French Polynesia</option>
|
||||
<option value="French Southern Ter">French Southern Ter</option>
|
||||
<option value="Gabon">Gabon</option>
|
||||
<option value="Gambia">Gambia</option>
|
||||
<option value="Georgia">Georgia</option>
|
||||
<option value="Germany">Germany</option>
|
||||
<option value="Ghana">Ghana</option>
|
||||
<option value="Gibraltar">Gibraltar</option>
|
||||
<option value="Great Britain">Great Britain</option>
|
||||
<option value="Greece">Greece</option>
|
||||
<option value="Greenland">Greenland</option>
|
||||
<option value="Grenada">Grenada</option>
|
||||
<option value="Guadeloupe">Guadeloupe</option>
|
||||
<option value="Guam">Guam</option>
|
||||
<option value="Guatemala">Guatemala</option>
|
||||
<option value="Guinea">Guinea</option>
|
||||
<option value="Guyana">Guyana</option>
|
||||
<option value="Haiti">Haiti</option>
|
||||
<option value="Hawaii">Hawaii</option>
|
||||
<option value="Honduras">Honduras</option>
|
||||
<option value="Hong Kong">Hong Kong</option>
|
||||
<option value="Hungary">Hungary</option>
|
||||
<option value="Iceland">Iceland</option>
|
||||
<option value="Indonesia">Indonesia</option>
|
||||
<option value="India">India</option>
|
||||
<option value="Iran">Iran</option>
|
||||
<option value="Iraq">Iraq</option>
|
||||
<option value="Ireland">Ireland</option>
|
||||
<option value="Isle of Man">Isle of Man</option>
|
||||
<option value="Israel">Israel</option>
|
||||
<option value="Italy">Italy</option>
|
||||
<option value="Jamaica">Jamaica</option>
|
||||
<option value="Japan">Japan</option>
|
||||
<option value="Jordan">Jordan</option>
|
||||
<option value="Kazakhstan">Kazakhstan</option>
|
||||
<option value="Kenya">Kenya</option>
|
||||
<option value="Kiribati">Kiribati</option>
|
||||
<option value="Korea North">Korea North</option>
|
||||
<option value="Korea Sout">Korea South</option>
|
||||
<option value="Kuwait">Kuwait</option>
|
||||
<option value="Kyrgyzstan">Kyrgyzstan</option>
|
||||
<option value="Laos">Laos</option>
|
||||
<option value="Latvia">Latvia</option>
|
||||
<option value="Lebanon">Lebanon</option>
|
||||
<option value="Lesotho">Lesotho</option>
|
||||
<option value="Liberia">Liberia</option>
|
||||
<option value="Libya">Libya</option>
|
||||
<option value="Liechtenstein">Liechtenstein</option>
|
||||
<option value="Lithuania">Lithuania</option>
|
||||
<option value="Luxembourg">Luxembourg</option>
|
||||
<option value="Macau">Macau</option>
|
||||
<option value="Macedonia">Macedonia</option>
|
||||
<option value="Madagascar">Madagascar</option>
|
||||
<option value="Malaysia">Malaysia</option>
|
||||
<option value="Malawi">Malawi</option>
|
||||
<option value="Maldives">Maldives</option>
|
||||
<option value="Mali">Mali</option>
|
||||
<option value="Malta">Malta</option>
|
||||
<option value="Marshall Islands">Marshall Islands</option>
|
||||
<option value="Martinique">Martinique</option>
|
||||
<option value="Mauritania">Mauritania</option>
|
||||
<option value="Mauritius">Mauritius</option>
|
||||
<option value="Mayotte">Mayotte</option>
|
||||
<option value="Mexico">Mexico</option>
|
||||
<option value="Midway Islands">Midway Islands</option>
|
||||
<option value="Moldova">Moldova</option>
|
||||
<option value="Monaco">Monaco</option>
|
||||
<option value="Mongolia">Mongolia</option>
|
||||
<option value="Montserrat">Montserrat</option>
|
||||
<option value="Morocco">Morocco</option>
|
||||
<option value="Mozambique">Mozambique</option>
|
||||
<option value="Myanmar">Myanmar</option>
|
||||
<option value="Nambia">Nambia</option>
|
||||
<option value="Nauru">Nauru</option>
|
||||
<option value="Nepal">Nepal</option>
|
||||
<option value="Netherland Antilles">Netherland Antilles</option>
|
||||
<option value="Netherlands">Netherlands (Holland, Europe)</option>
|
||||
<option value="Nevis">Nevis</option>
|
||||
<option value="New Caledonia">New Caledonia</option>
|
||||
<option value="New Zealand">New Zealand</option>
|
||||
<option value="Nicaragua">Nicaragua</option>
|
||||
<option value="Niger">Niger</option>
|
||||
<option value="Nigeria">Nigeria</option>
|
||||
<option value="Niue">Niue</option>
|
||||
<option value="Norfolk Island">Norfolk Island</option>
|
||||
<option value="Norway">Norway</option>
|
||||
<option value="Oman">Oman</option>
|
||||
<option value="Pakistan">Pakistan</option>
|
||||
<option value="Palau Island">Palau Island</option>
|
||||
<option value="Palestine">Palestine</option>
|
||||
<option value="Panama">Panama</option>
|
||||
<option value="Papua New Guinea">Papua New Guinea</option>
|
||||
<option value="Paraguay">Paraguay</option>
|
||||
<option value="Peru">Peru</option>
|
||||
<option value="Phillipines">Philippines</option>
|
||||
<option value="Pitcairn Island">Pitcairn Island</option>
|
||||
<option value="Poland">Poland</option>
|
||||
<option value="Portugal">Portugal</option>
|
||||
<option value="Puerto Rico">Puerto Rico</option>
|
||||
<option value="Qatar">Qatar</option>
|
||||
<option value="Republic of Montenegro">Republic of Montenegro</option>
|
||||
<option value="Republic of Serbia">Republic of Serbia</option>
|
||||
<option value="Reunion">Reunion</option>
|
||||
<option value="Romania">Romania</option>
|
||||
<option value="Russia">Russia</option>
|
||||
<option value="Rwanda">Rwanda</option>
|
||||
<option value="St Barthelemy">St Barthelemy</option>
|
||||
<option value="St Eustatius">St Eustatius</option>
|
||||
<option value="St Helena">St Helena</option>
|
||||
<option value="St Kitts-Nevis">St Kitts-Nevis</option>
|
||||
<option value="St Lucia">St Lucia</option>
|
||||
<option value="St Maarten">St Maarten</option>
|
||||
<option value="St Pierre & Miquelon">St Pierre & Miquelon</option>
|
||||
<option value="St Vincent & Grenadines">St Vincent & Grenadines</option>
|
||||
<option value="Saipan">Saipan</option>
|
||||
<option value="Samoa">Samoa</option>
|
||||
<option value="Samoa American">Samoa American</option>
|
||||
<option value="San Marino">San Marino</option>
|
||||
<option value="Sao Tome & Principe">Sao Tome & Principe</option>
|
||||
<option value="Saudi Arabia">Saudi Arabia</option>
|
||||
<option value="Senegal">Senegal</option>
|
||||
<option value="Seychelles">Seychelles</option>
|
||||
<option value="Sierra Leone">Sierra Leone</option>
|
||||
<option value="Singapore">Singapore</option>
|
||||
<option value="Slovakia">Slovakia</option>
|
||||
<option value="Slovenia">Slovenia</option>
|
||||
<option value="Solomon Islands">Solomon Islands</option>
|
||||
<option value="Somalia">Somalia</option>
|
||||
<option value="South Africa">South Africa</option>
|
||||
<option value="Spain">Spain</option>
|
||||
<option value="Sri Lanka">Sri Lanka</option>
|
||||
<option value="Sudan">Sudan</option>
|
||||
<option value="Suriname">Suriname</option>
|
||||
<option value="Swaziland">Swaziland</option>
|
||||
<option value="Sweden">Sweden</option>
|
||||
<option value="Switzerland">Switzerland</option>
|
||||
<option value="Syria">Syria</option>
|
||||
<option value="Tahiti">Tahiti</option>
|
||||
<option value="Taiwan">Taiwan</option>
|
||||
<option value="Tajikistan">Tajikistan</option>
|
||||
<option value="Tanzania">Tanzania</option>
|
||||
<option value="Thailand">Thailand</option>
|
||||
<option value="Togo">Togo</option>
|
||||
<option value="Tokelau">Tokelau</option>
|
||||
<option value="Tonga">Tonga</option>
|
||||
<option value="Trinidad & Tobago">Trinidad & Tobago</option>
|
||||
<option value="Tunisia">Tunisia</option>
|
||||
<option value="Turkey">Turkey</option>
|
||||
<option value="Turkmenistan">Turkmenistan</option>
|
||||
<option value="Turks & Caicos Is">Turks & Caicos Is</option>
|
||||
<option value="Tuvalu">Tuvalu</option>
|
||||
<option value="Uganda">Uganda</option>
|
||||
<option value="United Kingdom">United Kingdom</option>
|
||||
<option value="Ukraine">Ukraine</option>
|
||||
<option value="United Arab Emirates">United Arab Emirates</option>
|
||||
<option value="United States of America">United States of America</option>
|
||||
<option value="Uraguay">Uruguay</option>
|
||||
<option value="Uzbekistan">Uzbekistan</option>
|
||||
<option value="Vanuatu">Vanuatu</option>
|
||||
<option value="Vatican City State">Vatican City State</option>
|
||||
<option value="Venezuela">Venezuela</option>
|
||||
<option value="Vietnam">Vietnam</option>
|
||||
<option value="Virgin Islands (Brit)">Virgin Islands (Brit)</option>
|
||||
<option value="Virgin Islands (USA)">Virgin Islands (USA)</option>
|
||||
<option value="Wake Island">Wake Island</option>
|
||||
<option value="Wallis & Futana Is">Wallis & Futana Is</option>
|
||||
<option value="Yemen">Yemen</option>
|
||||
<option value="Zaire">Zaire</option>
|
||||
<option value="Zambia">Zambia</option>
|
||||
<option value="Zimbabwe">Zimbabwe</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Industry
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
What is your main focus?
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<select class="wide drop bg_grey" name="indus">
|
||||
<option {{{ifValueMatch config.registration.indus "empty" "selected" ""}}} value = "empty"></option>
|
||||
<option {{{ifValueMatch config.registration.indus "broad" "selected" ""}}} value = "broad">Broadcast TV</option>
|
||||
<option {{{ifValueMatch config.registration.indus "strea" "selected" ""}}} value = "strea">Streaming</option>
|
||||
<option {{{ifValueMatch config.registration.indus "event" "selected" ""}}} value = "event">Events</option>
|
||||
<option {{{ifValueMatch config.registration.indus "educa" "selected" ""}}} value = "educa">Education</option>
|
||||
<option {{{ifValueMatch config.registration.indus "other" "selected" ""}}} value = "other">Other</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Usage
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
What is or will most likely be the main use of SPX?
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<select class="wide drop bg_grey" name="usage">
|
||||
<option {{{ifValueMatch config.registration.usage "empty" "selected" ""}}} value = "empty"></option>
|
||||
<option {{{ifValueMatch config.registration.usage "perso" "selected" ""}}} value = "perso">For personal use</option>
|
||||
<option {{{ifValueMatch config.registration.usage "nonpr" "selected" ""}}} value = "nonpr">For non-profit projects</option>
|
||||
<option {{{ifValueMatch config.registration.usage "educa" "selected" ""}}} value = "educa">For education related projects</option>
|
||||
<option {{{ifValueMatch config.registration.usage "mybus" "selected" ""}}} value = "mybus">For my own business</option>
|
||||
<option {{{ifValueMatch config.registration.usage "workb" "selected" ""}}} value = "workb">For my employer's internal projects</option>
|
||||
<option {{{ifValueMatch config.registration.usage "servi" "selected" ""}}} value = "servi">For selling production services</option>
|
||||
<option {{{ifValueMatch config.registration.usage "other" "selected" ""}}} value = "other">Other</option>
|
||||
</select>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Developer level
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
What is your (organizations's) HTML/CSS template development skill level?
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<select class="wide drop bg_grey" name="skill">
|
||||
<option {{{ifValueMatch config.registration.devlevel "empty" "selected" ""}}} value = "empty"></option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "highl" "selected" ""}}} value = "highl">Highly skilled in web development</option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "somew" "selected" ""}}} value = "somew">Some web development skills</option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "modif" "selected" ""}}} value = "modif">Can modify existing code</option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "learn" "selected" ""}}} value = "learn">Learning</option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "avoid" "selected" ""}}} value = "avoid">Trying to avoid</option>
|
||||
<option {{{ifValueMatch config.registration.devlevel "noint" "selected" ""}}} value = "noint">Not interested</option>
|
||||
</select>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Anything else?
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
If there is something you would like us to know about, feel free to add it here.
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<textarea class="wide drop bg_grey"
|
||||
style="height: 6em;"
|
||||
name="freetext"
|
||||
style=""
|
||||
placeholder="Feedback, comments, ideas, etc."
|
||||
id="freetext">{{config.registration.freetext}}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; margin-top: 0.2em;" cellspacing="15" border="0">
|
||||
<tr>
|
||||
<td class="vmid spxConfigHead wrap" style="width: 30%;">
|
||||
Email
|
||||
<div style="font-size: 0.7em; margin-top: 1em; opacity: 0.7;">
|
||||
Your email is never shared with any third parties
|
||||
add you will not be spammed by us either.
|
||||
</div>
|
||||
</td>
|
||||
<td class="vmid">
|
||||
<input type="text" class="wide drop bg_grey"
|
||||
placeholder="name@inter.net"
|
||||
name="email" id="email" value="{{config.registration.email}}" oninput="checkEmail(this)">
|
||||
<div style="font-size: 0.6em; margin-top: 1em; opacity: 0.5;">
|
||||
<div id="checks">
|
||||
<input {{{ifValueMatch config.registration.newsletter true "checked" ""}}}
|
||||
type="checkbox"
|
||||
name="newsletter"
|
||||
id="newsletter"
|
||||
style="transform: scale(1.5);"
|
||||
> Join SPX newsletter (max 4 messages/year)
|
||||
<BR>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table style="width: 100%; border-radius:0em; background-color: #0000003a; border:0px solid yellow; margin-top: 0.2em;" cellspacing="25" border="0">
|
||||
<tr>
|
||||
<td class="vmid">
|
||||
<div class="wide spxInfotext center" style="font-size: 0.55em;">
|
||||
This information is stored in <i>config.json</i> and if removed a menu item appears again.
|
||||
<BR>
|
||||
<BR>
|
||||
<input type="submit" class="spxformtext btn w50 bg_green ripple" value="Submit" style="margin:0.0em 0em 0.4em; font-size:1.2em;">
|
||||
<br>
|
||||
<div style="text-align: center; opacity: 0.4; margin-top: 1em; font-size: 0.8em;">
|
||||
<a href="#" onClick="skip();">Skip registration</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<span style="font-size: 0.55em; opacity:0.9; color:#000000;">
|
||||
v.{{{ShowVersion}}} | <a href="https://spxgraphics.com">© 2020- SPX Graphics</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,616 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!-- DO NOT MODIFY THIS FILE -->
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
|
||||
<!-- SPX GRAPHICS CONTROLLER -->
|
||||
<!-- ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ -->
|
||||
<!-- (c) 2020- SPX Graphics -->
|
||||
<!-- http://spxgraphics.com -->
|
||||
<!-- -->
|
||||
<!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
|
||||
|
||||
<!--
|
||||
Scripts, no frameworks.
|
||||
"Some extract of vanilla, enough to feed Godzilla."
|
||||
-->
|
||||
|
||||
<script src="./js/socket.io.js"></script>
|
||||
<script src="/js/lib/dotlottie-player.js"></script>
|
||||
<script src="/js/spx_rendererUtils.js" type="module"></script> <!-- added in 1.3.3 RC-->
|
||||
<script src="/js/ograf_functions.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
<title>SPX Renderer</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0px;
|
||||
background-color: transparent;
|
||||
background-color: rgba(0,0,0,0);
|
||||
color: black;
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
#root {
|
||||
padding: 0px;
|
||||
/* MAIN RENDERER size set by SPX to {{width}}x{{height}} */
|
||||
width: {{width}};
|
||||
height: {{height}};
|
||||
position: relative;
|
||||
border: 0px dashed red;
|
||||
background-size: 100% 100%;
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
#overlays {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
position: absolute;
|
||||
border: 0px solid red;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.frame {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
position: absolute;
|
||||
border: 0px solid red;
|
||||
}
|
||||
|
||||
.ografRenderTarget > iframe,
|
||||
.ografRenderTarget {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
border: 0px dashed green;
|
||||
}
|
||||
|
||||
.debugMessage{
|
||||
top: 5%;
|
||||
left: 10%;
|
||||
opacity: 0.0;
|
||||
z-index: 500;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
padding: 0.1em 0.5em;
|
||||
display: inline-block;
|
||||
color: rgb(3, 42, 3);
|
||||
transform: rotate(1deg);
|
||||
border: 1px solid green;
|
||||
background-color: rgba(205, 255, 218, 0.85);
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
|
||||
#cursorHider {
|
||||
z-index: 200;
|
||||
background-color: rgba(0,0,0,0.0);
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
#wm {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
position: absolute;
|
||||
border: 0px dashed red;
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Renderer info to console
|
||||
console.log('RENDERER: ' + navigator?.userAgent);
|
||||
|
||||
// Renderer info to console
|
||||
console.log('RENDERER: ' + navigator?.userAgent);
|
||||
|
||||
let incomingData; // a placeholder for templateData
|
||||
let WMtimer = null;
|
||||
let startTime = new Date().getTime();
|
||||
|
||||
function setTarget(LayerNro, projectFormat) {
|
||||
if (projectFormat === "OGRAF") {
|
||||
return 'div' + LayerNro;
|
||||
} else {
|
||||
return 'layer' + LayerNro;
|
||||
}
|
||||
}
|
||||
|
||||
function allowLayerControl(LayerNro) {
|
||||
let playMode = incomingData.playmode || 'notFoundSoMustBeProgramCommand' ;
|
||||
if ( isPreviewMode() && playMode != 'preview') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !isPreviewMode() && playMode == 'preview') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const limitLayers = urlParams.get('layers');
|
||||
LayerNro = Math.min(parseInt(LayerNro), 5);
|
||||
if (limitLayers) {
|
||||
let allowedLayers = JSON.parse(limitLayers);
|
||||
if ( allowedLayers.includes(LayerNro) ) {
|
||||
return true;
|
||||
} else {
|
||||
console.log('Layer ' + LayerNro + ' blocked, allows ', allowedLayers);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function validateLayerNro(LayerNro) {
|
||||
if (!allowLayerControl(LayerNro)) { return false }
|
||||
|
||||
if ( isPreviewMode() ) {
|
||||
return 1
|
||||
} else {
|
||||
// console.log('Validating LayerNro ' + LayerNro); // debug
|
||||
return Math.min(parseInt(LayerNro),5);
|
||||
}
|
||||
}
|
||||
|
||||
function isPreviewMode() {
|
||||
const url = new URL(window.location.href);
|
||||
let previewFlag = url.searchParams.get('preview') || '';
|
||||
let previewPage = url.pathname || '';
|
||||
if ( previewFlag == 'true' || previewPage.includes('preview') ) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isLocalRenderer() {
|
||||
if (this.name == 'LOCAL') {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function clearLayer(LayerNro){
|
||||
let ValidatedLayerNro = validateLayerNro(LayerNro);
|
||||
|
||||
// v1.1.4 allow clearing of all layers (even restricted ones)
|
||||
if (!ValidatedLayerNro) {
|
||||
ValidatedLayerNro = LayerNro
|
||||
}
|
||||
populateLayer(ValidatedLayerNro,'',true); // clear layer forcefully
|
||||
}
|
||||
|
||||
function echo(msg) {
|
||||
document.getElementById('debugMessage').innerText=msg;
|
||||
}
|
||||
|
||||
function spxWM(mode=0,ref=0, minMins=15, maxMins=30) {
|
||||
clearTimeout(WMtimer);
|
||||
WMtimer = null;
|
||||
let MODES = ['init','wait', 'play','stop', 'force'];
|
||||
const player = document.getElementById('wm');
|
||||
let file = '/img/json/wm-' + ref + '.json';
|
||||
let fadeOutAfter = 8000; // Anim duration
|
||||
|
||||
switch (MODES[mode]) {
|
||||
case 'init':
|
||||
console.log('0: spxWM init');
|
||||
player.style.opacity=0;
|
||||
player.load(file);
|
||||
spxWM(1,ref, minMins, maxMins);
|
||||
return;
|
||||
break;
|
||||
|
||||
case 'wait':
|
||||
// DEBUG #######
|
||||
// minMins = 0.2
|
||||
// maxMins = 0.5
|
||||
// #############
|
||||
let minMS = (parseFloat(minMins) * 60 * 1000); // default 15 min
|
||||
let maxMS = (parseFloat(maxMins) * 60 * 1000); // default 30 min
|
||||
minMS = Math.max(minMS, fadeOutAfter+500)
|
||||
let rnd = Math.floor(Math.random() * maxMS) + minMS;
|
||||
console.log('1: spxWM delay sec', (rnd/1000));
|
||||
WMtimer = setTimeout(function () {
|
||||
spxWM(2,ref, minMins, maxMins);
|
||||
}, rnd);
|
||||
return;
|
||||
break;
|
||||
|
||||
case 'play':
|
||||
console.log('2: spxWM play');
|
||||
player.style.opacity=1;
|
||||
player.seek(0);
|
||||
player.play();
|
||||
spxWM(1,ref, minMins, maxMins);
|
||||
setTimeout(function () {
|
||||
player.style.opacity=0;
|
||||
}, fadeOutAfter);
|
||||
break;
|
||||
|
||||
case 'stop':
|
||||
console.log('3: spxWM stop');
|
||||
clearTimeout(WMtimer);
|
||||
WMtimer = null;
|
||||
player.stop();
|
||||
player.style.opacity=0;
|
||||
break;
|
||||
|
||||
case 'force':
|
||||
console.log('4: force play wm');
|
||||
player.load(file);
|
||||
setTimeout(function () {
|
||||
player.seek(0);
|
||||
player.style.opacity=1;
|
||||
player.play();
|
||||
}, 200);
|
||||
setTimeout(function () {
|
||||
player.style.opacity=0;
|
||||
if (WMtimer) {
|
||||
clearTimeout(WMtimer);
|
||||
spxWM(1,ref);
|
||||
} else {
|
||||
clearTimeout(WMtimer);
|
||||
WMtimer = null;
|
||||
}
|
||||
}, fadeOutAfter*1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function protocolCheck() {
|
||||
// check if we are http or file.
|
||||
let protocol = location.protocol;
|
||||
if (protocol != "http:" && protocol != "https:") {
|
||||
alert('Please use this via server! Functions and CORS may not work when used as a file. (Current protocol: ' + protocol + ')');
|
||||
}
|
||||
}
|
||||
|
||||
function remoteFunction(LayerNro, functionName, arg) {
|
||||
LayerNro = validateLayerNro(LayerNro);
|
||||
if (!LayerNro) { return }
|
||||
let iframe = 'layer' + LayerNro;
|
||||
document.getElementById(iframe).contentWindow.echo(arg);
|
||||
}
|
||||
|
||||
function populateLayer(LayerNro,TemplateFileRef='', forced=false) {
|
||||
let projectFormat = incomingData.projectFormat || 'SPX'; // default value
|
||||
if (!forced) {
|
||||
LayerNro = validateLayerNro(LayerNro);
|
||||
if (!LayerNro) { return }
|
||||
}
|
||||
let renderTarget = setTarget(LayerNro, projectFormat);
|
||||
let templa = '';
|
||||
|
||||
if (TemplateFileRef!='') {
|
||||
templa = TemplateRoot + TemplateFileRef;
|
||||
} else {
|
||||
templa = TemplateRoot + 'empty.html';
|
||||
}
|
||||
|
||||
templa = templa.replace(/\/\//g, "/");
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
let customParams = '';
|
||||
for(let param of urlParams) {
|
||||
customParams += '&' + param[0] + '=' + param[1];
|
||||
}
|
||||
let ranNro = (new Date()).getTime() + Math.floor(Math.random() * 1000000);
|
||||
document.getElementById(renderTarget).src=templa + "?random=" + ranNro + customParams;
|
||||
}
|
||||
|
||||
function playLayer(LayerNro,fieldData, projectFormat = 'SPX', incomingData) {
|
||||
LayerNro = validateLayerNro(LayerNro);
|
||||
if (!LayerNro) { return }
|
||||
let renderTarget = setTarget(LayerNro, projectFormat)
|
||||
let formattedJSON = formatJSONAndSetDomFields(fieldData, renderTarget);
|
||||
let manifestPath = incomingData.relpath;
|
||||
if (projectFormat === "OGRAF") {
|
||||
loadTheGraphic("/templates" + manifestPath, renderTarget, incomingData);
|
||||
} else {
|
||||
document.getElementById(renderTarget).contentWindow?.update(formattedJSON);
|
||||
document.getElementById(renderTarget).contentWindow?.play();
|
||||
}
|
||||
}
|
||||
|
||||
async function updateLayer(LayerNro,fieldData, projectFormat = "SPX") {
|
||||
LayerNro = validateLayerNro(LayerNro);
|
||||
if (!LayerNro) { return }
|
||||
let renderTarget = setTarget(LayerNro, projectFormat)
|
||||
let formattedJSON = formatJSONAndSetDomFields(fieldData, renderTarget);
|
||||
if (projectFormat === "OGRAF") {
|
||||
updateItem()
|
||||
} else {
|
||||
document.getElementById(renderTarget).contentWindow?.update(formattedJSON);
|
||||
}
|
||||
}
|
||||
|
||||
function formatJSONAndSetDomFields(fieldData, iframeID) {
|
||||
let formattedJsonOut = {};
|
||||
if (fieldData) {
|
||||
var keys = [];
|
||||
for (var k in fieldData) keys.push(k);
|
||||
fieldData.forEach((item,index) => {
|
||||
let KEY = Object.keys(item)[0];
|
||||
let VAL = fieldData[index][Object.keys(item)[0]]
|
||||
formattedJsonOut[KEY]=VAL;
|
||||
});
|
||||
return JSON.stringify(formattedJsonOut)
|
||||
}
|
||||
}
|
||||
|
||||
function stopLayer(LayerNro, projectFormat = "SPX") {
|
||||
if (!allowLayerControl(LayerNro)) return; // check layer param
|
||||
LayerNro = validateLayerNro(LayerNro);
|
||||
let renderTarget = setTarget(LayerNro, projectFormat)
|
||||
if (projectFormat === "OGRAF") {
|
||||
graphicInstances[renderTarget]?.stopAction({})
|
||||
} else {
|
||||
document.getElementById(renderTarget).contentWindow?.stop();
|
||||
}
|
||||
}
|
||||
|
||||
var url_string = window.location.href;
|
||||
var url = new URL(url_string);
|
||||
let TemplateRoot;
|
||||
var GCserver = url.searchParams.get("gc") || undefined;
|
||||
if (GCserver==undefined) {
|
||||
TemplateRoot = "/templates/";
|
||||
var socket = io();
|
||||
} else {
|
||||
TemplateRoot = "templates/";
|
||||
var socket = io(GCserver);
|
||||
}
|
||||
|
||||
socket.on('connect', function () {
|
||||
data={};
|
||||
data.name = 'SPX_RENDERER'; // <---- Name of this socket connection
|
||||
data.spxcmd = 'identifyClient';
|
||||
socket.emit('SPXMessage2Server', data);
|
||||
});
|
||||
|
||||
socket.on('SPXMessage2Client', function (data) {
|
||||
incomingData = data;
|
||||
let LayerNro;
|
||||
let projectFormat = ""
|
||||
let customCommand = ""
|
||||
switch (data.spxcmd) {
|
||||
case 'reloadRendererWithLayers':
|
||||
let currURL = window.location.href;
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
let userName = urlParams.get('name') || 'NO_NAME';
|
||||
let nameMatch = (userName.toUpperCase() === data?.name?.toUpperCase());
|
||||
if (urlParams.get('remote')=='true' && nameMatch) {
|
||||
let baseURL = currURL.split('?')[0];
|
||||
let layerList = "[" + data.layers.join(',') + "]";
|
||||
if (data?.layers?.length>0 ) {
|
||||
window.location.href = baseURL + '?layers=' + layerList + '&remote=true&name=' + userName;
|
||||
} else {
|
||||
window.location.href = baseURL + '?remote=true&name=' + userName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'clearAllLayers':
|
||||
spxWM(3);
|
||||
document.getElementById('root').style.opacity=0;
|
||||
document.querySelectorAll('.htmlFrame').forEach(function(frame,index) {
|
||||
LayerNro = (index+1);
|
||||
clearLayer(LayerNro,'');
|
||||
});
|
||||
|
||||
document.querySelectorAll('.ografFrame').forEach(function(frame,index) {
|
||||
LayerNro = (index+1);
|
||||
frame.innerHTML = '';
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('root').style.opacity=1;
|
||||
}, 200);
|
||||
break;
|
||||
|
||||
case 'clearLayer':
|
||||
clearLayer(data.layerno);
|
||||
break;
|
||||
|
||||
case 'loadTemplate':
|
||||
populateLayer(data.webplayout,data.relpath);
|
||||
break;
|
||||
|
||||
case 'forceWM':
|
||||
spxWM(4);
|
||||
break;
|
||||
|
||||
case 'playTemplate':
|
||||
projectFormat = incomingData.projectFormat || 'SPX';
|
||||
if (data.modify && data.modify==='autoPlayLocal' ) {
|
||||
if (!isLocalRenderer()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LayerNro = validateLayerNro(data.webplayout);
|
||||
if (!LayerNro) { return }
|
||||
if (projectFormat === "OGRAF") {
|
||||
playLayer(LayerNro, data.fields, projectFormat, incomingData);
|
||||
}else {
|
||||
document.getElementById('layer' + LayerNro).onload = function() {
|
||||
playLayer(LayerNro, data.fields, projectFormat, incomingData);
|
||||
};
|
||||
}
|
||||
|
||||
populateLayer(data.webplayout,data.relpath);
|
||||
break;
|
||||
|
||||
case 'nextTemplate':
|
||||
projectFormat = incomingData.projectFormat || 'SPX';
|
||||
LayerNro = validateLayerNro(data.webplayout);
|
||||
let renderTarget = setTarget(LayerNro, projectFormat);
|
||||
if (!LayerNro) { return }
|
||||
if (projectFormat === "OGRAF") {
|
||||
graphicInstances[renderTarget].playAction();
|
||||
} else {
|
||||
document.getElementById(renderTarget).contentWindow?.next();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'updateTemplate':
|
||||
projectFormat = incomingData.projectFormat || 'OGRAF'; // default value
|
||||
LayerNro = validateLayerNro(data.webplayout);
|
||||
setTimeout(function(){ updateLayer(data.webplayout, data.fields, projectFormat); }, 10);
|
||||
break;
|
||||
|
||||
case 'stopTemplate':
|
||||
projectFormat = incomingData.projectFormat || 'SPX'; // default value
|
||||
LayerNro = validateLayerNro(data.webplayout);
|
||||
if (!LayerNro) { return }
|
||||
stopLayer(LayerNro, projectFormat);
|
||||
break;
|
||||
|
||||
case 'customAction':
|
||||
LayerNro = validateLayerNro(data.webplayout)
|
||||
graphicInstances['div' + LayerNro].customAction({id: incomingData.id})
|
||||
|
||||
|
||||
case 'invokeFunction':
|
||||
LayerNro = validateLayerNro(data.webplayout);
|
||||
if (!LayerNro) { return }
|
||||
try {
|
||||
// Important change! --------------------------------------------------
|
||||
// Starting from version 1.2.0 it is recommended to use
|
||||
// "data.function" and "data.params" instead of "data.invoke"
|
||||
// that was a string representation of a function call with
|
||||
// parameters. Server will log all uses of the old "data.invoke"
|
||||
// and will recommend to use the new "data.function" and "data.params"
|
||||
// instead. The old "data.invoke" will be deprecated in the future.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if (data.function) {
|
||||
var myFunction = data.function;
|
||||
var myParamets = data.params || null;
|
||||
if (typeof document.getElementById('layer' + LayerNro).contentWindow[myFunction] === "function") {
|
||||
let paramPreview = '';
|
||||
if (myParamets && myParamets!="undefined") {
|
||||
paramPreview = 'First 30 chars of args: ' + myParamets.substring(0, 30);
|
||||
} else {
|
||||
paramPreview = 'No args.';
|
||||
}
|
||||
document.getElementById('layer' + LayerNro).contentWindow[myFunction](myParamets);
|
||||
} else {
|
||||
console.warn('Function "' + myFunction + '" not found on layer ' + LayerNro + '. Verify function and loaded template.');
|
||||
}
|
||||
|
||||
let ografLayer = document.getElementById('div' + LayerNro)
|
||||
let ografFrame = ografLayer.querySelector('.ografRenderTarget').querySelector('iframe')
|
||||
let ografContent = ografFrame.contentWindow
|
||||
if (typeof ografContent[myFunction] === "function") {
|
||||
ografContent[myFunction](myParamets);
|
||||
} else {
|
||||
console.warn('Function "' + myFunction + '" not found on OGraf ' + LayerNro + '. Verify function and loaded graphic.');
|
||||
}
|
||||
|
||||
} else {
|
||||
if (data.invoke) {
|
||||
let warning = '\DEPRECATION WARNING\n';
|
||||
warning += '`data.invoke` will be deprecated in the next SPX version. Refactor your extensions to '
|
||||
warning += 'use `data.function` and `data.params` instead when calling the /gc/playout API or use ';
|
||||
warning += 'the public API endpoint /api/v1/invokeTemplateFunction instead.\n';
|
||||
warning += 'You had a call [' + data.invoke + '].\n\n';
|
||||
console.warn(warning);
|
||||
let myFunction = data.invoke.split('(')[0]; // Checking if template has this function
|
||||
if (typeof document.getElementById('layer' + LayerNro).contentWindow[myFunction] === "function") {
|
||||
eval("document.getElementById('layer' + " + LayerNro + ").contentWindow." + data.invoke);
|
||||
} else {
|
||||
console.warn('Function "' + myFunction + '" not found on layer ' + LayerNro + '. Verify function and loaded template.');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(err) {
|
||||
console.warn('Error invoking "' + myFunction + '" on layer ' + LayerNro + '. Verify function and loaded template.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'setRendererBackgroundImage':
|
||||
if (data.background != '' ) {
|
||||
document.getElementById('root').style.backgroundImage = 'url(/' + data.background + ')';
|
||||
} else {
|
||||
document.getElementById('root').style.backgroundImage = '';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// console.log('Unknown SPXMessage2Client command in renderer: ' + data.spxcmd);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('SPXWebRendererMessage', function (data) {
|
||||
// Handles messages coming from server to this client.
|
||||
// All comms using 'SPXWebRendererMessage' as a conduit with data object and
|
||||
// data.spxcmd as function identifier. Additional object values are payload.
|
||||
// console.log('SPXWebRendererMessage received (but doing nothing to it)', data)
|
||||
}); // socketMessage handler ended
|
||||
|
||||
window.addEventListener('load',protocolCheck,false);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root">
|
||||
<dotlottie-player id="wm"></dotlottie-player>
|
||||
{{#ifValue hideCursor "true"}}
|
||||
<div id="cursorHider"></div>
|
||||
{{/ifValue}}
|
||||
<!-- SPX Solo does not support in-layer transitions -->
|
||||
<iframe class="frame htmlFrame" allow="autoplay" id="layer1" style="z-index: 101;" src="about:blank"></iframe>
|
||||
<iframe class="frame htmlFrame" allow="autoplay" id="layer2" style="z-index: 102;" src="about:blank"></iframe>
|
||||
<iframe class="frame htmlFrame" allow="autoplay" id="layer3" style="z-index: 103;" src="about:blank"></iframe>
|
||||
<iframe class="frame htmlFrame" allow="autoplay" id="layer4" style="z-index: 104;" src="about:blank"></iframe>
|
||||
<iframe class="frame htmlFrame" allow="autoplay" id="layer5" style="z-index: 105;" src="about:blank"></iframe>
|
||||
<div class="frame ografFrame" allow="autoplay" id="div1" style="z-index: 201"></div>
|
||||
<div class="frame ografFrame" allow="autoplay" id="div2" style="z-index: 202"></div>
|
||||
<div class="frame ografFrame" allow="autoplay" id="div3" style="z-index: 203"></div>
|
||||
<div class="frame ografFrame" allow="autoplay" id="div4" style="z-index: 204"></div>
|
||||
<div class="frame ografFrame" allow="autoplay" id="div5" style="z-index: 205" ></div>
|
||||
</div>
|
||||
<div class="debugMessage" id="debugMessage" style="opacity:0; position: absolute; z-index:1000;"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,179 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_renderpopups.css">
|
||||
|
||||
<title>SPX - scalable renderer view</title>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<style>
|
||||
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: rgb(0,0,0);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
box-sizing: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.renderer {
|
||||
/* rendererscalable hardcoded to 1920x1080 data received {{width}}x{{height}}*/
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0px;
|
||||
outline: 0px;
|
||||
width: {{width}};
|
||||
height: {{height}};
|
||||
ZZZwidth: 1920px;
|
||||
ZZZheight: 1080px;
|
||||
background-size: 10vw;
|
||||
transform-origin: top left;
|
||||
background-image: url('/img/checker60.png'); /* bgimage for local preview */
|
||||
}
|
||||
|
||||
#message {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
color: orange;
|
||||
font-size: 2.0vw;
|
||||
line-height: 1.5em;
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-shadow: 2px 2px 4px black;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.pale {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#previewBG {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 0px solid yellowgreen;
|
||||
}
|
||||
|
||||
#previewIF {
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script>
|
||||
var socket = io();
|
||||
let socData={};
|
||||
|
||||
socket.on('connect', function () {
|
||||
{{#ifValue mode 'preview'}}
|
||||
socData.name = 'SPX_PREVIEW';
|
||||
{{/ifValue}}
|
||||
{{#ifValue mode 'program'}}
|
||||
socData.name = 'SPX_PROGRAM';
|
||||
{{/ifValue}}
|
||||
socData.spxcmd = 'identifyClient';
|
||||
socket.emit('SPXMessage2Server', socData);
|
||||
});
|
||||
|
||||
socket.on('SPXMessage2Client', function (data) {
|
||||
if (data.spxcmd == 'closepreview' && socData.name == 'SPX_PREVIEW') {
|
||||
window.close();
|
||||
}
|
||||
if (data.spxcmd == 'closeprogram' && socData.name == 'SPX_PROGRAM') {
|
||||
window.close();
|
||||
}
|
||||
}); // end SPXMessage2Client
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onresize="resizePreview();">
|
||||
|
||||
{{#ifValue mode 'preview'}}
|
||||
<div class="watermark prev"></div>
|
||||
{{/ifValue}}
|
||||
|
||||
{{#ifValue mode 'program'}}
|
||||
<div class="watermark prog"></div>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
<div id="previewBG" style="background-color: rgb(0, 0, 0); overflow: hidden;">
|
||||
|
||||
{{#ifValue mode 'preview'}}
|
||||
<iframe id="previewIF" src="/renderer?preview=true" class="renderer"></iframe>
|
||||
{{else}}
|
||||
<iframe id="previewIF" src="/renderer" class="renderer"></iframe>
|
||||
{{/ifValue}}
|
||||
</div>
|
||||
|
||||
|
||||
<div id="message">
|
||||
THIS SCALABLE VIEW IS FOR SPX OPERATOR ONLY
|
||||
<br>
|
||||
<small class="pale">Use transparent <span style="color:#fff;">/renderer</span> for production.</small>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
anime({
|
||||
targets: '#message',
|
||||
opacity: 0,
|
||||
duration: 1000,
|
||||
easing: 'linear',
|
||||
delay: 2000
|
||||
});
|
||||
|
||||
function resizePreview() {
|
||||
// renderscalable
|
||||
// Scalable renderer size set by SPX to {{width}}x{{height}}
|
||||
let DefaultX = '{{width}}'; // Math always defaults to 16:9
|
||||
let DefaultY = '{{height}}';
|
||||
// console.log('Resizer ' + DefaultX + ' x ' + DefaultY + ' px');
|
||||
|
||||
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
|
||||
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
|
||||
|
||||
if (DefaultX.includes('vw')) {
|
||||
// Responsive settings, use window size! Added in v1.3.0
|
||||
// console.log('Responsive settings, use window size! Added in v1.3.0');
|
||||
DefaultX = vw;
|
||||
DefaultY = vh;
|
||||
}
|
||||
|
||||
let Wpx = vw// document.getElementById('previewWidthRuler').offsetWidth;
|
||||
let Sca = Wpx/parseInt(DefaultX);
|
||||
let Hpx = parseInt(parseInt(DefaultY) * Sca);
|
||||
document.getElementById('previewBG').style.width=Wpx+'px';
|
||||
document.getElementById('previewBG').style.height=Hpx+'px';
|
||||
document.getElementById('previewIF').style.transform="scale("+Sca+")";
|
||||
document.getElementById('previewBG').style.display='block';
|
||||
// console.log('Resized to ' + Wpx + ' x ' + Hpx + ' px, scale multiplier: ' + Sca);
|
||||
}
|
||||
|
||||
resizePreview();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,540 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/Sortable.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
<script src="/js/spx_showConfig.js"></script>
|
||||
<title>SPX | {{lang 'pagetitle.configshow'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_accents.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
</head>
|
||||
|
||||
<body onload="pageInit();" class="bg_body" onmouseover="tip('');">
|
||||
|
||||
<input type="hidden" id="treedata" value="{{TemplateFiles}}">
|
||||
<input type="hidden" id="showfolder" value="{{folder}}">
|
||||
<input type="hidden" id="templateroot" value="{{TemplateRootFolder}}">
|
||||
<input type="hidden" id="templaterootmassage" value="{{lang 'error.preventBrowseUp'}}">
|
||||
<input type="hidden" id="projectFormat" value="{{showconfig.projectFormat}}">
|
||||
|
||||
|
||||
{{!-- <h1>format: {{showconfig.projectFormat}}</h1> --}}
|
||||
|
||||
|
||||
{{>partial-templatebrowsermodal}}
|
||||
{{>partial-showextrabrowsermodal}}
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
|
||||
<div class="header">
|
||||
{{>header page="showconfig"}}
|
||||
</div><!-- header ended -->
|
||||
|
||||
|
||||
<div class="content">
|
||||
<div class="centerColumn pM wrapper">
|
||||
<div id="itemList" class="content pM scroller" style="border: 0px solid yellow;">
|
||||
|
||||
{{#if messageCode}}
|
||||
<div class="message">{{messageCode}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if errorCode}}
|
||||
<div class="messagerror"><B>{{errorCode}}</B><BR><BR>{{lang errorCode}}</div>
|
||||
{{/if}}
|
||||
<div style="display: flex;">
|
||||
<div style="flex-grow: 1" class="vmidTD tableheaderText">{{lang 'config.templates'}}</div>
|
||||
<div class="tableheaderHelp">
|
||||
{{#ifValue showconfig.projectFormat 'OGRAF'}}
|
||||
<a onClick="help('ograf');" onmouseover="tip('What is OGraf?');">
|
||||
<img src="/img/ograf-logo-mono-white.svg" style="width: 5vw;">
|
||||
</a>
|
||||
{{/ifValue}}
|
||||
|
||||
</div>
|
||||
<div class="tableheaderHelp"><a title="{{lang 'general.help'}}" onClick="help('projecttemplates');"
|
||||
onmouseover="tip('{{lang 'hover.help'}}');">
|
||||
<i class="far fa-question-circle"></i>
|
||||
</a></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
Move this nag to documentation instead...
|
||||
<span style="display: block; padding: 0.6em 1.7em; background: #0000004b; color:#ffffff; font-size:0.7em; border-radius:9px; margin_5px; text-align:center;">
|
||||
{{lang 'warning.showprofilebackup'}}
|
||||
</span><BR>
|
||||
-->
|
||||
|
||||
|
||||
{{!-- <table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.templates'}}</td>
|
||||
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('projecttemplates');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table> --}}
|
||||
|
||||
|
||||
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
|
||||
<!-- iterate all templates from showconfig ========================================================================= -->
|
||||
|
||||
{{#each showconfig.templates}}
|
||||
|
||||
<div id="template{{@index}}">
|
||||
<button class="collapsible bg_grey15 row_accent{{uicolor}}" type="button" onmouseover="tip('{{lang 'hover.confitem'}}');">
|
||||
{{{nameFromTemplatePath relpath }}}
|
||||
<SPAN style="background: #fff; padding: 0.1em 0.5em; border-radius: 0.5em; border: 0px solid yellow; float:right; opacity:0.3; color: #000">{{playlayer}} | {{{max5 webplayout}}}</SPAN>
|
||||
</button>
|
||||
<div class="collapsiblecontent spxConfigHead" >
|
||||
<form name="config{{@index}}" id="config{{@index}}" method="post" action="config/saveTemplate">
|
||||
<input type="hidden" name="showFolder" value="{{../folder}}">
|
||||
<input type="hidden" name="TemplIndex" value="{{@index}}">
|
||||
<input type="hidden" name="templateData[DataFields]" value="{{{DataToJSONString DataFields}}}">
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.templatefile'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" id="templateIndex{{@index}}" placeholder="Template file" name="templateData[relpath]" value="{{relpath}}" onmouseover="tip('{{lang 'hover.templatepath'}}');"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.description'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="Description" name="templateData[description]" value="{{description}}" onmouseover="tip('{{lang 'hover.templatedescr'}}');"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.inputfields'}}</span></td>
|
||||
<td onmouseover="tip('{{lang 'hover.fields'}}');">
|
||||
<span class="spxConfigHead">
|
||||
{{DataFields.length}} {{lang 'general.pcs'}}
|
||||
<!-- removed in 1.0.14
|
||||
{{#each DataFields}}
|
||||
{{title}}
|
||||
{{/each}}
|
||||
-->
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.ccgplayout'}}</span></td>
|
||||
<td>
|
||||
<div class="" style="width: 100%; border: 0px solid blue;">
|
||||
<select style="width: 50%;" class="drop bg_grey15" name="templateData[playserver]" onmouseover="tip('{{lang 'hover.ccgserver'}}');">
|
||||
{{{generateCasparCgPlayoutOptions playserver}}}
|
||||
</select>
|
||||
<input style="width: 23%;" type="text" class="bg_grey15 cfg" onmouseover="tip('{{lang 'hover.ccgchannel'}}');" placeholder="Channel" name="templateData[playchannel]" value="{{playchannel}}">
|
||||
<input style="width: 23%;" type="text" class="bg_grey15 cfg" onmouseover="tip('{{lang 'hover.ccglayer'}}');" placeholder="Layer" name="templateData[playlayer]" value="{{playlayer}}">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.dataformat'}}</span></td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="templateData[dataformat]" onmouseover="tip('{{lang 'hover.dataformat'}}');">
|
||||
{{{generateDataFormatOptions dataformat}}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.webplayout'}}</span></td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="templateData[webplayout]" onmouseover="tip('{{lang 'hover.weblayer'}}');">
|
||||
{{{generateWebPlayoutOptions webplayout}}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.stopmode'}}</span></td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="templateData[out]" onmouseover="tip('{{lang 'hover.outmode'}}');">
|
||||
{{{generateOutOptions out}}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.coloraccent'}}</span></td>
|
||||
<td onmouseover="tip('{{lang 'hover.accent'}}');">
|
||||
{{{generateColorAccents uicolor @index}}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
{{#if imported}}
|
||||
<tr>
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.updated'}}</span></td>
|
||||
<td onmouseover="tip('{{lang 'hover.updated'}}');">
|
||||
<span class="spxConfigHead">
|
||||
{{{generateTimestamp imported}}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="wide" style="padding: 10px; margin-bottom:10px;">
|
||||
<tr>
|
||||
<td width="25%">
|
||||
<button type="button"
|
||||
class="wide spxFlexItem btnsmall bg_grey10 ripple black"
|
||||
onclick="removeTemplateIndex({{@index}});"
|
||||
onmouseover="tip('{{lang 'hover.removetemplate'}}');"
|
||||
>{{lang 'button.deletetemplate'}}</button>
|
||||
</td>
|
||||
<td width="25%">
|
||||
<button type="button"
|
||||
class="wide spxFlexItem btnsmall bg_grey10 ripple black"
|
||||
onclick="reimportTemplateIndex({{@index}});"
|
||||
onmouseover="tip('{{lang 'hover.replacetemplate'}}');"
|
||||
>{{lang 'button.replacetemplate'}}</button>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td width="25%" class="aright">
|
||||
<button type="submit"
|
||||
class="wide spxFlexItem btnsmall bg_grey10 ripple black"
|
||||
onmouseover="tip('{{lang 'hover.saveprofile'}}');"
|
||||
>{{lang 'button.save'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</div><!--ended item -->
|
||||
|
||||
</div><!-- index ended -->
|
||||
{{/each}}
|
||||
<!-- templates ended from showconfig ========================================================================= -->
|
||||
|
||||
|
||||
<div class="wide" style="text-align: center; padding:0.5rem;">
|
||||
{{#if showconfig.templates}}
|
||||
<!-- templates above -->
|
||||
{{else}}
|
||||
<span style="display: inline-block; margin: 10px;padding: 0.6em 1.7em; background: #0000001c; color:#ffffff; font-size:0.7em; border-radius:2em; margin_5px; text-align:center;">
|
||||
{{lang 'config.addfirsttemplate'}}
|
||||
</span><BR>
|
||||
{{/if}}
|
||||
|
||||
<button type="button" class="addbtn bg_blue ripple" onClick="ModalOn('fileoverlay');" onmouseover="tip('{{lang 'hover.browsetemplate'}}');">+</button>
|
||||
</div>
|
||||
|
||||
<BR><BR>
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.general'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('projectgeneral');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<div class="configGeneralContent spxConfigHead" >
|
||||
<form name="configGeneral" id="configGeneral" method="post" action="config/saveGeneralSettings">
|
||||
<input type="hidden" name="showFolder" value="{{folder}}">
|
||||
|
||||
<!-- background option -->
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr>
|
||||
<td width="50%"><span class="spxConfigHead">{{lang 'config.backgroundImage'}}</span></td>
|
||||
<td width="30%">
|
||||
<select style="width: 100%; color:#white; background-color: #656E7A;" class="drop" name="background" onmouseover="tip('Choose an image');">
|
||||
<option value="">{{lang 'general.none'}} ({{lang 'color.transparent'}})</option>
|
||||
<option class="generalSettingDropdown" disabled></option>
|
||||
<option class="generalSettingDropdown" disabled>{{lang 'config.optionalBgImage'}}:</option>
|
||||
<option class="generalSettingDropdown" disabled>ASSETS/media/images/hd</option>
|
||||
<option class="generalSettingDropdown" disabled></option>
|
||||
{{{ PopulateFilelistOptions 'media/images/hd' 'png' showconfig.general.background }}}
|
||||
</select>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<button type="submit" onmouseover="tip('{{lang 'hover.cancelconfig'}}');" class="wide btn bg_grey10 ripple">SET</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<BR><BR>
|
||||
|
||||
|
||||
|
||||
<!-- Project Variables are not used right now
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.projectvariables'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('projectvariables');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr">
|
||||
<div class="configGeneralContent" >
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr>
|
||||
<td width="25%" class="spxTableHeadsmall">Variable description</td>
|
||||
<td width="25%" class="spxTableHeadsmall" align="right">Name: pcs </td>
|
||||
<td width="50%" class="spxTableHeadsmall"> Value</td>
|
||||
</tr>
|
||||
{{#each showconfig.variables}}
|
||||
<tr>
|
||||
<td width="25%"><span class="spxConfigHead">{{title}}</span></span></td>
|
||||
<td width="25%"><span class="spxConfigHead"><span class="prvar">{{prvar}}: {{{itemCount users}}}</span></span></td>
|
||||
<td width="50%"><input type="text" class="wide bg_grey15 cfg" id="templateIndex{{@index}}" name="templateData[relpath]" value="{{value}}" onmouseover="tip('{{lang 'hover.templatepath'}}');"></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
<BR><BR>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'config.showextras'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('projectextras');" onmouseover="tip('{{lang 'hover.help'}}');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
|
||||
<!-- script linker -->
|
||||
<div id="scriptLinker">
|
||||
<button class="collapsible bg_grey15 row_accentExtras" type="button">{{lang 'config.functionlibrary'}}</button>
|
||||
<div class="collapsiblecontent spxConfigHead" >
|
||||
<form name="extrascript" id="extrascript" method="post" action="config/saveExtraScript">
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.javascriptfile'}}</span></td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="ExtraFunctions/myExtraFunctions.js" id="customscript" name="customscript"
|
||||
{{#if showconfig.showExtras.customscript}}
|
||||
value="{{showconfig.showExtras.customscript}}"
|
||||
{{else}}
|
||||
value="ExtraFunctions/demoFunctions.js"
|
||||
{{/if}}
|
||||
onmouseover="tip('{{lang 'hover.showjsfile'}}');">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td><button type="button" class="wide spxFlexItem btnsmall bg_grey10 ripple black" onClick="addShowScript();" onmouseover="tip('{{lang 'hover.saveprofile'}}');">{{lang 'button.save'}}</button></td>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</div><!--ended extra item -->
|
||||
</div><!-- extra index ended -->
|
||||
<!-- //script linker -->
|
||||
|
||||
|
||||
{{#each showconfig.showExtras.CustomControls}}
|
||||
<!-- each extra button -->
|
||||
<div id="extra{{@index}}">
|
||||
<button class="collapsible bg_grey15 row_accentExtras" type="button">{{description}}</button>
|
||||
<div class="collapsiblecontent spxConfigHead" >
|
||||
<form name="extra{{@index}}" id="extra{{@index}}" method="post" action="config/saveExtra">
|
||||
<input type="hidden" name="ExtraIndex" value="{{@index}}">
|
||||
<input type="hidden" name="showFolder" value="{{../folder}}">
|
||||
<input type="hidden" name="extraData[ftype]" value="{{ftype}}">
|
||||
<table class="wide" style="border: 0px solid pink; border-spacing: 10px; border-collapse: separate;" border="0">
|
||||
<tr onmouseover="tip('{{lang 'hover.buttontype'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontype'}}</span></td>
|
||||
<td><span class="spxConfigHead">{{ftype}}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.functiondescription'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="Description" name="extraData[description]" value="{{description}}" onmouseover="tip('{{lang 'hover.extradescr'}}');"></td>
|
||||
</tr>
|
||||
<tr onmouseover="tip('{{lang 'hover.colors'}}');">
|
||||
<td width="40%"><span class="spxConfigHead">{{lang 'config.buttoncolor'}}</span></td>
|
||||
<td>
|
||||
<select class="wide drop bg_grey15" name="extraData[bgclass]">
|
||||
{{{generateButtonColorClasses bgclass}}}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
{{#ifValue ftype "button"}}
|
||||
<tr onmouseover="tip('{{lang 'hover.text'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontext'}}</span></td>
|
||||
<td>
|
||||
<input type="text" class="wide bg_grey15 cfg" placeholder="Caption" name="extraData[text]" value="{{text}}" >
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="clickHandler" name="extraData[fcall]" value="{{fcall}}" ></td>
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "togglebutton"}}
|
||||
<tr>
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontexts'}}</span></td>
|
||||
<td>
|
||||
<input type="text" style="width: 49%;" class="bg_grey15 cfg" placeholder="ON" name="extraData[text0]" value="{{text0}}" onmouseover="tip('{{lang 'hover.text'}}');">
|
||||
<input type="text" style="width: 49%;" class="bg_grey15 cfg" placeholder="OFF" name="extraData[text1]" value="{{text1}}" onmouseover="tip('{{lang 'hover.text1'}}');">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="toggleHandler" name="extraData[fcall]" value="{{fcall}}" ></td>
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
|
||||
{{#ifValue ftype "selectbutton"}}
|
||||
<input type="hidden" name="value" value="{{value}}">
|
||||
<tr onmouseover="tip('{{lang 'hover.text'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.buttontext'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="Caption" name="extraData[text]" value="{{text}}" ></td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.fcall'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.functionhandler'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="toggleHandler" name="extraData[fcall]" value="{{fcall}}" ></td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.defaultvalue'}}');">
|
||||
<td><span class="spxConfigHead">{{lang 'config.defaultvalue'}}</span></td>
|
||||
<td><input type="text" class="wide bg_grey15 cfg" placeholder="" name="extraData[value]" value="{{value}}" ></td>
|
||||
</tr>
|
||||
|
||||
<tr onmouseover="tip('{{lang 'hover.options'}}');">
|
||||
<td><span class="spxConfigHead vtop">{{lang 'config.options'}}</span></td>
|
||||
<td>
|
||||
{{#each items}}
|
||||
<input type="text" class="w50 bg_grey15 cfg" placeholder="{{lang 'config.text'}}" name="extraData[items][{{@index}}][text]" value="{{text}}" >
|
||||
<input type="text" class="w50 bg_grey15 cfg" placeholder="{{lang 'config.value'}}" name="extraData[items][{{@index}}][value]" value="{{value}}" ><BR>
|
||||
<!-- name="casparcg[servers][{{@index}}][name]" -->
|
||||
{{/each}}
|
||||
<input type="text" class="w50 bg_grey15 cfg" placeholder="{{lang 'config.text'}}" name="newTXT" value="" >
|
||||
<input type="text" class="w50 bg_grey15 cfg" placeholder="{{lang 'config.value'}}" name="newVAL" value="" ><BR>
|
||||
<span style="display:block; font-size: 0.7em; text-align:center;">{{lang 'config.addnewtip'}}</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{{/ifValue}}
|
||||
|
||||
</table>
|
||||
<table class="wide" style="padding: 10px; margin-bottom:10px;">
|
||||
<tr >
|
||||
<td width="25%" onmouseover="tip('{{lang 'hover.removetemplate'}}');">
|
||||
<button type="button" class="wide spxFlexItem btnsmall bg_grey10 ripple black" onclick="removeExtraIndex({{@index}});" >{{lang 'button.deletebutton'}}</button>
|
||||
</td>
|
||||
<td> </td>
|
||||
<td width="25%" class="aright" onmouseover="tip('{{lang 'hover.saveprofile'}}');">
|
||||
<button type="submit" class="wide spxFlexItem btnsmall bg_grey10 ripple black" >{{lang 'button.save'}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</div><!--ended extra item -->
|
||||
</div><!-- extra index ended -->
|
||||
|
||||
|
||||
|
||||
<!-- //each extra button -->
|
||||
{{/each}}
|
||||
<div class="wide" style="text-align: center; padding:0.5rem;">
|
||||
{{#if showconfig.showExtras.CustomControls}}
|
||||
<!-- templates above -->
|
||||
{{else}}
|
||||
<span style="display: inline-block; margin: 10px;padding: 0.6em 1.7em; background: #0000001c; color:#ffffff; font-size:0.7em; border-radius:2em; margin_5px; text-align:center;">
|
||||
{{lang 'config.addfirstextra'}}
|
||||
</span><BR>
|
||||
{{/if}}
|
||||
<button type="button" class="addbtn bg_blue ripple" onClick="ModalOn('extraoverlay');" onmouseover="tip('{{lang 'hover.browseextras'}}');">+</button>
|
||||
</div>
|
||||
|
||||
</div><!-- itemlist ended -->
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
|
||||
|
||||
{{>footer}}
|
||||
|
||||
|
||||
</div><!-- MAINwrapper ended -->
|
||||
|
||||
|
||||
<script>
|
||||
// See spx_gc.js
|
||||
function pageInit(){
|
||||
RenderFolder(JSON.parse(document.getElementById('treedata').value));
|
||||
|
||||
// COLLAPSIPLE HANDLERS
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("active");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.maxHeight){
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// TREE HANDLERS
|
||||
// https://www.w3schools.com/howto/howto_js_treeview.asp
|
||||
var toggler = document.getElementsByClassName("caret");
|
||||
var z;
|
||||
for (z = 0; z < toggler.length; z++) {
|
||||
toggler[z].addEventListener("click", function() {
|
||||
this.parentElement.querySelector(".nested").classList.toggle("opened");
|
||||
this.classList.toggle("caret-down");
|
||||
});
|
||||
}
|
||||
|
||||
spxInit('');
|
||||
heartbeat(206); // page identifier (was missing in 1.1.0)
|
||||
AppState("EDITING");
|
||||
}
|
||||
|
||||
|
||||
function AddTemplatesTab(tabNro) {
|
||||
let tabs = [1, 2, 3, 4]
|
||||
tabs.forEach((tab) => {
|
||||
let thisBtn = document.getElementById('tabBtn' + tab);
|
||||
thisBtn.classList.remove('tabSelected')
|
||||
let thisTab = document.getElementById('tab' + tab);
|
||||
thisTab.style.display = "none";
|
||||
if (thisBtn.id === 'tabBtn' + tabNro) {
|
||||
document.getElementById('tabBtn' + tabNro).classList.add('tabSelected')
|
||||
document.getElementById('tab' + tabNro).style.display = "flex";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
{{>copyright }}
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SPX {{SPX.title}} | {{lang 'pagetitle.selectshow'}}</title>
|
||||
<link rel="icon" type="image/png" href="/img/spx-gc.ico">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_fonts.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_forms.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_colors.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/spx_modal.css">
|
||||
<script src="/js/axios.min.js"></script>
|
||||
<script src="/js/fontawesome.all.min.js"></script>
|
||||
<script src="/js/anime.min.js"></script>
|
||||
<script src="/js/socket.io.js"></script>
|
||||
<script src="/js/spx_gc.js"></script>
|
||||
</head>
|
||||
<body onload="pageInit();" class="bg_body" onmouseover="tip('');">
|
||||
{{>projectForm}}
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
{{>header page="shows"}}
|
||||
</div><!-- header ended -->
|
||||
<div class="content">
|
||||
<div class="centerColumn pM wrapper ">
|
||||
<div id="itemList" class="content pM scroller" style="border: 0px solid yellow;">
|
||||
{{#if message}}
|
||||
<div class="message">{{message}}</div>
|
||||
{{/if}}
|
||||
{{#if error}}
|
||||
<div class="messagerror">{{error}}</div>
|
||||
{{/if}}
|
||||
<table class="wide" border=0>
|
||||
<TR>
|
||||
<td class="vmid tableheaderText">{{lang 'headline.select'}}</td>
|
||||
<td class="vmid tableheaderHelp aright" title="{{lang 'general.help'}}" onClick="help('projects');"><i class="far fa-question-circle"></i> </td>
|
||||
</TR>
|
||||
</table>
|
||||
<hr class="h2hr"><!-- =========================================== -->
|
||||
<table style="width: 100%;" cellspacing="10" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<select id="allProjects" style="display:none;">
|
||||
{{#each folders}}
|
||||
<option>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
{{#ifGreater folders.length 5}}
|
||||
<!-- more than 5 projects (above), so enable filtering -->
|
||||
<input type="text"
|
||||
id="projectFilter"
|
||||
placeholder="{{lang 'button.filterprojects'}}"
|
||||
onkeyup="filterProjects()"
|
||||
class="wide gcinputFilter bg_grey40 spxformtext"
|
||||
style="color:white; border-radius: 0.2em; ::placeholder {color: rgb(156, 0, 0);}"
|
||||
autofocus>
|
||||
{{/ifGreater}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<select id="lists"
|
||||
size=14 class="spxformtext bg_grey40"
|
||||
style="width: 100%; height:100%; color:white; border:0px; padding:0.2em; line-height:3;"
|
||||
onmouseover="tip('{{lang 'hover.showlist'}}');"
|
||||
ondblclick="eps();"
|
||||
{{#ifGreater folders.length 5}}
|
||||
<!-- filtering enabled -->
|
||||
{{else}}
|
||||
autofocus
|
||||
{{/ifGreater}}
|
||||
>
|
||||
{{#each folders}}
|
||||
<option>{{this}}</option>
|
||||
{{/each}}
|
||||
</select><BR>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<HR>
|
||||
<div class="spxFlexContainer">
|
||||
<button onmouseover="tip('{{lang 'hover.addshow'}}');" class="spxformtext btn spxFlexItem bg_blue ripple" onClick="addshow('projectFormOverlay');">{{lang 'button.add'}}</button>
|
||||
<button onmouseover="tip('{{lang 'hover.deleteshow'}}');" class="spxformtext btn spxFlexItem bg_blue ripple" onClick="delshow();">{{lang 'button.delete'}}...</button>
|
||||
<button onmouseover="tip('{{lang 'hover.navishow'}}');" class="spxformtext btn spxFlexItem bg_orange ripple" onClick="eps();">{{lang 'button.select'}}</button>
|
||||
</div>
|
||||
</div><!-- itemlist ended -->
|
||||
</div><!-- center wrapper ended -->
|
||||
</div><!-- content ended -->
|
||||
{{>footer}}
|
||||
</div><!-- MAINwrapper ended -->
|
||||
<script>
|
||||
window.onload = function () {
|
||||
document.getElementById('lists').selectedIndex = "0";
|
||||
heartbeat(204); // page identifier
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user