const fileInput = document.querySelector('[data-local-media-file]'); const launchButton = document.querySelector('[data-local-media-launch]'); const projectionSelect = document.querySelector('[data-local-media-projection]'); const preview = document.querySelector('[data-local-media-preview]'); const fileName = document.querySelector('[data-local-media-name]'); let activeObjectUrl = ''; fileInput?.addEventListener('change', () => { const file = fileInput.files?.[0]; if (!file) { clearLocalMedia(); return; } const mediaType = getMediaType(file); if (!mediaType) { clearLocalMedia(); setPreviewMessage('Choose an image or video file.'); return; } if (activeObjectUrl) { URL.revokeObjectURL(activeObjectUrl); } activeObjectUrl = URL.createObjectURL(file); updateLauncher(file, mediaType, activeObjectUrl); renderPreview(file, mediaType, activeObjectUrl); }); projectionSelect?.addEventListener('change', () => { if (launchButton && projectionSelect) { launchButton.dataset.projection = projectionSelect.value; } }); window.addEventListener('pagehide', () => { if (activeObjectUrl) { URL.revokeObjectURL(activeObjectUrl); } }); function clearLocalMedia() { if (activeObjectUrl) { URL.revokeObjectURL(activeObjectUrl); activeObjectUrl = ''; } if (launchButton) { launchButton.disabled = true; delete launchButton.dataset.src; delete launchButton.dataset.mediaType; delete launchButton.dataset.type; delete launchButton.dataset.title; } if (fileName) { fileName.textContent = 'No file selected'; } setPreviewMessage('Preview will appear here.'); } function getMediaType(file) { if (file.type.startsWith('image/')) { return 'image'; } if (file.type.startsWith('video/')) { return 'video'; } const extension = file.name.split('.').pop()?.toLowerCase(); if (['avif', 'gif', 'jpeg', 'jpg', 'png', 'webp'].includes(extension)) { return 'image'; } if (['m4v', 'mov', 'mp4', 'ogv', 'webm'].includes(extension)) { return 'video'; } return ''; } function updateLauncher(file, mediaType, objectUrl) { if (!launchButton || !projectionSelect) { return; } launchButton.disabled = false; launchButton.dataset.src = objectUrl; launchButton.dataset.mediaType = mediaType; launchButton.dataset.projection = projectionSelect.value; launchButton.dataset.title = file.name; if (file.type) { launchButton.dataset.type = file.type; } else { delete launchButton.dataset.type; } if (fileName) { fileName.textContent = `${file.name} (${mediaType})`; } } function renderPreview(file, mediaType, objectUrl) { if (!preview) { return; } preview.replaceChildren(); if (mediaType === 'image') { const image = document.createElement('img'); image.src = objectUrl; image.alt = file.name; preview.appendChild(image); return; } const video = document.createElement('video'); video.src = objectUrl; video.controls = true; video.muted = true; video.playsInline = true; video.preload = 'metadata'; preview.appendChild(video); } function setPreviewMessage(message) { if (!preview) { return; } const placeholder = document.createElement('p'); placeholder.textContent = message; preview.replaceChildren(placeholder); }