diff --git a/public/s/css/f0ckm.css b/public/s/css/f0ckm.css index e139058..a3871e4 100644 --- a/public/s/css/f0ckm.css +++ b/public/s/css/f0ckm.css @@ -5649,6 +5649,33 @@ body[type='login'] { padding: 0; } +/* Hold-to-preview sticker overlay */ +.sticker-preview-overlay { + position: fixed; + inset: 0; + z-index: 99999; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.8); + pointer-events: none; + opacity: 0; + transition: opacity 0.12s ease; +} +.sticker-preview-overlay.visible { + opacity: 1; +} +.sticker-preview-overlay img, +.sticker-preview-overlay video { + max-width: min(85vw, 420px); + max-height: min(85vh, 420px); + width: auto; + height: auto; + object-fit: contain; + border-radius: 12px; + box-shadow: 0 8px 40px rgba(0, 0, 0, 0.6); +} + .emoji-picker img { width: 60px; height: 60px; @@ -5690,7 +5717,6 @@ body[type='login'] { background: transparent; cursor: pointer; opacity: 0.55; - border-radius: 6px; padding: 4px; } diff --git a/public/s/js/comments.js b/public/s/js/comments.js index 5c4c3c0..dd64d85 100644 --- a/public/s/js/comments.js +++ b/public/s/js/comments.js @@ -4014,6 +4014,30 @@ class CommentSystem { let picker = null; let closeHandler = null; + // ── Shared sticker hold-to-preview overlay ──────────────────────── + if (!window.stickerPreview) { + const overlay = document.createElement('div'); + overlay.className = 'sticker-preview-overlay'; + document.body.appendChild(overlay); + let _hideTimer = null; + window.stickerPreview = { + show(src, isVideo) { + clearTimeout(_hideTimer); + overlay.innerHTML = ''; + const el = isVideo ? document.createElement('video') : document.createElement('img'); + el.src = src; + if (isVideo) { el.autoplay = true; el.loop = true; el.muted = true; el.playsInline = true; } + overlay.appendChild(el); + overlay.classList.add('visible'); + if (isVideo) el.play().catch(() => {}); + }, + hide() { + overlay.classList.remove('visible'); + _hideTimer = setTimeout(() => { overlay.innerHTML = ''; }, 200); + } + }; + } + const buildPickerContent = () => { if (!picker) return; picker.innerHTML = ''; @@ -4028,8 +4052,9 @@ class CommentSystem { // Helper: create img or video element for a given emoji URL const makeEmojiEl = (url, name) => { + const isVideo = url && url.endsWith('.webm'); let el; - if (url && url.endsWith('.webm')) { + if (isVideo) { el = document.createElement('video'); el.src = url; el.autoplay = true; @@ -4043,6 +4068,17 @@ class CommentSystem { } el.title = `:${name}:`; el.onerror = () => { el.style.display = 'none'; }; + // Hold-to-preview + let holdTimer = null; + const startHold = () => { holdTimer = setTimeout(() => window.stickerPreview?.show(url, isVideo), 400); }; + const cancelHold = () => { clearTimeout(holdTimer); }; + const endHold = () => { clearTimeout(holdTimer); window.stickerPreview?.hide(); }; + el.addEventListener('mousedown', startHold); + el.addEventListener('mouseup', endHold); + el.addEventListener('mouseleave', cancelHold); + el.addEventListener('touchstart', startHold, { passive: true }); + el.addEventListener('touchend', endHold); + el.addEventListener('touchcancel', endHold); return el; }; diff --git a/public/s/js/messages.js b/public/s/js/messages.js index 7a5effb..15ea2bf 100644 --- a/public/s/js/messages.js +++ b/public/s/js/messages.js @@ -1768,8 +1768,9 @@ if (window.__dmLoaded) { // ── Helper: img or video element for a given emoji URL ──────────────── function makeDmEmojiEl(url, name) { + const isVideo = url && url.endsWith('.webm'); let el; - if (url && url.endsWith('.webm')) { + if (isVideo) { el = document.createElement('video'); el.src = url; el.autoplay = true; @@ -1783,6 +1784,17 @@ if (window.__dmLoaded) { } el.title = `:${name}:`; el.onerror = () => { el.style.display = 'none'; }; + // Hold-to-preview (uses shared window.stickerPreview from comments.js) + let holdTimer = null; + const startHold = () => { holdTimer = setTimeout(() => window.stickerPreview?.show(url, isVideo), 400); }; + const cancelHold = () => { clearTimeout(holdTimer); }; + const endHold = () => { clearTimeout(holdTimer); window.stickerPreview?.hide(); }; + el.addEventListener('mousedown', startHold); + el.addEventListener('mouseup', endHold); + el.addEventListener('mouseleave', cancelHold); + el.addEventListener('touchstart', startHold, { passive: true }); + el.addEventListener('touchend', endHold); + el.addEventListener('touchcancel', endHold); return el; }