Release v2.15.5
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m13s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 33s

This commit is contained in:
lzstealth committed 2026-10-17 16:55:37 +01:00
1 parent 0e77998e92
commit 2fd059d35a
18 files changed
+385 -30

No files matched your search

+11 -3
View File
@@ -188,9 +188,17 @@
var previewBox = region.querySelector('.slide-image-region-preview-box');
if (previewBox) {
var safePath = escapeHtml(path);
previewBox.innerHTML = type === 'video'
? '<div class="slide-image-region-preview-shell"><video class="slide-image-region-preview" src="' + safePath + '" muted playsinline preload="metadata"></video></div>'
: '<div class="slide-image-region-preview-shell"><img class="slide-image-region-preview" src="' + safePath + '" alt="Selected media preview" /></div>';
var isVideo = type === 'video';
var isQrImage = String(hidden.name || '').indexOf('existing_region_qr_image_') === 0;
var mediaLabel = isVideo ? 'video' : isQrImage ? 'QR image' : 'image';
var removeAction = isVideo ? 'region-video' : isQrImage ? 'region-qr-image' : 'region-image';
var regionId = escapeHtml(region.getAttribute('data-region-id') || '');
previewBox.innerHTML = '<div class="slide-image-region-preview-shell" data-remove-' + removeAction + '="' + regionId + '" role="button" tabindex="0" aria-label="Remove ' + mediaLabel + '">' +
(isVideo
? '<video class="slide-image-region-preview" src="' + safePath + '" muted playsinline preload="metadata"></video>'
: '<img class="slide-image-region-preview" src="' + safePath + '" alt="Selected ' + mediaLabel + ' preview" />') +
'<span class="slide-image-region-preview-remove" aria-hidden="true"><i class="bi bi-trash3" aria-hidden="true"></i></span>' +
'</div>';
}
return;
}
+5 -1
View File
@@ -139,6 +139,9 @@
var mode = String(displayMode || 'upcoming').trim().toLowerCase();
entries = entries.filter(function (entry) {
if (mode === 'all') {
return true;
}
if (mode === 'current') {
return isLive(entry, now);
}
@@ -337,7 +340,8 @@
'<select id="region_timetable_display_mode_' + region.id + '" name="region_timetable_display_mode_' + region.id + '" class="form-select">' +
'<option value="upcoming"' + (currentDisplayMode === 'upcoming' ? ' selected' : '') + '>Upcoming</option>' +
'<option value="current"' + (currentDisplayMode === 'current' ? ' selected' : '') + '>Current</option>' +
'<option value="both"' + (currentDisplayMode === 'both' ? ' selected' : '') + '>Both</option>' +
'<option value="both"' + (currentDisplayMode === 'both' ? ' selected' : '') + '>Current &amp; Upcoming</option>' +
'<option value="all"' + (currentDisplayMode === 'all' ? ' selected' : '') + '>All</option>' +
'</select>' +
'</div>' +
'<div class="col-6 col-lg-2">' +
@@ -1232,8 +1232,18 @@
return Boolean(getRegionLockRatio(card));
}
function syncLockedDimensions(card, changedField) {
normalizeRegionCard(card, changedField);
function syncLockedDimensions(card, changedField, isEditing) {
if (isEditing) {
var current = readCard(card);
var aspect = parseLockRatio(current.lock_ratio);
if (aspect && changedField === 'width' && current.width > 0) {
writeCard(card, { height: Math.max(12, Math.round(current.width / aspect.ratio)) });
} else if (aspect && changedField === 'height' && current.height > 0) {
writeCard(card, { width: Math.max(12, Math.round(current.height * aspect.ratio)) });
}
} else {
normalizeRegionCard(card, changedField);
}
updateRegionLockBadge(card);
markTemplateFormDirty();
requestOverlayRender();
@@ -1327,9 +1337,6 @@
card.dataset.regionKey = String(region.region_key || region.label || getRegionName(card) || '').trim();
setRegionRemovalState(card);
var nameInput = card.querySelector('[name="region_name[]"]');
var lockRatioInput = card.querySelector('[name="region_lock_ratio[]"]');
var widthInput = card.querySelector('[name="region_width[]"]');
var heightInput = card.querySelector('[name="region_height[]"]');
var animationPresetInputs = card.querySelectorAll('[data-animation-preset]');
var animationResetButtons = card.querySelectorAll('[data-animation-reset-button]');
var animationAdvancedButton = card.querySelector('[data-animation-advanced-button]');
@@ -1365,21 +1372,24 @@
}
});
}
if (lockRatioInput) {
lockRatioInput.addEventListener('input', function () {
syncLockedDimensions(card, 'width');
['x', 'y', 'z', 'width', 'height', 'lock_ratio'].forEach(function (field) {
var input = card.querySelector('[name="region_' + field + '[]"]');
if (!input) {
return;
}
var changedField = field === 'lock_ratio' ? 'width' : field;
input.addEventListener('input', function () {
syncLockedDimensions(card, changedField, true);
});
}
if (widthInput) {
widthInput.addEventListener('input', function () {
syncLockedDimensions(card, 'width');
input.addEventListener('change', function () {
syncLockedDimensions(card, changedField);
});
}
if (heightInput) {
heightInput.addEventListener('input', function () {
syncLockedDimensions(card, 'height');
});
}
});
card.addEventListener('keydown', function (event) {
if (event.key === 'Enter' && event.target && event.target.tagName === 'INPUT') {
event.preventDefault();
}
});
card.addEventListener('click', function (event) {
if (event.target && event.target.closest && event.target.closest('[data-region-remove-button]')) {
return;