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); } }