220 lines
7.8 KiB
JavaScript
220 lines
7.8 KiB
JavaScript
var loadingNewData = false;
|
||
var indexFromWebSocket = false;
|
||
var acceptingRemoteSettings = true;
|
||
var currentForm = document.getElementById('currentForm');
|
||
var currentDisplayIndex = 0;
|
||
var nbsp = ' ';
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
function handleBroadcastedMessage(message) {
|
||
if (message.type == 'SettingsRequest')
|
||
sendThroughWebSocket(JSON.stringify({
|
||
type: 'Settings',
|
||
settings: getSettings()
|
||
}));
|
||
else if ((message.type == 'NewSettings') || (message.type == 'Settings' && acceptingRemoteSettings)) {
|
||
acceptingRemoteSettings = true;
|
||
applyLoadedSettings(message.settings);
|
||
acceptingRemoteSettings = false;
|
||
}
|
||
console.log(message);
|
||
}
|
||
|
||
function downloadTextFile(filename, text) {
|
||
var element = document.createElement('a');
|
||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
|
||
element.setAttribute('download', filename);
|
||
element.style.display = 'none';
|
||
document.body.appendChild(element);
|
||
element.click();
|
||
document.body.removeChild(element);
|
||
}
|
||
|
||
function getSettings() {
|
||
var settings = {};
|
||
for (var form of Array.from(document.querySelectorAll('form.form')))
|
||
for (var keyPair of Array.from((new FormData(form)).entries()))
|
||
settings[keyPair[0]] = keyPair[1];
|
||
settings.templateParams = getTemplateParameters();
|
||
return settings;
|
||
}
|
||
|
||
function saveSettings() {
|
||
var token = window.location.hash.substr(1);
|
||
downloadTextFile(
|
||
`manual-notifier_settings_${token}.json`,
|
||
JSON.stringify(getSettings())
|
||
);
|
||
}
|
||
|
||
function loadSettings(input) {
|
||
var file = input.files[0];
|
||
input.value = null;
|
||
if (file) {
|
||
var fr = new FileReader();
|
||
fr.onload = () => {
|
||
var text = fr.result;
|
||
applyLoadedSettings(JSON.parse(text));
|
||
};
|
||
fr.readAsText(file);
|
||
}
|
||
}
|
||
|
||
function loadBackgroundMedia(input) {
|
||
if (!input) {
|
||
var backgroundMediaHidden = document.getElementById('backgroundMediaHidden');
|
||
backgroundMediaHidden.value = '';
|
||
updateMediaPreviewAfterChange();
|
||
broadcastChanges();
|
||
} else {
|
||
var file = input.files[0];
|
||
input.value = null;
|
||
var fr = new FileReader();
|
||
fr.readAsDataURL(file);
|
||
fr.onloadend = () => {
|
||
var backgroundMediaHidden = document.getElementById('backgroundMediaHidden');
|
||
backgroundMediaHidden.value = fr.result;
|
||
updateMediaPreviewAfterChange();
|
||
broadcastChanges();
|
||
};
|
||
}
|
||
}
|
||
|
||
function updateMediaPreviewAfterChange() {
|
||
var mediaPreview = document.getElementById('mediaPreview');
|
||
var backgroundMediaHidden = document.getElementById('backgroundMediaHidden');
|
||
var backgroundMediaString = backgroundMediaHidden.value;
|
||
mediaPreview.style.backgroundColor = document.getElementById('backgroundColor').value;
|
||
if (backgroundMediaString == '') {
|
||
mediaPreview.innerHTML = 'No media.';
|
||
} else if (backgroundMediaString.startsWith('data:image/')) {
|
||
mediaPreview.innerHTML = `<img src="${backgroundMediaString}" style="width: 100%;">`;
|
||
} else if (backgroundMediaString.startsWith('data:video/')) {
|
||
mediaPreview.innerHTML = `<video src="${backgroundMediaString}" controls playsinline autoplay muted loop style="width: 100%;">`;
|
||
} else {
|
||
mediaPreview.innerHTML = 'Incompatible type.';
|
||
}
|
||
}
|
||
|
||
setTimeout(updateMediaPreviewAfterChange, 100);
|
||
|
||
function applyLoadedSettings(settings) {
|
||
loadingNewData = true;
|
||
for (var setting of Object.entries(settings)) {
|
||
var key = setting[0];
|
||
var value = setting[1];
|
||
var field = document.querySelector(`[name="${key}"]`);
|
||
if (!!field) {
|
||
if (field.type == 'radio' || field.type == 'checkbox') {
|
||
field = document.querySelector(`[name="${key}"][value="${value}"]`);
|
||
field.checked = true;
|
||
} else {
|
||
field.value = value;
|
||
}
|
||
}
|
||
}
|
||
updateMediaPreviewAfterChange();
|
||
loadingNewData = false;
|
||
if (!acceptingRemoteSettings)
|
||
broadcastChanges(); // only once
|
||
}
|
||
|
||
function broadcastChanges() {
|
||
if (!loadingNewData)
|
||
sendThroughWebSocket(JSON.stringify({
|
||
type: 'NewSettings',
|
||
settings: getSettings()
|
||
}));
|
||
}
|
||
|
||
var escapeHtml = (unsafe) => (unsafe
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """)
|
||
.replace(/'/g, "'"));
|
||
|
||
var form_send = document.getElementById('form_send');
|
||
var form_send_fields = document.getElementById('form_send_fields');
|
||
|
||
function getTemplateParametersFrom(input) {
|
||
return input.value.match(/\{.+?\}/g);
|
||
}
|
||
|
||
function getTemplateParameters() {
|
||
var params = ['primaryText', 'secondaryText'].map(x => document.getElementById(x)).flatMap(x => getTemplateParametersFrom(x));
|
||
return Array.from(new Set(params)).sort();
|
||
}
|
||
|
||
Element.prototype.insertChildAtIndex = function (child, index) {
|
||
if (!index) index = 0;
|
||
if (index >= this.children.length || index < 0)
|
||
this.appendChild(child);
|
||
else
|
||
this.insertBefore(child, this.children[index]);
|
||
}
|
||
|
||
function updateSendFields() {
|
||
var currentTemplateParameters = getTemplateParameters();
|
||
var onScreenTemplateParametersSet = new Set(Array.from(document.getElementsByClassName('variable-field')).map(
|
||
it => it.id).map(x => x.split('_', 2)[1]).map(x => `{${x}}`));
|
||
var currentTemplateParametersSet = new Set(currentTemplateParameters);
|
||
var fieldsToRemove = new Set([...onScreenTemplateParametersSet].filter(x => !currentTemplateParametersSet.has(x)));
|
||
var fieldsToAdd = new Set([...currentTemplateParametersSet].filter(x => !onScreenTemplateParametersSet.has(x)));
|
||
for (let fieldNameLonger of Array.from(fieldsToRemove)) {
|
||
let fieldName = fieldNameLonger.substr(1, fieldNameLonger.length - 2);
|
||
let fieldId = `variableField_${fieldName}`;
|
||
let field = document.getElementById(fieldId);
|
||
let parent = field.parentNode;
|
||
parent.removeChild(field);
|
||
}
|
||
for (let fieldNameLonger of Array.from(fieldsToAdd).sort()) {
|
||
let fieldName = fieldNameLonger.substr(1, fieldNameLonger.length - 2);
|
||
let containerId = `variableField_${fieldName}`;
|
||
let fieldId = `${containerId}_field`;
|
||
let labelId = `${containerId}_label`;
|
||
let container = document.createElement('div');
|
||
container.setAttribute('id', containerId);
|
||
container.classList.add('variable-field');
|
||
form_send_fields.insertChildAtIndex(container, currentTemplateParameters.indexOf(fieldName));
|
||
let label = document.createElement('label');
|
||
label.setAttribute('id', labelId);
|
||
label.setAttribute('for', fieldId);
|
||
label.setAttribute('class', 'f6 b db mb1 mt3 sans-serif mid-gray');
|
||
label.innerText = fieldName;
|
||
let field = document.createElement('input');
|
||
field.setAttribute('type', 'text');
|
||
field.setAttribute('id', fieldId);
|
||
field.setAttribute('name', containerId);
|
||
field.setAttribute('class', 'w-100 f5 pv3 ph3 bg-light-gray bn');
|
||
field.setAttribute('onkeyup', 'broadcastChanges()');
|
||
field.setAttribute('onkeydown', 'broadcastChanges()');
|
||
field.setAttribute('onchange', 'broadcastChanges()');
|
||
container.appendChild(label);
|
||
container.appendChild(field);
|
||
}
|
||
}
|
||
updateSendFields();
|
||
|
||
function sendToDisplay() {
|
||
sendThroughWebSocket(JSON.stringify({
|
||
type: 'SendToDisplay',
|
||
settings: getSettings()
|
||
}));
|
||
} |