여행 기록 프론트 오류 수정

This commit is contained in:
2026-01-26 02:07:33 +09:00
parent bca9724a4b
commit d53f581c58
2 changed files with 83 additions and 48 deletions

View File

@@ -172,7 +172,9 @@ const Travel = () => {
const [regionsGeojson, setRegionsGeojson] = useState(null);
const [selectedPhotoIndex, setSelectedPhotoIndex] = useState(null);
const [modalOffset, setModalOffset] = useState(24);
const [touchStartX, setTouchStartX] = useState(null);
const touchStartXRef = useRef(null);
const [slideDirection, setSlideDirection] = useState('next');
const [slideToken, setSlideToken] = useState(0);
const [page, setPage] = useState(1);
const [hasNext, setHasNext] = useState(true);
const cacheRef = useRef(new Map());
@@ -366,6 +368,28 @@ const Travel = () => {
}
}, [hasNext, loading, loadingMore, page, photoSummary, selectedRegion]);
const bumpSlide = (direction) => {
setSlideDirection(direction);
setSlideToken((prev) => prev + 1);
};
const goPrev = useCallback(() => {
if (selectedPhotoIndex === null || selectedPhotoIndex <= 0) return;
bumpSlide('prev');
setSelectedPhotoIndex(selectedPhotoIndex - 1);
}, [selectedPhotoIndex]);
const goNext = useCallback(() => {
if (
selectedPhotoIndex === null ||
selectedPhotoIndex >= photos.length - 1
) {
return;
}
bumpSlide('next');
setSelectedPhotoIndex(selectedPhotoIndex + 1);
}, [photos.length, selectedPhotoIndex]);
useEffect(() => {
if (selectedPhotoIndex === null) return undefined;
@@ -375,45 +399,34 @@ const Travel = () => {
return;
}
if (event.key === 'ArrowLeft') {
setSelectedPhotoIndex((prev) =>
prev === null
? prev
: (prev - 1 + photos.length) % photos.length
);
goPrev();
}
if (event.key === 'ArrowRight') {
setSelectedPhotoIndex((prev) =>
prev === null ? prev : (prev + 1) % photos.length
);
goNext();
}
};
const handleTouchStart = (event) => {
if (selectedPhotoIndex === null) return;
const touch = event.touches[0];
setTouchStartX(touch.clientX);
touchStartXRef.current = touch.clientX;
};
const handleTouchEnd = (event) => {
if (selectedPhotoIndex === null || touchStartX === null) return;
if (selectedPhotoIndex === null || touchStartXRef.current === null)
return;
const touch = event.changedTouches[0];
const deltaX = touch.clientX - touchStartX;
const deltaX = touch.clientX - touchStartXRef.current;
if (Math.abs(deltaX) > 50) { // 스와이프 거리 임계값
if (deltaX > 0) {
// 왼쪽으로 스와이프: 이전 사진
setSelectedPhotoIndex((prev) =>
prev === null
? prev
: (prev - 1 + photos.length) % photos.length
);
goPrev();
} else {
// 오른쪽으로 스와이프: 다음 사진
setSelectedPhotoIndex((prev) =>
prev === null ? prev : (prev + 1) % photos.length
);
goNext();
}
}
setTouchStartX(null);
touchStartXRef.current = null;
};
window.addEventListener('keydown', handleKeyDown);
@@ -424,7 +437,7 @@ const Travel = () => {
window.removeEventListener('touchstart', handleTouchStart);
window.removeEventListener('touchend', handleTouchEnd);
};
}, [photos.length, selectedPhotoIndex]);
}, [goNext, goPrev, selectedPhotoIndex]);
useEffect(() => {
if (selectedPhotoIndex === null) return undefined;
@@ -441,6 +454,11 @@ const Travel = () => {
: getStripRange(photos.length, selectedPhotoIndex);
const handleSelectPhoto = (index, event) => {
if (selectedPhotoIndex === null) {
bumpSlide('next');
} else if (index !== selectedPhotoIndex) {
bumpSlide(index > selectedPhotoIndex ? 'next' : 'prev');
}
if (event) {
const pointY =
typeof event.clientY === 'number'
@@ -571,26 +589,20 @@ const Travel = () => {
<button
type="button"
className="travel-modal__arrow is-prev"
onClick={() =>
setSelectedPhotoIndex((prev) =>
prev === null
? prev
: (prev - 1 + photos.length) %
photos.length
)
}
onClick={goPrev}
disabled={selectedPhotoIndex === 0}
aria-label="Previous"
>
{'<'}
</button>
<div className="travel-modal__frame">
<img
key={
photos[selectedPhotoIndex]?.original ||
photos[selectedPhotoIndex]?.src ||
selectedPhotoIndex
}
className="travel-modal__image"
key={`${selectedPhotoIndex}-${slideToken}`}
className={`travel-modal__image ${
slideDirection === 'prev'
? 'is-prev'
: 'is-next'
}`}
src={
photos[selectedPhotoIndex]?.original ||
photos[selectedPhotoIndex]?.src
@@ -609,12 +621,9 @@ const Travel = () => {
<button
type="button"
className="travel-modal__arrow is-next"
onClick={() =>
setSelectedPhotoIndex((prev) =>
prev === null
? prev
: (prev + 1) % photos.length
)
onClick={goNext}
disabled={
selectedPhotoIndex === photos.length - 1
}
aria-label="Next"
>