swipe bug fix
This commit is contained in:
@@ -4,15 +4,16 @@ import { createPortal } from 'react-dom';
|
||||
export default function ImageLightbox({ src, onClose }) {
|
||||
const overlayRef = useRef(null);
|
||||
|
||||
// Close on Escape
|
||||
// Close on Escape; signal global pinch handler to stand down while open
|
||||
useEffect(() => {
|
||||
const handler = (e) => { if (e.key === 'Escape') onClose(); };
|
||||
window.addEventListener('keydown', handler);
|
||||
// Prevent body scroll while open
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.documentElement.dataset.lightboxOpen = '1';
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handler);
|
||||
document.body.style.overflow = '';
|
||||
delete document.documentElement.dataset.lightboxOpen;
|
||||
};
|
||||
}, [onClose]);
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ if ('serviceWorker' in navigator) {
|
||||
|
||||
document.addEventListener('touchmove', function (e) {
|
||||
if (e.touches.length === 2 && pinchStartDist !== null) {
|
||||
// Two-finger pinch: scale fonts, not viewport
|
||||
// Two-finger pinch: scale fonts, not viewport.
|
||||
// Skip when a lightbox is open — let the browser handle pinch natively there.
|
||||
if (document.documentElement.dataset.lightboxOpen) return;
|
||||
e.preventDefault();
|
||||
const ratio = getTouchDist(e) / pinchStartDist;
|
||||
const newScale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, pinchStartScale * ratio));
|
||||
|
||||
@@ -455,11 +455,15 @@ export default function Chat() {
|
||||
setUnreadGroups(prev => { const next = new Map(prev); next.delete(id); return next; });
|
||||
};
|
||||
|
||||
// Establish one history sentinel on mount (mobile only) so back gestures are
|
||||
// always interceptable without accumulating extra entries.
|
||||
// Establish two history entries on mount (mobile only):
|
||||
// floor — marks the true exit point; always stays below the sentinel
|
||||
// sentinel — intercepted by handlePopState on every back gesture
|
||||
// Two entries are required so that iOS fires popstate (same-document navigation)
|
||||
// before exiting, giving the handler a chance to push a new sentinel.
|
||||
useEffect(() => {
|
||||
if (window.innerWidth < 768) {
|
||||
window.history.replaceState({ rc: 'chat' }, '');
|
||||
window.history.replaceState({ rc: 'floor' }, '');
|
||||
window.history.pushState({ rc: 'chat' }, '');
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -486,8 +490,11 @@ export default function Chat() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Already at root (Messages list, no chat open) — let the browser handle
|
||||
// it so the next gesture actually exits the PWA. Don't re-push.
|
||||
// Already at root (Messages list, no chat open) — we just popped the sentinel
|
||||
// and are now on the floor entry. Step one more back so the browser exits the
|
||||
// PWA (or navigates to the previous URL). Without this explicit go(-1), iOS
|
||||
// leaves the user stranded on the invisible floor state.
|
||||
window.history.go(-1);
|
||||
};
|
||||
window.addEventListener('popstate', handlePopState);
|
||||
return () => window.removeEventListener('popstate', handlePopState);
|
||||
|
||||
Reference in New Issue
Block a user