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

This commit is contained in:
lzstealth committed 2026-10-11 18:54:43 +01:00
1 parent 635e1a9942
commit c3299abaac
174 files changed
+4483 -1687

No files matched your search

+138
View File
@@ -204,6 +204,87 @@
}
}
function queueUploadCleanup(input, uploadPath) {
var path = String(uploadPath || '').trim();
var cleanupUrl = String(input && input.dataset.uploadCleanupUrl || '').trim();
if (!path || !cleanupUrl) {
return;
}
var payload = JSON.stringify({ uploadPaths: [path] });
if (navigator.sendBeacon) {
try {
navigator.sendBeacon(cleanupUrl, new Blob([payload], { type: 'application/json' }));
return;
} catch (_error) {
// Fall through to fetch when sendBeacon is unavailable.
}
}
fetch(cleanupUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: payload,
credentials: 'same-origin',
keepalive: true
}).catch(function () {});
}
async function uploadSelectedFile(input, file) {
var uploadUrl = String(input.dataset.uploadUrl || '').trim();
var hidden = document.getElementById(String(input.dataset.uploadHidden || '').trim());
if (!uploadUrl || !hidden || !file) {
return;
}
var maxBytes = Number(input.dataset.imageMaxBytes || 0);
if (maxBytes > 0 && file.size > maxBytes) {
input.value = '';
window.PulseUpload.showMessage('This file is larger than the current upload limit of ' + window.PulseUpload.formatUploadLimit(maxBytes) + '.');
return;
}
var formData = new FormData();
formData.append('file', file, file.name || 'upload');
input.setCustomValidity('Upload is still in progress.');
try {
var response = await fetch(uploadUrl, {
method: 'POST',
body: formData,
credentials: 'same-origin',
headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' }
});
var payload = await response.json().catch(function () { return {}; });
if (!response.ok || !payload.path) {
throw new Error(payload.error || 'Unable to upload media.');
}
var previousPath = String(input.dataset.uploadedPath || '').trim();
if (previousPath && previousPath !== payload.path) {
queueUploadCleanup(input, previousPath);
}
input.dataset.uploadedPath = payload.path;
input.dataset.uploadedNeedsCleanup = '1';
input.value = '';
input.setCustomValidity('');
hidden.value = payload.path;
hidden.dispatchEvent(new Event('change', { bubbles: true }));
updatePreview(hidden, payload.path, 'image');
} catch (error) {
input.value = '';
var currentPath = String(hidden.value || '').trim();
var backgroundPreview = document.getElementById('background-preview');
var backgroundEmpty = document.getElementById('background-empty');
if (currentPath) {
updatePreview(hidden, currentPath, 'image');
} else if (backgroundPreview) {
backgroundPreview.removeAttribute('src');
backgroundPreview.style.display = 'none';
if (backgroundEmpty) backgroundEmpty.style.display = 'flex';
}
input.setCustomValidity('');
window.PulseUpload.showMessage(error.message || 'Unable to upload media.');
} finally {
}
}
document.addEventListener('click', function (event) {
var uploadTrigger = event.target && event.target.closest ? event.target.closest('[data-media-picker-upload]') : null;
if (uploadTrigger) {
@@ -247,8 +328,46 @@
updateSelection();
});
document.addEventListener('click', function (event) {
var removeBackground = event.target && event.target.closest ? event.target.closest('#remove-background-image') : null;
if (!removeBackground) {
return;
}
var input = document.getElementById('background-image');
if (input && input.dataset.uploadedNeedsCleanup === '1') {
queueUploadCleanup(input, input.dataset.uploadedPath);
delete input.dataset.uploadedNeedsCleanup;
delete input.dataset.uploadedPath;
}
});
if (search) search.addEventListener('input', resetVisibleItemLimit);
if (sort) sort.addEventListener('change', resetVisibleItemLimit);
document.addEventListener('change', function (event) {
var input = event.target;
if (!input || input.type !== 'file' || !input.dataset) {
return;
}
var file = input.files && input.files[0];
if (input.dataset.uploadUrl) {
input.setCustomValidity('');
if (file) {
uploadSelectedFile(input, file);
}
return;
}
if (!input.dataset.uploadMaxBytes) {
return;
}
var maxBytes = Number(input.dataset.uploadMaxBytes);
if (!file || !Number.isFinite(maxBytes) || maxBytes <= 0 || file.size <= maxBytes) {
input.setCustomValidity('');
return;
}
input.value = '';
input.setCustomValidity('Image must be ' + Math.round(maxBytes / 1024 / 1024) + ' MB or smaller.');
input.reportValidity();
});
if (loadMoreButton) loadMoreButton.addEventListener('click', async function () {
loadMoreButton.disabled = true;
try {
@@ -274,12 +393,31 @@
closePicker();
return;
}
var input = getActiveFileInput();
if (input && input.dataset.uploadedNeedsCleanup === '1' && input.dataset.uploadedPath !== pendingPath) {
queueUploadCleanup(input, input.dataset.uploadedPath);
delete input.dataset.uploadedNeedsCleanup;
delete input.dataset.uploadedPath;
}
hidden.value = pendingPath;
updatePreview(hidden, pendingPath, pendingType);
hidden.dispatchEvent(new Event('change', { bubbles: true }));
closePicker();
});
if (cancelButton) cancelButton.addEventListener('click', closePicker);
document.querySelectorAll('input[type="file"][data-upload-url]').forEach(function (input) {
var form = input.form;
if (form) {
form.addEventListener('submit', function () {
delete input.dataset.uploadedNeedsCleanup;
});
}
});
window.addEventListener('beforeunload', function () {
document.querySelectorAll('input[type="file"][data-upload-url][data-uploaded-needs-cleanup="1"]').forEach(function (input) {
queueUploadCleanup(input, input.dataset.uploadedPath);
});
});
modal.addEventListener('hidden.bs.modal', function () {
activeButton = null;
currentPath = '';