[251123] fix: FavoriteButton , YouMayAlsoClickj
🕐 커밋 시간: 2025. 11. 23. 20:51:57 📊 변경 통계: • 총 파일: 2개 • 추가: +64줄 • 삭제: -28줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx ~ com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx (javascript): 🔄 Modified: SpotlightContainerDecorator() 📄 com.twin.app.shoptime/src/views/DetailPanel/components/FavoriteBtn.jsx (javascript): 🔄 Modified: Spottable() 🔧 주요 변경 내용: • UI 컴포넌트 아키텍처 개선
This commit is contained in:
@@ -141,13 +141,19 @@ export default function YouMayAlsoLike({
|
|||||||
} = product;
|
} = product;
|
||||||
|
|
||||||
const handleItemClick = () => {
|
const handleItemClick = () => {
|
||||||
|
// Promise 체이닝으로 순서 보장 (Chrome 68, 87 호환성)
|
||||||
|
Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
// 1. 기존 비디오 강제 종료
|
||||||
dispatch(finishVideoPreview());
|
dispatch(finishVideoPreview());
|
||||||
dispatch(finishModalMediaForce());
|
dispatch(finishModalMediaForce());
|
||||||
|
|
||||||
if (themeProductInfos && themeProductInfos.length > 0) {
|
if (themeProductInfos && themeProductInfos.length > 0) {
|
||||||
dispatch(clearThemeDetail());
|
dispatch(clearThemeDetail());
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// 2. 비디오 종료 후 새로운 상품으로 업데이트
|
||||||
// popPanel + pushPanel 대신 updatePanel 사용
|
// popPanel + pushPanel 대신 updatePanel 사용
|
||||||
// DetailPanel을 언마운트하지 않고 상품 정보만 업데이트
|
// DetailPanel을 언마운트하지 않고 상품 정보만 업데이트
|
||||||
// 이렇게 하면 백그라운드 비디오 제어 상태가 유지됨
|
// 이렇게 하면 백그라운드 비디오 제어 상태가 유지됨
|
||||||
@@ -167,6 +173,7 @@ export default function YouMayAlsoLike({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
cursorOpen.current.stop();
|
cursorOpen.current.stop();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
// prdtId가 없는 경우를 대비한 안정적인 key 생성
|
// prdtId가 없는 경우를 대비한 안정적인 key 생성
|
||||||
const itemKey = prdtId ? `${patnrId}-${prdtId}` : `product-${index}`;
|
const itemKey = prdtId ? `${patnrId}-${prdtId}` : `product-${index}`;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useRef } from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
@@ -30,8 +30,12 @@ export default function FavoriteBtn({
|
|||||||
}) {
|
}) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { popupVisible, activePopup } = useSelector((state) => state.common.popup);
|
const { popupVisible, activePopup } = useSelector((state) => state.common.popup);
|
||||||
|
const clickLockRef = useRef(false);
|
||||||
|
|
||||||
|
const handleFavoriteActivate = useCallback(() => {
|
||||||
|
if (clickLockRef.current) return;
|
||||||
|
clickLockRef.current = true;
|
||||||
|
|
||||||
const handleFavoriteClick = useCallback(() => {
|
|
||||||
dispatch(
|
dispatch(
|
||||||
sendLogTotalRecommend({
|
sendLogTotalRecommend({
|
||||||
menu: logMenu,
|
menu: logMenu,
|
||||||
@@ -61,10 +65,34 @@ export default function FavoriteBtn({
|
|||||||
}
|
}
|
||||||
}, [dispatch, favoriteFlag, selectedPatnrId, selectedPrdtId, logMenu]);
|
}, [dispatch, favoriteFlag, selectedPatnrId, selectedPrdtId, logMenu]);
|
||||||
|
|
||||||
|
const handleMouseUp = useCallback(
|
||||||
|
(event) => {
|
||||||
|
// 실제 마우스 클릭(detail > 0)만 처리하고 키보드에서 전달된 mouse 이벤트(detail === 0)는 무시
|
||||||
|
if (event?.detail === 0) return;
|
||||||
|
if (event.button !== 0) return;
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
handleFavoriteActivate();
|
||||||
|
},
|
||||||
|
[handleFavoriteActivate]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleClick = useCallback(
|
||||||
|
(event) => {
|
||||||
|
// 키보드(Enter)에서 발생하는 click(detail === 0)만 처리
|
||||||
|
if (event?.detail !== 0) return;
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
handleFavoriteActivate();
|
||||||
|
},
|
||||||
|
[handleFavoriteActivate]
|
||||||
|
);
|
||||||
|
|
||||||
const PopUpOnClick = useCallback(() => {
|
const PopUpOnClick = useCallback(() => {
|
||||||
setTimeout(() => Spotlight.focus('favoriteBtn'));
|
setTimeout(() => Spotlight.focus('favoriteBtn'));
|
||||||
dispatch(setHidePopup());
|
dispatch(setHidePopup());
|
||||||
onFavoriteFlagChanged(favoriteFlag === 'Y' ? 'N' : 'Y');
|
onFavoriteFlagChanged(favoriteFlag === 'Y' ? 'N' : 'Y');
|
||||||
|
clickLockRef.current = false;
|
||||||
}, [dispatch, favoriteFlag, onFavoriteFlagChanged]);
|
}, [dispatch, favoriteFlag, onFavoriteFlagChanged]);
|
||||||
|
|
||||||
const handleSpotlightDown = useCallback(
|
const handleSpotlightDown = useCallback(
|
||||||
@@ -96,7 +124,8 @@ export default function FavoriteBtn({
|
|||||||
role="button"
|
role="button"
|
||||||
aria-label="Register in Favorites"
|
aria-label="Register in Favorites"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={handleFavoriteClick}
|
onMouseUp={handleMouseUp}
|
||||||
|
onClick={handleClick}
|
||||||
onSpotlightDown={handleSpotlightDown}
|
onSpotlightDown={handleSpotlightDown}
|
||||||
data-spotlight-next-down={
|
data-spotlight-next-down={
|
||||||
kind === 'item_detail' ? nextDownId || 'product-details-button' : undefined
|
kind === 'item_detail' ? nextDownId || 'product-details-button' : undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user