[251120] fix: PlayerPanel Return Video Playback
🕐 커밋 시간: 2025. 11. 20. 12:29:35 📊 변경 통계: • 총 파일: 5개 • 추가: +270줄 • 삭제: -97줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/panelActions.js ~ com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx ~ com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.jsx 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 대규모 기능 개발
This commit is contained in:
@@ -17,6 +17,8 @@ export const SOURCE_MENUS = {
|
|||||||
HOME_GENERAL: 'home_general',
|
HOME_GENERAL: 'home_general',
|
||||||
THEMED_PRODUCT: 'themed_product',
|
THEMED_PRODUCT: 'themed_product',
|
||||||
GENERAL_PRODUCT: 'general_product',
|
GENERAL_PRODUCT: 'general_product',
|
||||||
|
PLAYER_SHOP_NOW: 'player_shop_now', // PlayerPanel의 ShopNow에서 진입
|
||||||
|
PLAYER_MEDIA: 'player_media', // PlayerPanel의 Media에서 진입
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -218,6 +220,7 @@ export const navigateToDetail = ({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
panelInfo.sourcePanel = panel_names.HOME_PANEL; // ✅ source panel 정보
|
||||||
panelInfo.fromHome = true;
|
panelInfo.fromHome = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -236,14 +239,35 @@ export const navigateToDetail = ({
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
panelInfo.sourcePanel = panel_names.SEARCH_PANEL; // ✅ source panel 정보
|
||||||
panelInfo.fromSearch = true;
|
panelInfo.fromSearch = true;
|
||||||
panelInfo.searchQuery = additionalInfo.searchVal;
|
panelInfo.searchQuery = additionalInfo.searchVal;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_MENUS.THEMED_PRODUCT:
|
case SOURCE_MENUS.THEMED_PRODUCT:
|
||||||
// 테마 상품: 별도 처리 필요할 경우
|
// 테마 상품: 별도 처리 필요할 경우
|
||||||
|
panelInfo.sourcePanel = panel_names.HOME_PANEL; // ✅ source panel 정보 (HOME으로 간주)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SOURCE_MENUS.PLAYER_SHOP_NOW:
|
||||||
|
case SOURCE_MENUS.PLAYER_MEDIA: {
|
||||||
|
// PlayerPanel에서 온 경우
|
||||||
|
const { hidePlayerOverlays } = require('./videoPlayActions');
|
||||||
|
|
||||||
|
// DetailPanel push 전에 VideoPlayer 오버레이 숨김
|
||||||
|
dispatch(hidePlayerOverlays());
|
||||||
|
|
||||||
|
// 현재 포커스된 요소 저장
|
||||||
|
if (Object.keys(focusSnapshot).length > 0) {
|
||||||
|
panelInfo.lastFocusedTargetId = focusSnapshot.lastFocusedTargetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PlayerPanel 정보 보존 (복귀 시 필요)
|
||||||
|
panelInfo.sourcePanel = panel_names.PLAYER_PANEL; // ✅ source panel 정보
|
||||||
|
panelInfo.fromPlayer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SOURCE_MENUS.GENERAL_PRODUCT:
|
case SOURCE_MENUS.GENERAL_PRODUCT:
|
||||||
default:
|
default:
|
||||||
// 일반 상품: 기본 처리
|
// 일반 상품: 기본 처리
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ import {
|
|||||||
finishVideoPreview,
|
finishVideoPreview,
|
||||||
pauseFullscreenVideo,
|
pauseFullscreenVideo,
|
||||||
resumeFullscreenVideo,
|
resumeFullscreenVideo,
|
||||||
|
pauseModalVideo,
|
||||||
|
resumeModalVideo,
|
||||||
} from '../../actions/playActions';
|
} from '../../actions/playActions';
|
||||||
import {
|
import {
|
||||||
clearProductDetail,
|
clearProductDetail,
|
||||||
@@ -159,62 +161,175 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
}));
|
}));
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
// ✅ [251118] DetailPanel이 사라질 때 HomePanel 활성화
|
// ✅ [251120] DetailPanel이 사라질 때 처리 - sourcePanel에 따라 switch 문으로 처리
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
|
const sourcePanel = panelInfo?.sourcePanel;
|
||||||
|
const sourceMenu = panelInfo?.sourceMenu;
|
||||||
|
|
||||||
// DetailPanel이 unmount되는 시점
|
// DetailPanel이 unmount되는 시점
|
||||||
console.log('[DetailPanel] unmount - HomePanel 활성화 신호 전송');
|
console.log('[DetailPanel] unmount:', {
|
||||||
|
sourcePanel,
|
||||||
|
sourceMenu,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
});
|
||||||
|
|
||||||
// HomePanel에서 비디오 재생을 다시 시작하도록 신호 보내기
|
// sourcePanel에 따른 상태 업데이트
|
||||||
console.log('[TRACE-GRADIENT] 🔶 DetailPanel unmount - Creating new panelInfo');
|
switch (sourcePanel) {
|
||||||
console.log('[TRACE-GRADIENT] 🔶 DetailPanel unmount - Existing panelInfo before update:', JSON.stringify(panelInfo));
|
case panel_names.PLAYER_PANEL: {
|
||||||
|
// PlayerPanel에서 온 경우: PlayerPanel에 detailPanelClosed flag 전달
|
||||||
dispatch(updateHomeInfo({
|
console.log('[DetailPanel] unmount - PlayerPanel에 detailPanelClosed flag 전달');
|
||||||
name: panel_names.HOME_PANEL,
|
dispatch(updatePanel({
|
||||||
panelInfo: {
|
name: panel_names.PLAYER_PANEL,
|
||||||
shouldResumeVideo: true, // ✅ 신호
|
panelInfo: {
|
||||||
lastDetailPanelClosed: Date.now(), // ✅ 시점 기록
|
detailPanelClosed: true, // ✅ flag
|
||||||
showGradientBackground: false, // ✅ 명시적으로 그라데이션 끔기
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
|
case panel_names.HOME_PANEL: {
|
||||||
|
// HomePanel에서 온 경우: HomePanel에 detailPanelClosed flag 전달
|
||||||
|
console.log('[DetailPanel] unmount - HomePanel에 detailPanelClosed flag 전달');
|
||||||
|
console.log('[TRACE-GRADIENT] 🔶 DetailPanel unmount - HomePanel 복귀');
|
||||||
|
|
||||||
|
dispatch(updateHomeInfo({
|
||||||
|
name: panel_names.HOME_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
detailPanelClosed: true, // ✅ flag
|
||||||
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
|
showGradientBackground: false, // ✅ 명시적으로 그라데이션 끔기
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case panel_names.SEARCH_PANEL: {
|
||||||
|
// SearchPanel에서 온 경우: SearchPanel에 detailPanelClosed flag 전달
|
||||||
|
console.log('[DetailPanel] unmount - SearchPanel에 detailPanelClosed flag 전달');
|
||||||
|
dispatch(
|
||||||
|
updatePanel({
|
||||||
|
name: panel_names.SEARCH_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
detailPanelClosed: true, // ✅ flag
|
||||||
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn('[DetailPanel] unmount - 처리되지 않은 sourcePanel:', sourcePanel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}, [dispatch]);
|
}, [dispatch, panelInfo?.sourcePanel]);
|
||||||
|
|
||||||
const onBackClick = useCallback(
|
const onBackClick = useCallback(
|
||||||
(isCancelClick) => (ev) => {
|
(isCancelClick) => (ev) => {
|
||||||
|
const sourcePanel = panelInfo?.sourcePanel;
|
||||||
|
const sourceMenu = panelInfo?.sourceMenu;
|
||||||
|
|
||||||
fp.pipe(
|
fp.pipe(
|
||||||
() => {
|
() => {
|
||||||
dispatch(clearAllToasts()); // BuyOption Toast 포함 모든 토스트 제거
|
dispatch(clearAllToasts()); // BuyOption Toast 포함 모든 토스트 제거
|
||||||
dispatch(pauseFullscreenVideo()); // PLAYER_PANEL 비디오 중지
|
|
||||||
dispatch(finishModalMediaForce()); // MEDIA_PANEL(ProductVideo) 강제 종료
|
// sourcePanel에 따른 사전 처리
|
||||||
dispatch(finishVideoPreview());
|
switch (sourcePanel) {
|
||||||
|
case panel_names.PLAYER_PANEL:
|
||||||
|
// PlayerPanel에서 온 경우: 플레이어 비디오는 그대로 두고 모달만 정리
|
||||||
|
console.log('[DetailPanel] onBackClick - PlayerPanel 출신: 모달 정리만 수행');
|
||||||
|
dispatch(finishModalMediaForce()); // MEDIA_PANEL(ProductVideo) 강제 종료
|
||||||
|
dispatch(finishVideoPreview());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case panel_names.HOME_PANEL:
|
||||||
|
case panel_names.SEARCH_PANEL:
|
||||||
|
default:
|
||||||
|
// HomePanel, SearchPanel 등에서 온 경우: 백그라운드 비디오 일시 중지
|
||||||
|
console.log('[DetailPanel] onBackClick - source panel:', sourcePanel, '백그라운드 비디오 일시 중지');
|
||||||
|
dispatch(pauseFullscreenVideo()); // PLAYER_PANEL 비디오 중지
|
||||||
|
dispatch(finishModalMediaForce()); // MEDIA_PANEL(ProductVideo) 강제 종료
|
||||||
|
dispatch(finishVideoPreview());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(popPanel(panel_names.DETAIL_PANEL));
|
dispatch(popPanel(panel_names.DETAIL_PANEL));
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
// 패널 업데이트 조건 체크
|
// sourcePanel에 따른 상태 업데이트
|
||||||
const shouldUpdatePanel =
|
switch (sourcePanel) {
|
||||||
fp.pipe(
|
case panel_names.PLAYER_PANEL: {
|
||||||
() => panels,
|
// PlayerPanel에서 온 경우: PlayerPanel에 detailPanelClosed flag 전달
|
||||||
fp.get('length'),
|
const shouldUpdatePanel =
|
||||||
(length) => length === 4
|
fp.pipe(
|
||||||
)() &&
|
() => panels,
|
||||||
fp.pipe(
|
fp.get('length'),
|
||||||
() => panels,
|
(length) => length === 3 // PlayerPanel이 [1]에 있고 DetailPanel이 [2]에 있는 상태
|
||||||
fp.get('1.name'),
|
)() &&
|
||||||
(name) => name === panel_names.PLAYER_PANEL
|
fp.pipe(
|
||||||
)();
|
() => panels,
|
||||||
|
fp.get('1.name'),
|
||||||
|
(name) => name === panel_names.PLAYER_PANEL
|
||||||
|
)();
|
||||||
|
|
||||||
if (shouldUpdatePanel) {
|
if (shouldUpdatePanel) {
|
||||||
dispatch(
|
console.log('[DetailPanel] onBackClick - PlayerPanel에 detailPanelClosed flag 전달');
|
||||||
updatePanel({
|
dispatch(
|
||||||
name: panel_names.PLAYER_PANEL,
|
updatePanel({
|
||||||
|
name: panel_names.PLAYER_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
thumbnail: fp.pipe(() => panelInfo, fp.get('thumbnailUrl'))(),
|
||||||
|
detailPanelClosed: true, // ✅ flag
|
||||||
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case panel_names.HOME_PANEL: {
|
||||||
|
// HomePanel에서 온 경우: HomePanel에 detailPanelClosed flag 전달
|
||||||
|
console.log('[DetailPanel] onBackClick - HomePanel에 detailPanelClosed flag 전달');
|
||||||
|
dispatch(updateHomeInfo({
|
||||||
|
name: panel_names.HOME_PANEL,
|
||||||
panelInfo: {
|
panelInfo: {
|
||||||
thumbnail: fp.pipe(() => panelInfo, fp.get('thumbnailUrl'))(),
|
detailPanelClosed: true, // ✅ flag
|
||||||
},
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
})
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
);
|
showGradientBackground: false,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case panel_names.SEARCH_PANEL: {
|
||||||
|
// SearchPanel에서 온 경우: SearchPanel에 detailPanelClosed flag 전달
|
||||||
|
console.log('[DetailPanel] onBackClick - SearchPanel에 detailPanelClosed flag 전달');
|
||||||
|
dispatch(
|
||||||
|
updatePanel({
|
||||||
|
name: panel_names.SEARCH_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
detailPanelClosed: true, // ✅ flag
|
||||||
|
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||||
|
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn('[DetailPanel] onBackClick - 처리되지 않은 sourcePanel:', sourcePanel);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// PlayerPanel의 isOnTop useEffect가 자동으로 오버레이 표시
|
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
|
|
||||||
@@ -725,46 +840,48 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
|
|
||||||
// 백그라운드 전체화면 비디오 제어: DetailPanel 진입/퇴장 시
|
// 백그라운드 전체화면 비디오 제어: DetailPanel 진입/퇴장 시
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log('[BgVideo] DetailPanel mounted - checking panels:', {
|
// PlayerPanel이 존재하는지 확인 (Modal 또는 Fullscreen)
|
||||||
// panelsCount: panels?.length,
|
const playerPanel = panels.find(
|
||||||
// panels: panels?.map(p => ({ name: p.name, modal: p.panelInfo?.modal }))
|
(panel) => panel.name === panel_names.PLAYER_PANEL
|
||||||
// });
|
);
|
||||||
|
const hasPlayerPanel = !!playerPanel;
|
||||||
// 전체화면 PlayerPanel(modal=false)이 존재하는지 확인
|
const isModal = playerPanel?.panelInfo?.modal;
|
||||||
const hasFullscreenPlayerPanel = fp.pipe(
|
|
||||||
() => panels,
|
|
||||||
(panelList) =>
|
|
||||||
panelList.some(
|
|
||||||
(panel) => panel.name === panel_names.PLAYER_PANEL && !panel.panelInfo?.modal
|
|
||||||
)
|
|
||||||
)();
|
|
||||||
|
|
||||||
// ProductAllSection에 비디오가 있는지 확인
|
// ProductAllSection에 비디오가 있는지 확인
|
||||||
const hasProductVideo = fp.pipe(() => productData, fp.get('prdtMediaUrl'), fp.isNotNil)();
|
const hasProductVideo = fp.pipe(() => productData, fp.get('prdtMediaUrl'), fp.isNotNil)();
|
||||||
|
|
||||||
// console.log('[BgVideo] hasFullscreenPlayerPanel:', hasFullscreenPlayerPanel);
|
console.log('[BgVideo] DetailPanel - Video Control Check:', {
|
||||||
// console.log('[BgVideo] hasProductVideo:', hasProductVideo);
|
hasPlayerPanel,
|
||||||
|
isModal,
|
||||||
|
hasProductVideo,
|
||||||
|
sourceMenu: panelInfo?.sourceMenu
|
||||||
|
});
|
||||||
|
|
||||||
// 전체화면 PlayerPanel이 있고, 제품에 비디오가 있을 때만 백그라운드 비디오 멈춤
|
// PlayerPanel이 있고, 제품에 비디오가 있을 때만 비디오 멈춤
|
||||||
if (hasFullscreenPlayerPanel && hasProductVideo) {
|
if (hasPlayerPanel && hasProductVideo) {
|
||||||
// console.log('[BgVideo] DetailPanel - Product has video, dispatching pauseFullscreenVideo()');
|
console.log('[BgVideo] DetailPanel - Pausing video');
|
||||||
dispatch(pauseFullscreenVideo());
|
if (isModal) {
|
||||||
|
dispatch(pauseModalVideo());
|
||||||
|
} else {
|
||||||
|
dispatch(pauseFullscreenVideo());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[BgVideo] DetailPanel - Skipping pause:', {
|
console.log('[BgVideo] DetailPanel - Skipping pause');
|
||||||
reason: !hasFullscreenPlayerPanel ? 'no fullscreen PlayerPanel' : 'no product video',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// DetailPanel 언마운트 시: 비디오가 있었고 멈췄던 경우만 재생 재개
|
// DetailPanel 언마운트 시: 비디오가 있었고 멈췄던 경우만 재생 재개
|
||||||
// console.log('[BgVideo] DetailPanel unmounting');
|
if (hasPlayerPanel && hasProductVideo) {
|
||||||
if (hasFullscreenPlayerPanel && hasProductVideo) {
|
console.log('[BgVideo] DetailPanel - Resuming video');
|
||||||
// console.log('[BgVideo] DetailPanel - Product had video, dispatching resumeFullscreenVideo()');
|
if (isModal) {
|
||||||
dispatch(resumeFullscreenVideo());
|
dispatch(resumeModalVideo());
|
||||||
|
} else {
|
||||||
|
dispatch(resumeFullscreenVideo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []); // 마운트/언마운트 시에만 실행
|
}, [panelInfo?.sourceMenu, productData?.prdtMediaUrl]);
|
||||||
|
|
||||||
// MediaPanel modal 상태 변화 감지 -> ProductVideo로 포커스 이동
|
// MediaPanel modal 상태 변화 감지 -> ProductVideo로 포커스 이동
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -809,17 +809,20 @@ const HomePanel = ({ isOnTop, showGradientBackground = false }) => {
|
|||||||
console.log('[HomeActive] 재생 기록 업데이트:', bannerId);
|
console.log('[HomeActive] 재생 기록 업데이트:', bannerId);
|
||||||
}, [isOnTop, dispatch]);
|
}, [isOnTop, dispatch]);
|
||||||
|
|
||||||
// ✅ [251118] DetailPanel 닫힘 감지 useEffect
|
// ✅ [251120] DetailPanel 닫힘 감지 useEffect - detailPanelClosed flag 사용
|
||||||
|
const detailPanelClosed = useSelector(
|
||||||
|
(state) => state.home.homeInfo?.panelInfo?.detailPanelClosed
|
||||||
|
);
|
||||||
const detailPanelClosedTime = useSelector(
|
const detailPanelClosedTime = useSelector(
|
||||||
(state) => state.home.homeInfo?.panelInfo?.lastDetailPanelClosed
|
(state) => state.home.homeInfo?.panelInfo?.detailPanelClosedAt
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (detailPanelClosedTime && isOnTop) {
|
if (detailPanelClosed && isOnTop) {
|
||||||
// if (isOnTop) {
|
console.log('[TRACE-GRADIENT] 🔄 detailPanelClosed flag triggered - HomePanel reactivated');
|
||||||
console.log('[TRACE-GRADIENT] 🔄 lastDetailPanelClosed triggered - HomePanel reactivated');
|
|
||||||
console.log('[HomePanel] *** ✅ HomePanel isOnTop = true');
|
console.log('[HomePanel] *** ✅ HomePanel isOnTop = true');
|
||||||
console.log('[HomePanel] *** lastDetailPanelClosed:', detailPanelClosedTime);
|
console.log('[HomePanel] *** detailPanelClosed:', detailPanelClosed);
|
||||||
|
console.log('[HomePanel] *** detailPanelClosedTime:', detailPanelClosedTime);
|
||||||
console.log('[HomePanel] *** isOnTop:', isOnTop);
|
console.log('[HomePanel] *** isOnTop:', isOnTop);
|
||||||
console.log('[HomePanel] *** videoPlayIntentRef.current:', videoPlayIntentRef.current);
|
console.log('[HomePanel] *** videoPlayIntentRef.current:', videoPlayIntentRef.current);
|
||||||
console.log('[HomePanel] *** lastPlayedBannerIdRef.current:', lastPlayedBannerIdRef.current);
|
console.log('[HomePanel] *** lastPlayedBannerIdRef.current:', lastPlayedBannerIdRef.current);
|
||||||
@@ -931,9 +934,20 @@ const HomePanel = ({ isOnTop, showGradientBackground = false }) => {
|
|||||||
// refs 초기화
|
// refs 초기화
|
||||||
videoPlayIntentRef.current = null;
|
videoPlayIntentRef.current = null;
|
||||||
lastPlayedBannerIdRef.current = null;
|
lastPlayedBannerIdRef.current = null;
|
||||||
|
|
||||||
|
// detailPanelClosed 플래그 초기화 (다음 사이클에서 재사용 방지)
|
||||||
|
console.log('[HomePanel] *** detailPanelClosed flag 초기화');
|
||||||
|
dispatch(updateHomeInfo({
|
||||||
|
name: panel_names.HOME_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
detailPanelClosed: false,
|
||||||
|
detailPanelClosedAt: undefined,
|
||||||
|
detailPanelClosedFromSource: undefined,
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [detailPanelClosedTime, isOnTop, bannerDataList, dispatch]);
|
}, [detailPanelClosed, isOnTop, bannerDataList, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
startVideoPlayer,
|
startVideoPlayer,
|
||||||
pauseModalVideo,
|
pauseModalVideo,
|
||||||
resumeModalVideo,
|
resumeModalVideo,
|
||||||
|
resumeFullscreenVideo,
|
||||||
} from '../../actions/playActions';
|
} from '../../actions/playActions';
|
||||||
import { resetPlayerOverlays } from '../../actions/videoPlayActions';
|
import { resetPlayerOverlays } from '../../actions/videoPlayActions';
|
||||||
import { convertUtcToLocal } from '../../components/MediaPlayer/util';
|
import { convertUtcToLocal } from '../../components/MediaPlayer/util';
|
||||||
@@ -340,21 +341,46 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
|||||||
// }
|
// }
|
||||||
// },[isOnTop, panelInfo])
|
// },[isOnTop, panelInfo])
|
||||||
|
|
||||||
// PlayerPanel.jsx의 라인 313-327 useEffect 수정
|
// PlayerPanel.jsx의 라인 313-327 useEffect 수정 - detailPanelClosed flag 감지 추가
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('[PlayerPanel] isOnTop useEffect:', {
|
console.log('[PlayerPanel] isOnTop useEffect:', {
|
||||||
isOnTop,
|
isOnTop,
|
||||||
modal: panelInfo?.modal,
|
modal: panelInfo?.modal,
|
||||||
isPaused: panelInfo?.isPaused,
|
isPaused: panelInfo?.isPaused,
|
||||||
|
detailPanelClosed: panelInfo?.detailPanelClosed,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (panelInfo && panelInfo.modal) {
|
if (isOnTop) {
|
||||||
if (!isOnTop) {
|
// 1. Resume Video if needed (isPaused or detailPanelClosed)
|
||||||
console.log('[PlayerPanel] Not on top - pausing video');
|
if (panelInfo.isPaused || panelInfo.detailPanelClosed) {
|
||||||
dispatch(pauseModalVideo());
|
if (panelInfo.modal) {
|
||||||
} else if (isOnTop && panelInfo.isPaused) {
|
console.log('[PlayerPanel] Back on top (Modal) - resuming video');
|
||||||
console.log('[PlayerPanel] Back on top - resuming video ← 이곳에서 resumeModalVideo 호출!');
|
dispatch(resumeModalVideo());
|
||||||
dispatch(resumeModalVideo());
|
} else {
|
||||||
|
console.log('[PlayerPanel] Back on top (Fullscreen) - resuming video');
|
||||||
|
dispatch(resumeFullscreenVideo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Reset detailPanelClosed flag
|
||||||
|
if (panelInfo.detailPanelClosed) {
|
||||||
|
console.log('[PlayerPanel] detailPanelClosed flag 초기화');
|
||||||
|
dispatch(
|
||||||
|
updatePanel({
|
||||||
|
name: panel_names.PLAYER_PANEL,
|
||||||
|
panelInfo: {
|
||||||
|
detailPanelClosed: false,
|
||||||
|
detailPanelClosedAt: undefined,
|
||||||
|
detailPanelClosedFromSource: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not on top
|
||||||
|
if (panelInfo && panelInfo.modal) {
|
||||||
|
// console.log('[PlayerPanel] Not on top - pausing video');
|
||||||
|
// dispatch(pauseModalVideo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isOnTop, panelInfo]);
|
}, [isOnTop, panelInfo]);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDeco
|
|||||||
import { getContainerNode, setContainerLastFocusedElement } from '@enact/spotlight/src/container';
|
import { getContainerNode, setContainerLastFocusedElement } from '@enact/spotlight/src/container';
|
||||||
|
|
||||||
import { sendLogTotalRecommend } from '../../../../actions/logActions';
|
import { sendLogTotalRecommend } from '../../../../actions/logActions';
|
||||||
import { pushPanel } from '../../../../actions/panelActions';
|
import { navigateToDetail, SOURCE_MENUS, pushPanel } from '../../../../actions/panelActions';
|
||||||
import { hidePlayerOverlays } from '../../../../actions/videoPlayActions';
|
import { hidePlayerOverlays } from '../../../../actions/videoPlayActions';
|
||||||
import TItemCard, { TYPES } from '../../../../components/TItemCard/TItemCard';
|
import TItemCard, { TYPES } from '../../../../components/TItemCard/TItemCard';
|
||||||
import TVirtualGridList from '../../../../components/TVirtualGridList/TVirtualGridList';
|
import TVirtualGridList from '../../../../components/TVirtualGridList/TVirtualGridList';
|
||||||
@@ -151,26 +151,18 @@ export default function ShopNowContents({
|
|||||||
const isYouMayLikeStart = shopNowInfo && index === shopNowInfo.length;
|
const isYouMayLikeStart = shopNowInfo && index === shopNowInfo.length;
|
||||||
|
|
||||||
const handleItemClick = () => {
|
const handleItemClick = () => {
|
||||||
// 현재 포커스된 요소의 spotlightId 저장
|
console.log('[ShopNowContents] DetailPanel 진입 - sourceMenu:', SOURCE_MENUS.PLAYER_SHOP_NOW);
|
||||||
const currentFocusedElement = Spotlight.getCurrent();
|
|
||||||
const currentSpotlightId = currentFocusedElement?.getAttribute('data-spotlight-id');
|
|
||||||
console.log('[ShopNowContents] 현재 포커스된 spotlightId:', currentSpotlightId);
|
|
||||||
|
|
||||||
// DetailPanel push 전에 VideoPlayer 오버레이 숨김
|
|
||||||
dispatch(hidePlayerOverlays());
|
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
pushPanel({
|
navigateToDetail({
|
||||||
name: panel_names.DETAIL_PANEL,
|
patnrId,
|
||||||
panelInfo: {
|
prdtId,
|
||||||
|
sourceMenu: SOURCE_MENUS.PLAYER_SHOP_NOW,
|
||||||
|
additionalInfo: {
|
||||||
showNm: playListInfo?.showNm,
|
showNm: playListInfo?.showNm,
|
||||||
showId: playListInfo?.showId,
|
showId: playListInfo?.showId,
|
||||||
liveFlag: playListInfo?.liveFlag,
|
liveFlag: playListInfo?.liveFlag,
|
||||||
thumbnailUrl: playListInfo?.thumbnailUrl,
|
thumbnailUrl: playListInfo?.thumbnailUrl,
|
||||||
patnrId,
|
|
||||||
prdtId,
|
|
||||||
launchedFromPlayer: true,
|
|
||||||
lastFocusedTargetId: currentSpotlightId, // 현재 포커스된 spotlightId 저장
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user