restore mobile swipe navigation in modal
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import clsx from 'clsx';
|
||||
import React, { type RefCallback, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { type RefCallback, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { fetchStatusWithContext } from 'pl-fe/actions/statuses';
|
||||
@ -119,6 +119,40 @@ const MediaModal: React.FC<MediaModalProps & BaseModalProps> = (props) => {
|
||||
}
|
||||
}, [handleChangeIndex, index]);
|
||||
|
||||
// Touch swipe handling
|
||||
const touchStartX = useRef<number | null>(null);
|
||||
const touchStartY = useRef<number | null>(null);
|
||||
const carouselRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleTouchStart = useCallback((e: React.TouchEvent) => {
|
||||
if (zoomedIn) return;
|
||||
touchStartX.current = e.touches[0].clientX;
|
||||
touchStartY.current = e.touches[0].clientY;
|
||||
}, [zoomedIn]);
|
||||
|
||||
const handleTouchEnd = useCallback((e: React.TouchEvent) => {
|
||||
if (zoomedIn || touchStartX.current === null || touchStartY.current === null) return;
|
||||
|
||||
const touchEndX = e.changedTouches[0].clientX;
|
||||
const touchEndY = e.changedTouches[0].clientY;
|
||||
const deltaX = touchEndX - touchStartX.current;
|
||||
const deltaY = touchEndY - touchStartY.current;
|
||||
|
||||
// Only trigger if horizontal swipe is greater than vertical (to avoid conflicts with scroll)
|
||||
// and if the swipe distance is significant enough
|
||||
const minSwipeDistance = 50;
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > minSwipeDistance) {
|
||||
if (deltaX > 0) {
|
||||
handleChangeIndex(index - 1); // Swipe right = previous
|
||||
} else {
|
||||
handleChangeIndex(index + 1); // Swipe left = next
|
||||
}
|
||||
}
|
||||
|
||||
touchStartX.current = null;
|
||||
touchStartY.current = null;
|
||||
}, [zoomedIn, handleChangeIndex, index]);
|
||||
|
||||
const handleDownload = () => {
|
||||
const mediaItem = hasMultipleImages ? media[index as number] : media[0];
|
||||
window.open(mediaItem?.url);
|
||||
@ -333,7 +367,12 @@ const MediaModal: React.FC<MediaModalProps & BaseModalProps> = (props) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='absolute inset-0 overflow-hidden'>
|
||||
<div
|
||||
ref={carouselRef}
|
||||
className='absolute inset-0 overflow-hidden'
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: `${media.length * 100}%`,
|
||||
|
||||
Reference in New Issue
Block a user