aboutsummaryrefslogtreecommitdiffstats
path: root/assets/js/pages/admin-vibe.js
diff options
context:
space:
mode:
authorsillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
committersillylaird <sillyfanboy@gmail.com>2026-09-03 00:33:59 +0000
commit898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch)
tree85c6ee5ad58b860144551184d4cf86b560c62b91 /assets/js/pages/admin-vibe.js
downloadwww-main.tar.gz
www-main.zip
import live www.sillylaird.ca webrootHEADmain
Diffstat (limited to '')
-rw-r--r--assets/js/pages/admin-vibe.js71
1 files changed, 71 insertions, 0 deletions
diff --git a/assets/js/pages/admin-vibe.js b/assets/js/pages/admin-vibe.js
new file mode 100644
index 0000000..0f7b79e
--- /dev/null
+++ b/assets/js/pages/admin-vibe.js
@@ -0,0 +1,71 @@
+function detectType(url) {
+ if (!url) return 'none';
+ try { new URL(url); } catch(e) { return 'none'; }
+ const path = (new URL(url)).pathname.toLowerCase();
+ const ext = path.split('.').pop();
+ const imgs = ['jpg','jpeg','png','gif','webp','bmp','svg','avif'];
+ const vids = ['mp4','webm','ogv','mov'];
+ const auds = ['mp3','flac','wav','ogg','aac','opus','m4a'];
+ if (imgs.includes(ext)) return 'image';
+ if (vids.includes(ext)) return 'video';
+ if (auds.includes(ext)) return 'audio';
+ if (/(?:youtube\.com\/watch\?.*v=|youtu\.be\/)([A-Za-z0-9_-]{11})/.test(url)) return 'youtube';
+ if (/vimeo\.com\/(\d+)/.test(url)) return 'vimeo';
+ return 'link';
+}
+
+function getYTId(url) {
+ const m = url.match(/(?:v=|youtu\.be\/)([A-Za-z0-9_-]{11})/);
+ return m ? m[1] : null;
+}
+function getVimeoId(url) {
+ const m = url.match(/vimeo\.com\/(\d+)/);
+ return m ? m[1] : null;
+}
+
+function updateBadge(type) {
+ const b = document.getElementById('type-badge');
+ b.textContent = type;
+}
+
+function updatePreview(url) {
+ const body = document.getElementById('preview-body');
+ if (!url) { body.innerHTML = '<p class="preview-empty">// no url set</p>'; return; }
+ const type = detectType(url);
+ const safeUrl = url.replace(/"/g, '%22');
+ let html = `<div class="preview-url"><a href="${safeUrl}" target="_blank" rel="noopener noreferrer">${url}</a></div>`;
+ if (type === 'image') {
+ html += `<img src="${safeUrl}" alt="vibe preview" loading="lazy" class="vibe-preview-media">`;
+ } else if (type === 'video') {
+ html += `<video controls preload="none" class="vibe-preview-media"><source src="${safeUrl}"></video>`;
+ } else if (type === 'audio') {
+ html += `<audio controls preload="none" class="vibe-preview-audio"><source src="${safeUrl}"></audio>`;
+ } else if (type === 'youtube') {
+ const id = getYTId(url);
+ if (id) html += `<div class="ratio-wrap"><iframe src="https://www.youtube.com/embed/${id}" allowfullscreen loading="lazy"></iframe></div>`;
+ } else if (type === 'vimeo') {
+ const id = getVimeoId(url);
+ if (id) html += `<div class="ratio-wrap"><iframe src="https://player.vimeo.com/video/${id}" allowfullscreen loading="lazy"></iframe></div>`;
+ } else {
+ html += `<a href="${safeUrl}" target="_blank" rel="noopener noreferrer" class="vibe-preview-link">${url}</a>`;
+ }
+ body.innerHTML = html;
+ updateBadge(type);
+}
+
+const urlInput = document.getElementById('url');
+let debounce;
+urlInput.addEventListener('input', () => {
+ clearTimeout(debounce);
+ debounce = setTimeout(() => updatePreview(urlInput.value.trim()), 400);
+});
+
+document.querySelectorAll('.preset-btn').forEach(btn => {
+ btn.addEventListener('click', () => {
+ const url = btn.dataset.url;
+ const desc = btn.dataset.desc;
+ urlInput.value = url;
+ if (desc) document.getElementById('description').value = desc;
+ updatePreview(url);
+ });
+});