diff --git a/20250806111925-non_technical_moc.org b/20250806111925-non_technical_moc.org index 138b233..c1dc522 100755 --- a/20250806111925-non_technical_moc.org +++ b/20250806111925-non_technical_moc.org @@ -11,3 +11,5 @@ - [[id:65F747B1-3CB2-429A-9E26-ED8BC169E689][Recipes MOC]] - [[id:45eefd5b-a3d8-4b83-84ea-5a6984025755][Proverbs]] + + diff --git a/assets/scripts/gallery-init.js b/assets/scripts/gallery-init.js index 34a83f4..2cb8df9 100755 --- a/assets/scripts/gallery-init.js +++ b/assets/scripts/gallery-init.js @@ -6,6 +6,13 @@ document.addEventListener('DOMContentLoaded', () => { function setupGalleries(root = document) { const imgs = root.querySelectorAll('.figure img, img.org-svg'); + const VIDEO_EXTENSIONS = ['mp4','webm','mov','m4v','ogv']; + + function isVideo(href){ + if(!href) return false; + href = href.toLowerCase(); + return VIDEO_EXTENSIONS.some(ext => href.endsWith('.' + ext)); + } imgs.forEach((img) => { if (img.closest('a')) return; @@ -16,10 +23,12 @@ document.addEventListener('DOMContentLoaded', () => { a.dataset.alt = img.alt || ''; const setDims = () => { - a.dataset.width = img.naturalWidth || img.width || 1920; - a.dataset.height = img.naturalHeight || img.height || 1080; + a.dataset.width = img.naturalWidth || img.width || 1920; + a.dataset.height = img.naturalHeight || img.height || 1080; }; - if (img.complete) setDims(); else img.addEventListener('load', setDims); + + if (img.complete) setDims(); + else img.addEventListener('load', setDims); img.style.cursor = 'zoom-in'; img.parentElement.insertBefore(a, img); @@ -27,37 +36,107 @@ document.addEventListener('DOMContentLoaded', () => { }); const containers = root.querySelectorAll('main, article, .content, body'); + containers.forEach((container) => { - const links = Array.from(container.querySelectorAll('.figure a, a:has(img.org-svg)')); + //const links = Array.from(container.querySelectorAll('.figure a, a:has(img.org-svg)')); + const links = Array.from(container.querySelectorAll( + '.figure a, a:has(img.org-svg), a[href$=".mp4"], a[href$=".webm"], a[href$=".mov"], a[href$=".m4v"], a[href$=".ogv"]' + )); if (!links.length) return; links.forEach((link) => { - if (link.dataset.bpBound) return; - link.dataset.bpBound = 'true'; + if (link.dataset.bpBound) return; + link.dataset.bpBound = 'true'; - link.addEventListener('click', (e) => { + link.addEventListener('click', (e) => { e.preventDefault(); - document.querySelectorAll(".theme-toggle").forEach(el => el.classList.add("hidden")); bp.open({ items: links, el: link, caption: (el) => el.querySelector('img')?.alt || el.title || '', maxZoom: 40, - onClose(containerEl) { - destroyPanZoom(); - teardownRotation(); - if (containerEl) containerEl.classList.add('bp-fadeout'); - document.querySelectorAll(".theme-toggle").forEach(el => el.classList.remove("hidden")); - }, - onOpen(containerEl) { setupRotation(containerEl); enhanceSVG(containerEl); }, - onUpdate(containerEl){ setupRotation(containerEl); enhanceSVG(containerEl); } + onOpen(containerEl){ + const linkEl = bp.currItem; + const href = linkEl?.href || ""; + + if (isVideo(href)) { + teardownRotation(); + + const htmlLayer = containerEl.querySelector(".bp-html"); + const imgLayer = containerEl.querySelector(".bp-img"); + + if (imgLayer) imgLayer.style.display = "none"; + + htmlLayer.innerHTML = ` + + `; + return; + } + + setupRotation(containerEl); + enhanceSVG(containerEl); + } }); - }); + }); }); }); } +function setupVideo(root=document){ + const links = root.querySelectorAll('a[href]'); + links.forEach(link=>{ + if(link.dataset.videoProcessed) return; + + const href = link.getAttribute("href"); + if(!isVideo(href)) return; + + link.dataset.videoProcessed = "true"; + + const video = document.createElement("video"); + video.controls = true; + video.preload = "metadata"; + video.style.maxWidth = "100%"; + video.style.borderRadius = "6px"; + + const source = document.createElement("source"); + source.src = href; + source.type = "video/" + href.split('.').pop(); + + video.appendChild(source); + + link.parentNode.replaceChild(video, link); + }); +} + function setupAudio(root = document) { + const audioLinks = root.querySelectorAll('a[href$=".mp3"]'); + + audioLinks.forEach((link) => { + if (link.dataset.audioProcessed) return; + link.dataset.audioProcessed = "true"; + + const src = link.href; + + const wrapper = document.createElement("div"); + wrapper.className = "audio-player"; + + const audio = document.createElement("audio"); + audio.controls = true; + audio.preload = "metadata"; + audio.src = src; + + const label = document.createElement("div"); + label.className = "audio-label"; + label.textContent = link.textContent || src.split("/").pop(); + + wrapper.appendChild(label); + wrapper.appendChild(audio); + + link.replaceWith(wrapper); + }); + } const bp = BiggerPicture({ target: document.body }); let activeContainer = null; @@ -233,12 +312,17 @@ document.addEventListener('DOMContentLoaded', () => { } setupGalleries(document); + setupAudio(document); const dynamicObserver = new MutationObserver((mutations) => { for (const m of mutations) { for (const node of m.addedNodes) { if (!(node instanceof HTMLElement)) continue; - if (node.querySelectorAll) setupGalleries(node); + if (node.querySelectorAll){ + setupGalleries(node); + setupAudio(node); + setupVideo(node); + } } } }); @@ -251,6 +335,8 @@ document.addEventListener('DOMContentLoaded', () => { lastUrl = currentUrl; console.log('[gallery-init] URL changed → reinitializing galleries'); setupGalleries(document); + setupAudio(document); + setupVideo(document); } }); urlObserver.observe(document, { subtree: true, childList: true }); diff --git a/assets/styles/style.css b/assets/styles/style.css index 5128e9c..8920a29 100755 --- a/assets/styles/style.css +++ b/assets/styles/style.css @@ -1044,3 +1044,19 @@ body.pane-fullscreen #content.content { max-width: 860px; } justify-content: flex-end; } } +.audio-player { + margin: 1rem 0; + padding: 0.6rem 0.8rem; + border-radius: 8px; + background: var(--bg-secondary); +} + +.audio-label { + font-size: 0.85rem; + opacity: 0.7; + margin-bottom: 0.4rem; +} + +.audio-player audio { + width: 100%; +} diff --git a/lisp/build.el b/lisp/build.el index 44a7d7f..1daf8fe 100755 --- a/lisp/build.el +++ b/lisp/build.el @@ -311,7 +311,7 @@ Created with %c on Arch