site-manual-notifier/static/js/display.js

210 lines
7.8 KiB
JavaScript

var knownSettings = null;
var currentDisplayIndex = 0;
var main = document.createElement('main');
document.body.appendChild(main);
if (!test_display)
main.classList.add('transparent');
var section_bg = document.createElement('section');
section_bg.style.zIndex = 1;
main.appendChild(section_bg);
var section_fg = document.createElement('section');
section_fg.style.zIndex = 2;
main.appendChild(section_fg);
var nextStyle = document.getElementById('nextStyle');
setTimeout(
() => sendThroughWebSocket(JSON.stringify({
type: 'SettingsRequest'
})),
50
);
function handleMessage(message) {
if (message.type == 'MessageBroadcast')
try {
handleBroadcastedMessage(JSON.parse(message.message));
} catch (e) {
console.error(message)
console.error(e);
}
if (message.type == 'YouAre')
setTimeout(() =>
sendThroughWebSocket(JSON.stringify({
type: 'SettingsRequest'
})),
10
);
if (message.type == 'ClientConnected') {
if (!knownSettings)
setTimeout(() =>
sendThroughWebSocket(JSON.stringify({
type: 'SettingsRequest'
})),
10
);
}
}
function handleBroadcastedMessage(message) {
if (message.type == 'Settings' || message.type == 'NewSettings') {
knownSettings = message.settings;
configureForSettings();
} else if (message.type == 'SettingsRequest') {
if (knownSettings)
sendThroughWebSocket(JSON.stringify({
type: 'Settings',
settings: knownSettings
}));
sendThroughWebSocket(JSON.stringify({
type: 'CurrentlyOnScreen',
index: currentDisplayIndex
}));
} else if (message.type == 'SendToDisplay') {
enqueueForDisplay(message.settings);
}
console.log(message);
}
function configureForSettings() {
if (!!knownSettings && test_display) {
configureDisplay(knownSettings);
configureTextContent(knownSettings);
}
}
function configureDisplay(settings) {
while (section_bg.firstChild) section_bg.removeChild(section_bg.firstChild);
nextStyle.innerHTML = `
* { transition-duration: ${settings.transitionDuration}ms; }
html > body > main > section > article {
padding-left: ${settings.horizontalPadding}em;
padding-right: ${settings.horizontalPadding}em;
font-family: ${settings.fontFamily};
}
html > body > main > section > article:nth-child(1) {
margin-top: ${settings.marginTopPrimary}em;
font-size: ${settings.fontSizePrimary}em;
font-weight: ${settings.fontWeightPrimary};
line-height: ${settings.lineHeightPrimary};
color: ${settings.colorBasePrimary};
-webkit-text-fill-color: ${settings.colorBasePrimary};
-webkit-text-stroke-width: ${settings.strokeWeightPrimary}em;
-webkit-text-stroke-color: ${settings.strokeColorPrimary};
}
html > body > main > section > article:nth-child(1) > span.template-substitution {
color: ${settings.colorTemplatedPrimary};
-webkit-text-fill-color: ${settings.colorTemplatedPrimary};
}
html > body > main > section > article:nth-child(2) {
margin-top: ${settings.marginTopSecondary}em;
font-size: ${settings.fontSizeSecondary}em;
font-weight: ${settings.fontWeightSecondary};
line-height: ${settings.lineHeightSecondary};
color: ${settings.colorBaseSecondary};
-webkit-text-fill-color: ${settings.colorBaseSecondary};
-webkit-text-stroke-width: ${settings.strokeWeightSecondary}em;
-webkit-text-stroke-color: ${settings.strokeColorSecondary};
}
html > body > main > section > article:nth-child(2) > span.template-substitution {
color: ${settings.colorTemplatedSecondary};
-webkit-text-fill-color: ${settings.colorTemplatedSecondary};
}
`.trim();
section_fg.style.width = `${settings.containerWidth}px`;
section_fg.style.height = `${settings.containerHeight}px`;
section_bg.style.backgroundColor = `${settings.backgroundColor}`;
section_bg.style.width = `${settings.containerWidth}px`;
section_bg.style.height = `${settings.containerHeight}px`;
let media = null;
let backgroundMediaString = settings.backgroundMediaHidden || '';
if (backgroundMediaString.startsWith('data:image/')) {
media = document.createElement('img');
} else if (backgroundMediaString.startsWith('data:video/')) {
media = document.createElement('video');
media.setAttribute('autoplay', '');
media.setAttribute('playsinline', '');
media.setAttribute('muted', '');
}
if (!!media) {
media.setAttribute('src', backgroundMediaString);
media.style.width = '100%';
media.style.height = '100%';
media.style.objectFit = 'contain';
media.style.objectPosition = 'center';
section_bg.appendChild(media);
}
}
function configureTextContent(settings) {
while (section_fg.firstChild) section_fg.removeChild(section_fg.firstChild);
let primarySubstituted = doSubstitution(settings, 'primaryText');
let secondarySubstituted = doSubstitution(settings, 'secondaryText');
section_fg.appendChild(renderSubstituted(primarySubstituted));
section_fg.appendChild(renderSubstituted(secondarySubstituted));
}
function doSubstitution(settings, templateName) {
let template = [[false, settings[templateName]]];
for (let templateParam of settings.templateParams) {
let templateParamName = templateParam.substr(1, templateParam.length - 2);
let renderAsValue = settings[`variableField_${templateParamName}`];
template = template.flatMap(x => x[0] ? [x] : [x[1]].flatMap(y => {
let a = y.split(templateParam).reduce((arr, z) => [...arr, [false, z], [true, renderAsValue]], []);
return a.splice(0, a.length - 1);
}));
}
return template.filter(x => x[1].length);
}
function renderSubstituted(listOfLists) {
let container = document.createElement('article');
for (let tuple of listOfLists) {
if (!tuple[0]) {
container.appendChild(document.createTextNode(tuple[1]));
} else {
let subcontainer = document.createElement('span');
subcontainer.classList.add('template-substitution');
let text = tuple[1];
for (let i = 0; i < text.length; i++) {
let char = text[i];
let charcontainer = document.createElement('span');
charcontainer.setAttribute('style', `--i: ${i};`);
charcontainer.appendChild(document.createTextNode(char));
subcontainer.appendChild(charcontainer);
}
container.appendChild(subcontainer);
}
}
return container;
}
var displayQueue = [];
function enqueueForDisplay(settings) {
if (!test_display) {
let emptyDisplayQueue = displayQueue.length == 0;
displayQueue.push(settings);
if (emptyDisplayQueue)
processDisplayQueue();
}
}
function processDisplayQueue() {
if (displayQueue.length > 0) {
let settings = displayQueue[0];
configureDisplay(settings);
configureTextContent(settings);
main.classList.remove('transparent');
setTimeout(() => {
setTimeout(() => {
main.classList.add('transparent');
setTimeout(() => {
displayQueue.shift();
processDisplayQueue();
}, settings.transitionDuration);
}, settings.onScreenDuration * 1000);
}, settings.transitionDuration);
}
}