Files
WebCG/views/view-controller.handlebars
T
2026-08-12 14:21:28 +09:00

1355 lines
62 KiB
Handlebars

<!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/socket.io.js"></script>
<script src="/js/vanilla-js-tooltip.js"></script>
<script src="/js/spx_controllerImportFunctions.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();
</script>
<script src="/js/spx_gc.js"></script>
<script>
// Make the DIV element draggable:
document.addEventListener("DOMContentLoaded", function() {
dragElement(document.getElementById("dialog"));
});
</script>
<title>SPX | {{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.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>
#previewIF {
border: 0px solid yellow;
}
#previewBG {
border: 0px dashed orange;
}
#colorPopup {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
display: none;
}
.stripedMessage {
--darkCol: rgba(0, 0, 0, 0.1);
--liteCol: rgba(0, 0, 0, 0.2);
top: 0;
left: 0;
width: 100%;
display: none; /* flex / controlled by JS logic */
z-index: 10;
padding: 0.5em;
font-size: 0.7em;
position: relative;
align-items: center;
border-radius: 0.0em;
margin-bottom: 0.4em;
justify-content: center;
background-size: 3vw 3vw;
color: rgb(181, 181, 181);
text-shadow: 1px 1px 1px rgb(0, 0, 0);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
background-image: linear-gradient(
135deg,
var(--darkCol) 25%,
var(--liteCol) 25%,
var(--liteCol) 50%,
var(--darkCol) 50%,
var(--darkCol) 75%,
var(--liteCol) 75%,
var(--liteCol) 100%);
}
.stripedMessage a {
color: rgb(161, 161, 161);
}
.stripedMessage a:hover {
color: rgb(255, 255, 255);
cursor: help;
}
.ListHeaderButtons {
width: 100%;
margin-bottom: 1em;
align-items: center;
justify-content: center;
padding: 0.7em;
border-left: 10px solid blue;
background-color: rgba(255, 255, 255, 0.1);
box-shadow: ;
}
#rundownInfoMessage {
display: none; /* flex / controlled by JS logic */
width: 100%;
padding: 0.2em;
align-items: center;
justify-content: center;
font-size: 0.6em;
background-color: rgba(0, 0, 0, 0.5);
margin-bottom: 0.2em;
}
.utilityOverlay {
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 50;
display: flex;
position: absolute;
align-items: center;
justify-content: flex-start;
backdrop-filter: blur(4px);
color: rgba(225, 225, 225, 0.752);
text-shadow: 1px 1px 1px rgb(0, 0, 0);
{{!-- background-color: rgba(52, 60, 68, 0.841); --}}
background-color: inherit;
}
.utilityOverlay:hover {
cursor: pointer;
background-color: rgba(0,0,0,0.5);
}
.utilitySection {
display: flex;
flex-direction: column;
padding: 0.5em 0.8em;
border-radius: 0.5em;
}
.utilitySection:nth-child(2) {
min-width: 12em;
}
.hoverable:hover {
transition: all 0.2s ease-in-out;
color: white;
background-color: rgba(255, 255, 255, 0.15);
}
.utilityTitle {
font-size: 0.7em;
}
.utiliteValue {
font-size: 0.9em;
font-family: 'UI-Regular';
}
.utiliteValueBold {
font-size: 0.9em;
font-family: 'UI-Bold';
}
.utiliteValueLarge {
font-size: 1.5em;
font-family: 'UI-Light';
padding-right: 0.8em;
border-right: rgb(207, 207, 207) 1px solid;
}
.deleteItem {
top: 0.4em;
right: 0.4em;
opacity: 0.5;
z-index: 200;
{{!-- font-size: 0.5rem; --}}
position: absolute;
padding: 0.1rem;
border-radius: 0.2em;
width: 0.9rem !important;
height: 0.9rem !important;
border: 1px solid transparent;
transition: background-color opacity 0.2s ease-in-out;
}
.deleteItem:hover {
opacity: 1;
cursor: pointer;
background-color: black;
border: 1px solid transparent;
transition: background-color opacity 0.2s ease-in-out;
}
#loaderHolder {
width: 100%;
height: 100%;
display: flex;
z-index: 1000;
position: absolute;
align-items: flex-end;
justify-content: flex-start;
background-color: transparent;
border: 0px dotted white;
}
#loader {
width: 50%;
height: 1.0%;
left: -100%;
position: absolute;
background-color: rgba(40, 146, 19, 0.8);
animation: moveAcross 1s infinite linear;
}
@keyframes moveAcross {
0% {
transform: translateX(0vw);
}
100% {
transform: translateX(100vw);
}
}
.optionsButton {
color: rgba(255, 255, 255, 0.2);
}
.optionsButton:active,
.optionsButton:hover {
color: white;
}
/* notification styles */
/* see colors in :root */
:root {
--info: rgb(0, 100, 0);
--warn: rgb(160, 0, 0);
}
#rundownNotification {
display: flex;
padding: 0.6em;
font-size: 0.7rem;
flex-direction: row;
border-radius: 0.3em;
margin-bottom: 0.5em;
pointer-events: no-none;
color: rgba(0, 0, 0, 0.8);
background-color: rgba(255, 255, 255, 0.527);
border-left: 10px solid rgba(128, 128, 128, 0.8);
}
.notifFGinfo { color: var(--info); }
.notifFGwarn { color: var(--warn); }
.notifBGinfo { background-color: var(--info); }
.notifBGwarn { background-color: var(--warn); }
#rundownNotification #notifLeft {
gap: 0.4em;
flex-grow: 1;
display: flex;
padding: 0.4em;
flex-direction: column;
}
#rundownNotification #notifLeft .notifHead {
font-size: 1.0em;
font-family: 'UI-Bold';
}
#rundownNotification #notifRight {
display: flex;
flex-shrink: 0;
flex-basis: 25%;
overflow: hidden;
border-radius: 0.5em;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
/* img set in hbs template */
}
.rundownNotificationinfo {
border-left-color: var(--info) !important;
}
.rundownNotificationwarn {
border-left-color: var(--warn) !important;
}
.notifLink a,
.notifLink a:visited,
.notifLink {
margin-top: 0.1em;
font-size: 1em;
color: rgb(0, 0, 0);
text-decoration: none;
padding-left: 0px;
transition: padding-left 0.2s ease-in-out,
color 0.2s ease-in-out;
}
.notifLink a:hover {
color: var(--info);
padding-left: 4px;
}
.notifLink::before {
content: "►";
padding-right: 0.2em;
}
.notifArrinfo {
color: var(--info);
}
.notifArrwarn {
color: var(--warn);
}
#dialogHeaderBar {
cursor: move;
}
#easter {
right: 0;
bottom: 9px;
z-index: 100;
width: 250px;
aspect-ratio: 2/1;
position: absolute;
pointer-events: none;
border: 0px dotted yellow;
background-size: 100% auto;
background-position: center;
background-repeat: no-repeat;
background-image: url('/img/easter/{{easteregg}}');
}
</style>
{{{ hookLoadControllerPlugins }}}
<script>
// See: js/spx_gc.js
</script>
</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'}}">
<input type="hidden" id="identifier" value="controller"> <!-- used by JS logic to identify view -->
<div class="overlay" id="overlayTemplatePicker">
<!-- This is the file browser modal overlay -->
<div class="modal wrapper" id="dialog">
<div class="modal_top height2" id="dialogHeaderBar">
<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; border: 0px solid white">
&nbsp;{{lang 'pagetitle.picktemplate'}} &nbsp; <a href="/show/{{folder}}/config"><i class="fas fa-cog"></i></a></small>
</td>
<td valign="middle" class="aright">
<i style="font-size: 1.5em; cursor: pointer;" class="fas fa-window-close" onClick="ModalOff('overlayTemplatePicker');"></i>&nbsp;
</td>
</tr>
</table>
</div>
<div class="content scroller">
<div id="treeview" class="filebrowser" style="padding: 2em;">
{{{ generateTemplateList folder }}}
<br>
<div class="addTemplateItem row_accent0">
<button type="button" class="addbtn bg_blue ripple" onClick="addAllTemplatesToRundown();" style="float:right;">{{lang 'general.all'}}</button>
<span class="templateName">{{lang 'pagetitle.pickAllTemplates'}}</span><BR>
<span class="templateDesc">Add all project templates to rundown with a single click</span>
</div>
<div onClick="openImportDialog();" class="addTemplateItem row_accent0">
<button type="button" class="addbtn bg_blue ripple" onClick="openImportDialog();" style="float:right; padding:0.2em 0.4em;"><i class="fas fa-file-import"></i></button>
<span class="templateName">CSV-file import</span><BR>
<span class="templateDesc">Generate multiple rundown items from a CSV file &nbsp;<span class="tableheaderHelp2" title="{{lang 'general.help'}}" onClick="help('csv');"><i class="far fa-question-circle"></i>&nbsp;</span></span>
</div>
</div>
</div>
</div>
</div><!-- overlay ended-->
{{>partial-genericfilebrowsermodal}}
<div class="overlay" id="overlayHelp">
<!-- This is the keyboard shortcuts modal overlay -->
<div class="modal wrapper">
<div class="modal_top height2">
<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;">
&nbsp;{{lang 'pagetitle.shortcuts'}}</small>
</td>
<td valign="middle" class="aright">
<i style="font-size: 1.5em; cursor: pointer;" class="fas fa-window-close" onClick="ModalOff('overlayHelp');"></i>&nbsp;
</td>
</tr>
</table>
</div>
<div class="modal_content content scroller" style="padding:2em;">
<h3>{{lang 'pagetitle.shortcuts'}}</h3><BR>
<p>
SPX controller has some basic keyboard shortcuts for fast operation. For more information about the software, visit
<A href="#" onClick="help('controller')" style="text-decoration: underline;">SPX Knowledge Base</A>.
</p>
<BR>
<table class="wide KBHelptable">
<TR>
<th width="30%"><B>Key</B></th><th><B>Function</B></th>
</TR>
<TR><td>F1</td> <td>{{lang 'pagetitle.f1ShortcutTip'}}</td></TR>
<TR><td>Up / Down</td> <td>{{lang 'pagetitle.upDownShortcutTip'}}</td></TR>
<TR><td>Enter</td> <td>{{lang 'pagetitle.enterShortcutTip'}}</td></TR>
<TR><td>Space</td> <td>{{lang 'pagetitle.spaceShortcutTip'}}<BR><small>{{lang 'pagetitle.tipContinue'}}</small></td></TR>
<TR><td>Ctrl + D</td> <td>{{lang 'pagetitle.ctrlDShortcutTip'}}</td></TR>
<TR><td>Shift + Space</td><td>{{lang 'pagetitle.shiftSpaceShortcutTip'}}</td></TR>
<TR><td>F5</td> <td>{{lang 'pagetitle.f5ShortcutTip'}}<BR><small>{{lang 'pagetitle.supportUpdateCommandTip'}}</small></td></TR>
<TR><td>Esc</td> <td>{{lang 'pagetitle.escShortcutTip'}}</td></TR>
<TR><td>CapsLock</td> <td>{{lang 'pagetitle.capsShortcutTip'}}</td></TR>
</table>
</div>
</div>
</div><!-- help overlay ended-->
<div class="wrapper" onmouseover="tip('');">
<div id="severalDetected" class="stripedMessage">
{{lang 'warning.severalControllers'}} &nbsp;
<a title="{{lang 'general.help'}}"
onClick="help('several');"
class="hoverWhite"
onmouseover="tip('{{lang 'hover.help'}}');">
<i class="far fa-question-circle"></i>
</a>
</div>
<div class="header">
{{>header page="controller" }}
</div><!-- header end -->
<div class="content">
<div class="left pM wrapper">
<div id="rdOptions">
{{>rundownOptions comment=filedata.comment }}
</div>
<div id="itemList" class="content pM itemlist scroller" style="user-select: none; opacity:0.2; border-radius: 0.4em;">
{{#if filedata.notification}}
<div id="rundownNotification" class="rundownNotification{{filedata.notification.type}}">
<div id="notifLeft">
{{#if filedata.notification.head}}
<div class="notifHead notifFG{{filedata.notification.type}}">{{filedata.notification.head}}</div>
{{/if}}
<div class="notifBody">{{filedata.notification.body}}</div>
{{#if filedata.notification.link}}
<div class="notifLink notifArr{{filedata.notification.type}}">
<a target="_blank"
href={{filedata.notification.link}}
title="{{filedata.notification.link}}"
>{{filedata.notification.text}}</a>
</div>
{{/if}}
</div>
{{#if filedata.notification.pict}}
<div id="notifRight" style="background-image: url({{filedata.notification.pict}});"></div>
{{/if}}
</div>
{{/if}}
{{#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>
<P>
Add templates to this rundown from + button below.<br>
<small style="opacity: 0.3;">Press 'F1' to open a list of useful keyboard shortcuts.</small>
</P>
</div>
{{/if}}
<!-- <div id="rundownInfoMessage" style="display:none;">CapsLock is on - showing item overlays.</div> -->
<!-- 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: 0px; margin-bottom:0px; padding-left:0px; padding-bottom:0px;">
<!-- COLLAPSED to small line-->
<div id="Collapsed" style="position:relative; padding: 10px;">
<i id="deleteSmall{{@index}}" data-spx-name="deletesmall" class="deleteItem fas fa-times" onClick="removeItemFromRundown(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.delete'}}');"></i>
<!-- UTILITY OVERLAY -->
<div class="utilityOverlay hidden">
<div class="utilitySection "
onClick="copyItemID('{{itemID}}');"
onmouseover="tip('Copy play API command for ItemID: {{itemID}}');">
<span class="utiliteValueLarge">{{{max5 webplayout}}}</span>
</div>
<div class="utilitySection hoverable"
onClick="copyItemID('{{itemID}}', '');"
onmouseover="tip('Copy ItemID [{{itemID}}]');">
<span class="utilityTitle">ItemID</span>
<span class="utiliteValueBold">{{itemID}}</span>
</div>
<div class="utilitySection hoverable"
onClick="copyItemID('{{itemID}}', 'play');"
onmouseover="tip('Copy API command [item/play/{{itemID}}]');">
<span class="utilityTitle">&nbsp;</span>
<span class="utiliteValue">PLAY</span>
</div>
<div class="utilitySection hoverable"
onClick="copyItemID('{{itemID}}', 'stop');"
onmouseover="tip('Copy API command [item/stop/{{itemID}}]');">
<span class="utilityTitle">&nbsp;</span>
<span class="utiliteValue">STOP</span>
</div>
{{#ifGreater steps 1}}
<div class="utilitySection hoverable"
onClick="copyItemID('{{itemID}}', 'continue');"
onmouseover="tip('Copy API command [item/continue/{{itemID}}]');">
<span class="utilityTitle">&nbsp;</span>
<span class="utiliteValue">CONTINUE</span>
</div>
{{/ifGreater}}
</div>
<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 colspan="2" class="vmid spxTableHeadsmall" style="height: 1.6em; text-transform:uppercase;">
<span><!--item {{@index}} &nbsp;&middot;&nbsp;-->{{{ nameFromTemplatePath relpath }}}
{{#if description}}
<span class="delim"></span> <span style="opacity:0.5;">{{description}}</span>
{{/if}}
</span>
</TD>
<!--
<TD class="vtop aright spxTableHeadsmall">
<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; padding: 0px 8px 2px 8px;">
<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>&nbsp;&nbsp;
<!-- disabled by default, enable with config -->
<i class="l-icon fas fa-edit {{{allowOpeningFolder}}}" 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>&nbsp; &nbsp;<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}}&nbsp;
<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>&nbsp; &nbsp;
</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;">
&nbsp; <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}}
{{#> PRO--types ftype=ftype}}
{{!-- Extended, proprietary ftypes --}}
{{/PRO--types}}
{{/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>
<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>
<!-- export CSV button -->
<i id="exportCSV{{@index}}" class="l-icon fas fa-file-export" onClick="exportItemAsCSV(this.closest('.itemrow'));" onmouseover="tip('{{lang 'hover.exportitem'}}');"></i><BR>
<!-- import CSV button (moved to add template view) -->
<!--
<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>
&nbsp;
</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="{{{max5 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 -->
<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> <!-- + Add Template To Rundown -->
</div>
</div>
<div style="padding-top: 10px;">
{{!-- MASTER STOP / PLAY / UPDATE --}}
<div class="wide center" style="margin: 0; padding: 0;">
<button
id="MasterTOGGLE"
class="btn bg_green ripple disabled"
style="width:45%;"
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"
style="width:45%;"
onClick="nextItem();"
onmouseover="tip('{{lang 'hover.mastercontinue'}}');"
>{{lang 'button.continue'}}</button>
<!-- *** hidden **** it was confusing there -->
<button
id="MasterUPDATE"
class="btn bg_blue ripple disabled"
style="width:33%; display:none;"
onClick="updateItem();"
onmouseover="tip('{{lang 'hover.masterupdate'}}');"
>{{lang 'button.update'}}</button> </div>
</div>
</div>
<div class="right pM scroller">
<!-- background: {{background}} -->
<div id="previewBG"
style="background-color: rgb(0, 0, 0);
width:100%;
height:27%;
overflow: hidden;
position: relative;
{{#ifValue renderer "popup"}}
display: none;
{{else}}
display: block;
{{/ifValue}}
opacity:0.1;">
<div id="LocalRendererDisabledNotification"
style="width: 100%;
{{#ifValue disableLRender "true"}}
opacity: 1;
{{else}}
opacity: 0;
{{/ifValue}}
position: absolute;
top: 0; left: 0;
height: 100%;
z-index:10;
text-align: center;
display: flex;
justify-content: center;
align-items:center;
background: transparent;
color: rgb(54, 54, 54);">Local SPX Renderer<br>DISABLED</div>
<div id="loaderHolder">
<div id="loader"></div>
</div>
<iframe
width="{{{localPreviewSize width}}}"
height="{{{localPreviewSize height}}}"
id="previewIF"
name="LOCAL"
data-comment: "Here we had width: {{width}} and height {{height}}"
{{#ifValue disableLRender "true"}}
src="/templates/empty.html"
{{else}}
src="/renderer"
{{/ifValue}}
class="renderer"
{{#if background}}
style="background-image: url('/{{background}}'); background-size: 100% 100%; position: absolute; top: 0; left: 0;"
{{/if}}
onLoad="localRendererLoaded();"
></iframe>
</div>
<div id="controllerFunctionsZone" style="opacity:0;">
<div id="renderOptionsFoldable" style="position: relative;">
<button id="localRendererCollapsiple"
class="collapsibleZone optionsButton {{{ GenerateLocalRendererOptions 'class' }}}"
type="button"
>OPTIONS</button>
<div class="collapsiblecontent spxConfigHead" style="box-shadow: inset 0 8px 12px rgba(0, 0, 0, 0.2); padding:0;">
<div style="padding:10px;">
<table style="width:100%;">
<tr>
<td width="60%" style="font-size: 0.7em;">{{lang 'config.autoplay'}}</td>
<td width="20%" ALIGN="center">
<div class="toggle-container">
<label class="vc-switch">
<input id="toggleRendererAutoplay"
{{#ifValue autoplayLocalRenderer "true"}}
checked
{{/ifValue}}
type="checkbox"
class="vc-switch-input"
onClick="toggleAutoplay(this, 'toggleAutoplaySwitch');"/>
<span id="recSlider" class="vc-switch-label"></span>
<span class="vc-handle" id="toggleAutoplaySwitch">
{{#ifValue autoplayLocalRenderer true}}
YES
{{else}}
NO
{{/ifValue}}
</span>
</label>
</div>
</td>
</tr>
<tr>
<td width="60%" style="font-size: 0.7em;">Disable local renderer</td>
<td width="20%" ALIGN="center">
<div class="toggle-container">
<label class="vc-switch">
<input id="toggleRendererWindowProgramMain"
{{#ifValue disableLRender "true"}}
checked
{{/ifValue}}
type="checkbox"
class="vc-switch-input"
onClick="toggleLRendererHandler(this, 'toggleLRender');"/>
<span id="recSlider" class="vc-switch-label"></span>
<span class="vc-handle" id="toggleLRender">
{{#ifValue disableLRender "true"}}
YES
{{else}}
NO
{{/ifValue}}
</span>
</label>
</div>
</td>
</tr>
<tr>
<td width="60%" id="toggleInfo1" style="font-size: 0.7em;">
Popup program renderer
</td>
<td width="20%" ALIGN="center">
<div class="toggle-container">
<label class="vc-switch">
<input id="toggleRendererWindowProgram"
{{#ifValue renderer "popup"}}
checked
{{/ifValue}}
type="checkbox"
class="vc-switch-input"
onClick="toggleSwitchHandler(this, 'toggle1', 'program');"/>
<span id="recSlider" class="vc-switch-label"></span>
<span class="vc-handle" id="toggle1">
{{#ifValue renderer "popup"}}
ON
{{else}}
OFF
{{/ifValue}}
</span>
</label>
</div>
</td>
<td width="20%" ALIGN="center" style="padding:0;">
<button style="font-size: 0.7em; width:90%; font-family:UI-Regular; padding: 0.15em 0; height: 1.7em;"
class="btn bg_grey ripple"
data-defaultTip = 'Program in a viewer'
data-toggleText = 'Copy program output url'
onmouseover="toggleTip('toggleInfo1', this, 'data-toggleText')"
onmouseout ="toggleTip('toggleInfo1', this, 'data-defaultTip')"
onclick = "copyRendererUrl()"
><i class="fas fa-clipboard"></i> URL</button>
</td>
</tr>
</table>
<table style="width:100%;">
<tr>
<td width="60%" id="toggleInfo2" style="font-size: 0.7em;">
Popup preview viewer
</td>
<td width="20%" ALIGN="center">
<div class="toggle-container">
<label class="vc-switch">
<input id="toggleRendererWindowPreview" type="checkbox" data-on="LOOP" data-off="OFF" class="vc-switch-input" onClick="toggleSwitchHandler(this, 'toggle2', 'preview');"/>
<span id="recSlider" class="vc-switch-label"></span>
<span class="vc-handle" id="toggle2">OFF</span>
</label>
</div>
</td>
<td width="20%" ALIGN="center" style="padding:0;">
<button style="font-size: 0.7em; width:90%; font-family:UI-Regular; padding: 0.15em 0; height: 1.7em;"
class="btn bg_grey ripple"
data-defaultTip = 'Show preview viewer'
data-toggleText = 'Copy preview output url'
onmouseover="toggleTip('toggleInfo2', this, 'data-toggleText')"
onmouseout ="toggleTip('toggleInfo2', this, 'data-defaultTip')"
onclick = "copyRendererUrl(true)"
><i class="fas fa-clipboard"></i> URL</button>
</td>
</tr>
</table>
</div>
</div>
</div> <!-- foldable end -->
</div><!-- zone ended -->
<HR id="previewWidthRuler"> <!-- =========================================================== -->
<div id="controllerPluginButtons" style="border:0px dashed yellow">
<!-- plugins zone, see hookLoadControllerPlugins -->
</div>
<!-- showExtras generated here. In future releases this may move to plugins -->
<script src="{{profiledataObj.showExtras.customscript}}"></script>
{{{ GenerateCustomControls profiledataObj.showExtras.CustomControls }}}
<script defer src="{{globalExtras.customscript}}"></script>
{{{ GenerateCustomControls globalExtras.CustomControls }}}
</div>
</div><!-- content end -->
{{#if easteregg}}
<div id="easter"></div>
{{/if}}
{{>footer}}
</div><!-- wrapper end -->
<script>
// See spx_gc.js
// console.log('Init tooltip');
var tooltip = new Tooltip();
function localRendererLoaded() {
// console.log('Local renderer loaded!');
document.getElementById('loaderHolder').style.display='none';
let AutoPlayEnabled = {{{autoplayLocalRenderer}}} || false;
if (AutoPlayEnabled) {
var items = document.querySelectorAll('[data-spx-onair]');
items.forEach((item, index) => {
if (item.getAttribute('data-spx-onair') == 'true') {
let itemID = item.getAttribute('data-spx-epoch');
playItemLocal(itemID);
}
});
} else {
// console.log('Autoplay disabled');
}
}
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
}
RenderFolder(JSON.parse(document.getElementById('csvlist').value));
resizePreview();
heartbeat(210); // page identifier
spxInit('');
} // pageInit
function forceWM() {
// Force watermark when version is double clicked
var data = {};
data.spxcmd = 'forceWM';
socket.emit('SPXWebRendererMessage', data);
}
function resizePreview() {
// 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', () => {
// added in 1.1.1 - UX is greatly improve with this change
// compared to previously used onload event
pageInit();
})
socket.on('connect', function () {
data={};
data.spxcmd = 'identifyClient';
data.name = 'SPX_CONTROLLER'; // <---- Name of this socket connection
socket.emit('SPXMessage2Server', data);
});
</script>
</body>
</html>