Release v2.2.0

This commit is contained in:
2026-08-01 21:41:44 +01:00
parent c643d2fb07
commit d6417b667c
673 changed files with 146752 additions and 7389 deletions
@@ -1,3 +1,5 @@
// Template designer bootstrap and form wiring.
(function () {
var dataElement = document.getElementById('template-editor-data');
if (!dataElement) {
@@ -33,6 +35,7 @@
var removeBackgroundFlag = document.getElementById('remove-background-image-flag');
var addRegionButton = document.getElementById('add-region-button');
var regionAddModal = document.getElementById('region-add-modal');
var regionAddOptions = document.getElementById('region-add-options');
var regionCardTemplate = document.getElementById('region-card-template');
var regionsJsonInput = document.getElementById('regions-json');
var templateForm = document.getElementById('template-form');
@@ -101,7 +104,7 @@
return utils.getDefaultRegionSize(regionType, lockRatio);
}
var ratio = parseLockRatio(lockRatio);
var locked = regionType === 'image' || regionType === 'webpage' || regionType === 'html' || regionType === 'rtmp' || regionType === 'rss';
var locked = false;
if (ratio) {
if (ratio.ratio >= 1) {
var baseWidth = locked ? 420 : 300;
@@ -113,6 +116,41 @@
return { width: locked ? 420 : 300, height: locked ? 240 : 120 };
}
function getRegionTypeEntries() {
if (window.pulseRegionTypes && typeof window.pulseRegionTypes.list === 'function') {
return window.pulseRegionTypes.list();
}
return ['api', 'html', 'image', 'rss', 'rtmp', 'text', 'time-date', 'video', 'webpage'].map(function (type) {
return { type: type, definition: window.pulseRegionTypes && typeof window.pulseRegionTypes.get === 'function' ? window.pulseRegionTypes.get(type) || {} : {} };
});
}
function formatRegionTypeLabel(regionType) {
return String(regionType || '')
.trim()
.replace(/(^|[_-])(\w)/g, function (_match, _prefix, letter) {
return String(letter || '').toUpperCase();
}) || 'Region';
}
function renderAddRegionOptions() {
if (!regionAddOptions) {
return;
}
regionAddOptions.innerHTML = getRegionTypeEntries().map(function (entry) {
var type = String(entry && entry.type ? entry.type : '').trim();
if (!type) {
return '';
}
var definition = entry.definition || {};
var label = definition.label || formatRegionTypeLabel(type);
return '<button type="button" class="btn btn-outline-secondary text-start" data-add-region-type="' + escapeHtml(type) + '">' + escapeHtml(label) + '</button>';
}).join('');
}
function getCards() {
return Array.prototype.slice.call(regionList.querySelectorAll('.region-item'));
}
@@ -179,7 +217,6 @@
region_key: getRegionName(card),
label: getRegionName(card),
region_type: card.querySelector('[name="region_type[]"]').value,
font_family: card.querySelector('[name="font_family[]"]').value,
lock_ratio: normalizeLockRatio(card.querySelector('[name="region_lock_ratio[]"]').value),
x: Number(card.querySelector('[name="region_x[]"]').value || 0),
y: Number(card.querySelector('[name="region_y[]"]').value || 0),
@@ -202,7 +239,6 @@
syncRegionIdentity(card, values.label);
}
if (values.region_type !== undefined) { card.querySelector('[name="region_type[]"]').value = values.region_type; }
if (values.font_family !== undefined) { card.querySelector('[name="font_family[]"]').value = values.font_family; }
if (values.lock_ratio !== undefined) { card.querySelector('[name="region_lock_ratio[]"]').value = normalizeLockRatio(values.lock_ratio); }
if (values.x !== undefined) { card.querySelector('[name="region_x[]"]').value = Math.round(values.x); }
if (values.y !== undefined) { card.querySelector('[name="region_y[]"]').value = Math.round(values.y); }
@@ -328,6 +364,10 @@
}
function getRegionChipLabel(regionType) {
if (window.pulseRegionTypes && typeof window.pulseRegionTypes.getRegionChipLabel === 'function') {
return window.pulseRegionTypes.getRegionChipLabel(regionType);
}
return regionType === 'image' ? 'Image' : regionType === 'video' ? 'Video' : regionType === 'webpage' ? 'Webpage' : regionType === 'html' ? 'HTML' : regionType === 'rtmp' ? 'RTMP' : regionType === 'rss' ? 'RSS' : 'Text';
}
@@ -335,7 +375,6 @@
var chip = card.querySelector('[data-region-chip]');
var title = card.querySelector('[data-region-title]');
var nameInput = card.querySelector('[name="region_name[]"]');
var fontFamilyInput = card.querySelector('[name="font_family[]"]');
var regionTypeInput = card.querySelector('[name="region_type[]"]');
var regionKeyInput = card.querySelector('[name="region_key[]"]');
var regionLabelInput = card.querySelector('[name="region_label[]"]');
@@ -349,9 +388,6 @@
if (nameInput) {
nameInput.value = region.region_key || region.label || '';
}
if (fontFamilyInput) {
fontFamilyInput.value = region.region_type === 'image' || region.region_type === 'video' || region.region_type === 'rtmp' ? '' : (region.font_family || 'Arial');
}
if (regionTypeInput) {
regionTypeInput.value = region.region_type || 'text';
}
@@ -577,7 +613,6 @@
region_key: name,
label: name,
region_type: type,
font_family: type === 'text' || type === 'html' || type === 'rss' || type === 'api' ? 'Arial' : '',
x: 80,
y: 80,
width: size.width,
@@ -753,19 +788,26 @@
}
if (addRegionButton && regionAddModal) {
var addRegionTypeButtons = regionAddModal.querySelectorAll('[data-add-region-type]');
addRegionButton.addEventListener('click', function () {
renderAddRegionOptions();
openAddRegionModal();
});
Array.prototype.forEach.call(addRegionTypeButtons, function (button) {
button.addEventListener('click', function () {
if (regionAddOptions) {
regionAddOptions.addEventListener('click', function (event) {
var button = event.target && event.target.closest ? event.target.closest('[data-add-region-type]') : null;
if (!button) {
return;
}
var regionType = button.getAttribute('data-add-region-type');
addRegion(createDefaultRegion(regionType));
if (window.pulseModal) {
window.pulseModal.hide(regionAddModal);
}
});
});
}
renderAddRegionOptions();
}
backgroundInput.addEventListener('change', function () {
var file = backgroundInput.files && backgroundInput.files[0];