[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,32 +141,39 @@ export default function YouMayAlsoLike({
|
||||
} = product;
|
||||
|
||||
const handleItemClick = () => {
|
||||
dispatch(finishVideoPreview());
|
||||
dispatch(finishModalMediaForce());
|
||||
// Promise 체이닝으로 순서 보장 (Chrome 68, 87 호환성)
|
||||
Promise.resolve()
|
||||
.then(() => {
|
||||
// 1. 기존 비디오 강제 종료
|
||||
dispatch(finishVideoPreview());
|
||||
dispatch(finishModalMediaForce());
|
||||
|
||||
if (themeProductInfos && themeProductInfos.length > 0) {
|
||||
dispatch(clearThemeDetail());
|
||||
}
|
||||
|
||||
// popPanel + pushPanel 대신 updatePanel 사용
|
||||
// DetailPanel을 언마운트하지 않고 상품 정보만 업데이트
|
||||
// 이렇게 하면 백그라운드 비디오 제어 상태가 유지됨
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: {
|
||||
showNm: panelInfo?.showNm,
|
||||
showId: panelInfo?.showId,
|
||||
liveFlag: panelInfo?.liveFlag,
|
||||
thumbnailUrl: panelInfo?.thumbnailUrl,
|
||||
patnrId,
|
||||
prdtId,
|
||||
launchedFromPlayer: launchedFromPlayer,
|
||||
bgVideoInfo: bgVideoInfo, // 백그라운드 비디오 정보 유지
|
||||
},
|
||||
if (themeProductInfos && themeProductInfos.length > 0) {
|
||||
dispatch(clearThemeDetail());
|
||||
}
|
||||
})
|
||||
);
|
||||
cursorOpen.current.stop();
|
||||
.then(() => {
|
||||
// 2. 비디오 종료 후 새로운 상품으로 업데이트
|
||||
// popPanel + pushPanel 대신 updatePanel 사용
|
||||
// DetailPanel을 언마운트하지 않고 상품 정보만 업데이트
|
||||
// 이렇게 하면 백그라운드 비디오 제어 상태가 유지됨
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: {
|
||||
showNm: panelInfo?.showNm,
|
||||
showId: panelInfo?.showId,
|
||||
liveFlag: panelInfo?.liveFlag,
|
||||
thumbnailUrl: panelInfo?.thumbnailUrl,
|
||||
patnrId,
|
||||
prdtId,
|
||||
launchedFromPlayer: launchedFromPlayer,
|
||||
bgVideoInfo: bgVideoInfo, // 백그라운드 비디오 정보 유지
|
||||
},
|
||||
})
|
||||
);
|
||||
cursorOpen.current.stop();
|
||||
});
|
||||
};
|
||||
// prdtId가 없는 경우를 대비한 안정적인 key 생성
|
||||
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 { useDispatch, useSelector } from 'react-redux';
|
||||
@@ -30,8 +30,12 @@ export default function FavoriteBtn({
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
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(
|
||||
sendLogTotalRecommend({
|
||||
menu: logMenu,
|
||||
@@ -61,10 +65,34 @@ export default function FavoriteBtn({
|
||||
}
|
||||
}, [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(() => {
|
||||
setTimeout(() => Spotlight.focus('favoriteBtn'));
|
||||
dispatch(setHidePopup());
|
||||
onFavoriteFlagChanged(favoriteFlag === 'Y' ? 'N' : 'Y');
|
||||
clickLockRef.current = false;
|
||||
}, [dispatch, favoriteFlag, onFavoriteFlagChanged]);
|
||||
|
||||
const handleSpotlightDown = useCallback(
|
||||
@@ -96,7 +124,8 @@ export default function FavoriteBtn({
|
||||
role="button"
|
||||
aria-label="Register in Favorites"
|
||||
tabIndex={0}
|
||||
onClick={handleFavoriteClick}
|
||||
onMouseUp={handleMouseUp}
|
||||
onClick={handleClick}
|
||||
onSpotlightDown={handleSpotlightDown}
|
||||
data-spotlight-next-down={
|
||||
kind === 'item_detail' ? nextDownId || 'product-details-button' : undefined
|
||||
|
||||
Reference in New Issue
Block a user