import { PdfViewer } from './pdf-viewer.js';
const $ = (s) => document.querySelector(s);
const parts = location.pathname.split('/').filter(Boolean);
const sessionId = parts[parts.length - 1];
const params = new URLSearchParams(location.search);
const token = params.get('token') || ''; // presenter token: mirror the console even after code rotation
const accessCode = params.get('k') || ''; // fallback for asset access
const socket = io();
let kind = null, built = false, viewer = null, videoEl = null;
function msg(text) { $('#stage').innerHTML = `
${text}
`; }
// Join as presenter (display-only — it never sends control) so it stays in sync
// with the console and isn't counted as an audience viewer.
socket.on('connect', () => socket.emit('join', { sessionId, role: 'presenter', token, k: accessCode }));
socket.on('error:join', (m) => msg(m));
socket.on('ended', () => msg('The presentation has ended.'));
socket.on('state', onState);
async function onState(s) {
if (!s.meta) return;
document.title = (s.meta.title || 'Presentation') + ' — MPS';
if (s.meta.status === 'processing') { msg('Preparing…'); return; }
if (s.meta.status === 'error') { msg('This presentation could not be prepared.'); return; }
if (!built) { await build(s.meta); built = true; }
if (kind === 'pdf') viewer.render(s.currentPage || 1);
else if (kind === 'video') applyVideo(s.video);
}
async function build(meta) {
kind = meta.kind;
const stage = $('#stage');
stage.innerHTML = '';
const src = `/s/${meta.id}/${meta.viewerFile}${accessCode ? `?k=${encodeURIComponent(accessCode)}` : ''}`;
if (kind === 'pdf') {
viewer = new PdfViewer(stage);
await viewer.load(src);
} else if (kind === 'video') {
videoEl = document.createElement('video');
videoEl.src = src;
videoEl.playsInline = true;
videoEl.preload = 'auto';
videoEl.setAttribute('webkit-playsinline', '');
stage.appendChild(videoEl);
} else if (kind === 'image') {
const img = document.createElement('img');
img.src = src; img.alt = meta.title || '';
stage.appendChild(img);
}
}
function applyVideo(v) {
if (!videoEl || !v) return;
const rate = v.rate || 1;
if (v.playing) {
const elapsed = (Date.now() - (v.updatedAt || Date.now())) / 1000;
const expected = (v.time || 0) + elapsed * rate;
if (Math.abs(videoEl.currentTime - expected) > 0.8) videoEl.currentTime = expected;
videoEl.playbackRate = rate;
// Play with sound where allowed; fall back to muted so the image still tracks.
videoEl.play().catch(() => { videoEl.muted = true; videoEl.play().catch(() => {}); });
} else {
videoEl.pause();
if (typeof v.time === 'number' && Math.abs(videoEl.currentTime - v.time) > 0.4) videoEl.currentTime = v.time;
}
}