Files
pulse-signage/src/web/views/signage/slides/popup-preview.hbs
T
lzstealth 3f4f57020a
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 31s
Release v2.10.3
2026-08-29 01:56:45 +01:00

226 lines
6.9 KiB
Handlebars

<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
background: #111;
color: #fff;
}
#popup-preview-stage {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
#popup-preview-canvas {
position: relative;
left: auto;
top: auto;
transform-origin: center center;
flex: 0 0 auto;
box-sizing: border-box;
display: block;
}
#popup-preview-canvas iframe {
width: 100%;
height: 100%;
border: 0;
display: block;
overflow: hidden;
}
#popup-preview-canvas .slide-preview-webpage-region iframe {
background: #fff;
}
#popup-preview-canvas .slide-preview-html-region iframe {
background: transparent;
}
.slide-preview-text-content {
line-height: 1.5;
}
.slide-preview-text-content > * {
margin: 1em 0;
}
.slide-preview-text-content > *:first-child {
margin-top: 0;
}
.slide-preview-text-content > *:last-child {
margin-bottom: 1em;
}
.slide-preview-text-content ul,
.slide-preview-text-content ol {
padding-left: 1.2em;
}
.slide-preview-text-content code {
white-space: pre-wrap;
}
</style>
<div class="slide-preview-popup-stage" id="popup-preview-stage">
<div class="slide-preview-popup-canvas" id="popup-preview-canvas"></div>
</div>
{{#if popupPreviewPayloadJson}}
<script>
window.__pulsePopupPreviewPayload = {{{popupPreviewPayloadJson}}};
</script>
{{/if}}
<script>
(function () {
function startPreviewVideoPlayback(root) {
if (!root) {
return;
}
var videos = root.querySelectorAll('video.slide-preview-video');
Array.prototype.forEach.call(videos, function (video) {
if (!video) {
return;
}
video.autoplay = true;
video.loop = true;
video.muted = true;
video.playsInline = true;
function tryPlay() {
try {
video.load();
} catch (_error) {
// Ignore load failures and try to play anyway.
}
var playPromise = video.play && video.play();
if (playPromise && typeof playPromise.catch === 'function') {
playPromise.catch(function () {
return null;
});
}
}
if (video.readyState >= 2) {
tryPlay();
return;
}
video.addEventListener('canplay', tryPlay, { once: true });
video.addEventListener('loadedmetadata', tryPlay, { once: true });
});
}
function injectFontStylesheet(href) {
var normalizedHref = String(href || '').trim();
if (!normalizedHref) {
return;
}
var existing = document.querySelector('link[data-slide-preview-fonts="true"]');
if (existing && existing.getAttribute('href') === normalizedHref) {
return;
}
if (existing && existing.parentNode) {
existing.parentNode.removeChild(existing);
}
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = normalizedHref;
link.setAttribute('data-slide-preview-fonts', 'true');
document.head.appendChild(link);
}
var stage = document.getElementById('popup-preview-stage');
var canvas = document.getElementById('popup-preview-canvas');
function readPayload() {
if (window.__pulsePopupPreviewPayload) {
return window.__pulsePopupPreviewPayload;
}
var hash = String(window.location.hash || '').replace(/^#/, '');
if (!hash) {
return null;
}
try {
return JSON.parse(decodeURIComponent(hash));
} catch (_error) {
return null;
}
}
function applyPayload() {
if (!stage || !canvas) {
return;
}
var payload = readPayload();
if (!payload) {
canvas.innerHTML = '<div class="slide-preview-empty" style="display:flex;align-items:center;justify-content:center;min-height:100%;color:rgba(255,255,255,0.75);">No preview data available.</div>';
return;
}
injectFontStylesheet(payload.fontStylesheetHref);
var backgroundColor = String(payload.backgroundColor || '#111111').trim() || '#111111';
var backgroundImagePath = String(payload.backgroundImagePath || '').trim();
var backgroundGradient = '';
try {
var gradientData = typeof payload.backgroundGradient === 'string' ? JSON.parse(payload.backgroundGradient) : payload.backgroundGradient;
if (gradientData && gradientData.type === 'linear' && ((Array.isArray(gradientData.stops) && gradientData.stops.length >= 2) || (Array.isArray(gradientData.colors) && gradientData.colors.length >= 2))) {
var gradientStops = Array.isArray(gradientData.stops) ? gradientData.stops : (gradientData.colors || []).map(function (color, index, colors) { return { color: color, position: colors.length > 1 ? Math.round(index * 100 / (colors.length - 1)) : 0 }; });
gradientStops = gradientStops.filter(function (stop) { return stop && /^#[0-9a-fA-F]{3,8}$/.test(String(stop.color || '').trim()); }).slice(0, 12);
if (gradientStops.length >= 2) {
var gradientAngle = Number(gradientData.angle);
backgroundGradient = 'linear-gradient(' + (Number.isFinite(gradientAngle) ? Math.max(0, Math.min(360, gradientAngle)) : 90) + 'deg,' + gradientStops.map(function (stop) { return stop.color + ' ' + Math.max(0, Math.min(100, Number(stop.position) || 0)) + '%'; }).join(',') + ')';
}
}
} catch (_error) {
backgroundGradient = '';
}
var canvasWidth = Math.max(1, Number(payload.canvasWidth || 1920));
var canvasHeight = Math.max(1, Number(payload.canvasHeight || 1080));
canvas.style.backgroundColor = backgroundColor;
canvas.style.backgroundImage = [backgroundImagePath ? 'url("' + encodeURI(backgroundImagePath) + '")' : '', backgroundGradient].filter(Boolean).join(',') || 'none';
canvas.style.backgroundPosition = 'center';
canvas.style.backgroundSize = backgroundImagePath ? 'contain, cover' : 'cover';
canvas.style.backgroundRepeat = 'no-repeat';
canvas.style.transformOrigin = 'center center';
canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';
canvas.innerHTML = String(payload.html || '');
startPreviewVideoPlayback(canvas);
var stageRect = stage.getBoundingClientRect();
if (!stageRect.width || !stageRect.height) {
window.requestAnimationFrame(applyPayload);
return;
}
var scale = Math.min(stageRect.width / canvasWidth, stageRect.height / canvasHeight) || 1;
canvas.style.transform = 'scale(' + scale + ')';
}
window.addEventListener('hashchange', applyPayload);
window.addEventListener('resize', applyPayload);
window.addEventListener('load', applyPayload);
applyPayload();
}());
</script>