This commit is contained in:
2026-07-16 02:12:58 +02:00
parent 0b22a1b590
commit 93e8a39a40
2 changed files with 43 additions and 8 deletions

View File

@@ -5802,6 +5802,16 @@ body[type='login'] {
cursor: pointer; cursor: pointer;
border-radius: 4px; border-radius: 4px;
box-sizing: border-box; box-sizing: border-box;
/* Suppress native mobile long-press menu (save image, copy link, etc.) */
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
.ep-sticker-wrap img,
.ep-sticker-wrap video {
-webkit-touch-callout: none;
-webkit-user-select: none;
} }
.ep-sticker-wrap:hover { .ep-sticker-wrap:hover {

View File

@@ -4022,7 +4022,9 @@ class CommentSystem {
let _hideTimer = null; let _hideTimer = null;
window.stickerPreview = { window.stickerPreview = {
isShowing: false, isShowing: false,
_autoHideTimer: null,
show(src, isVideo, name, url) { show(src, isVideo, name, url) {
clearTimeout(this._autoHideTimer);
clearTimeout(_hideTimer); clearTimeout(_hideTimer);
overlay.innerHTML = ''; overlay.innerHTML = '';
const el = isVideo ? document.createElement('video') : document.createElement('img'); const el = isVideo ? document.createElement('video') : document.createElement('img');
@@ -4051,16 +4053,29 @@ class CommentSystem {
if (isVideo) el.play().catch(() => {}); if (isVideo) el.play().catch(() => {});
}, },
hide() { hide() {
clearTimeout(this._autoHideTimer);
this._autoHideTimer = null;
this.isShowing = false; this.isShowing = false;
overlay.classList.remove('visible'); overlay.classList.remove('visible');
_hideTimer = setTimeout(() => { overlay.innerHTML = ''; }, 200); _hideTimer = setTimeout(() => { overlay.innerHTML = ''; }, 200);
},
// Auto-close after delay (used on mobile so user has time to tap the fav button)
scheduleHide(delay) {
clearTimeout(this._autoHideTimer);
this._autoHideTimer = setTimeout(() => {
this._autoHideTimer = null;
this.hide();
}, delay);
} }
}; };
// Click/tap overlay background to dismiss // Click/tap overlay background to dismiss
overlay.addEventListener('click', () => window.stickerPreview.hide()); overlay.addEventListener('click', () => window.stickerPreview.hide());
// Global mouseup: dismiss if released outside // Desktop safety net: if mouse released outside the sticker, hide preview
// (skipped if a mobile scheduleHide is already pending)
document.addEventListener('mouseup', () => { document.addEventListener('mouseup', () => {
if (window.stickerPreview.isShowing) window.stickerPreview.hide(); if (window.stickerPreview?.isShowing && !window.stickerPreview._autoHideTimer) {
window.stickerPreview.hide();
}
}); });
} }
@@ -4179,15 +4194,17 @@ class CommentSystem {
let holdTimer = null; let holdTimer = null;
let holdFired = false; let holdFired = false;
let favHoldFired = false; let favHoldFired = false;
const startHold = () => { let isTouchHold = false;
const startHold = (fromTouch) => {
holdFired = false; holdFired = false;
favHoldFired = false; favHoldFired = false;
isTouchHold = !!fromTouch;
holdTimer = setTimeout(() => { holdTimer = setTimeout(() => {
holdFired = true; holdFired = true;
window.stickerPreview?.show(url, isVideo, name, url); window.stickerPreview?.show(url, isVideo, name, url);
}, 400); }, 400);
}; };
const cancelHold = () => { clearTimeout(holdTimer); }; const cancelHold = () => { clearTimeout(holdTimer); isTouchHold = false; };
const endHold = () => { const endHold = () => {
clearTimeout(holdTimer); clearTimeout(holdTimer);
if (holdFired || favHoldFired) { if (holdFired || favHoldFired) {
@@ -4197,16 +4214,24 @@ class CommentSystem {
e.stopImmediatePropagation(); e.stopImmediatePropagation();
e.preventDefault(); e.preventDefault();
}, { once: true, capture: true }); }, { once: true, capture: true });
if (isTouchHold) {
// Mobile: linger so user can tap the fav ★ button
window.stickerPreview?.scheduleHide(1800);
} else {
window.stickerPreview?.hide();
}
} else {
window.stickerPreview?.hide();
} }
window.stickerPreview?.hide(); isTouchHold = false;
}; };
media.addEventListener('mousedown', startHold); media.addEventListener('mousedown', () => startHold(false));
media.addEventListener('mouseup', endHold); media.addEventListener('mouseup', endHold);
media.addEventListener('mouseleave', cancelHold); media.addEventListener('mouseleave', cancelHold);
media.addEventListener('mouseenter', () => { media.addEventListener('mouseenter', () => {
if (window.stickerPreview?.isShowing) window.stickerPreview.show(url, isVideo); if (window.stickerPreview?.isShowing) window.stickerPreview.show(url, isVideo, name, url);
}); });
media.addEventListener('touchstart', startHold, { passive: true }); media.addEventListener('touchstart', () => startHold(true), { passive: true });
media.addEventListener('touchend', endHold); media.addEventListener('touchend', endHold);
media.addEventListener('touchcancel', endHold); media.addEventListener('touchcancel', endHold);
// Right-click (desktop) → favorites; suppressed on mobile when hold gesture is active // Right-click (desktop) → favorites; suppressed on mobile when hold gesture is active