여행 기록 프론트 오류 수정
This commit is contained in:
@@ -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"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user