fix: DetailPanel above PlayerPanel , FeaturedBrandsPanel-2
This commit is contained in:
@@ -299,19 +299,28 @@ export const navigateToDetail = ({
|
||||
// PlayerPanel에서 온 경우
|
||||
const { hidePlayerOverlays } = require('./videoPlayActions');
|
||||
const statePanels = panels || getState().panels.panels;
|
||||
const playerPanelEntry = statePanels.find((p) => p.name === panel_names.PLAYER_PANEL);
|
||||
const playerPanelEntry =
|
||||
[...statePanels].reverse().find(
|
||||
(p) => p.name === panel_names.PLAYER_PANEL || p.name === panel_names.PLAYER_PANEL_NEW
|
||||
) || null;
|
||||
|
||||
// DetailPanel push 전에 VideoPlayer 오버레이 숨김
|
||||
dispatch(hidePlayerOverlays());
|
||||
|
||||
// PlayerPanel이 modal=true라면 풀스크린 백그라운드로 전환
|
||||
if (playerPanelEntry?.panelInfo?.modal) {
|
||||
// PlayerPanel이 modal=true라면 풀스크린 백그라운드로 전환 + lockModalFalse 설정 (Detail 동안 modal 복귀 방지)
|
||||
if (playerPanelEntry) {
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
name: playerPanelEntry.name,
|
||||
panelInfo: {
|
||||
...playerPanelEntry.panelInfo,
|
||||
modal: false,
|
||||
modalContainerId: undefined,
|
||||
modalStyle: undefined,
|
||||
modalScale: undefined,
|
||||
shouldShrinkTo1px: false,
|
||||
isHidden: false,
|
||||
lockModalFalse: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
@@ -73,6 +73,16 @@ export const startVideoPlayer =
|
||||
...rest
|
||||
}) =>
|
||||
(dispatch, getState) => {
|
||||
const caller = new Error().stack?.split('\n')[2]?.trim();
|
||||
console.log('[PTRACE-SP] startVideoPlayer call', {
|
||||
modal,
|
||||
modalContainerId,
|
||||
modalClassName,
|
||||
videoId,
|
||||
showUrl,
|
||||
caller,
|
||||
});
|
||||
|
||||
dlog(
|
||||
'[startVideoPlayer] ✅ START - videoId:',
|
||||
videoId,
|
||||
@@ -105,6 +115,9 @@ export const startVideoPlayer =
|
||||
|
||||
// 기존 PlayerPanel이 어디든 있으면 완전히 초기화: 타이머 정리 후 pop → 새로 push
|
||||
if (existingPlayerPanel) {
|
||||
console.log('[PTRACE-SP] startVideoPlayer: popping existing player before push', {
|
||||
stack: panels.map((p) => p.name),
|
||||
});
|
||||
dlog('[startVideoPlayer] 🔄 Resetting existing PLAYER_PANEL before start');
|
||||
clearAllVideoTimers();
|
||||
dispatch(popPanel(panel_names.PLAYER_PANEL));
|
||||
@@ -182,6 +195,17 @@ export const startVideoPlayerNew =
|
||||
...rest
|
||||
}) =>
|
||||
(dispatch, getState) => {
|
||||
const caller = new Error().stack?.split('\n')[2]?.trim();
|
||||
console.log('[PTRACE-SPN] startVideoPlayerNew call', {
|
||||
bannerId,
|
||||
modal,
|
||||
modalContainerId,
|
||||
modalClassName,
|
||||
videoId,
|
||||
showUrl,
|
||||
caller,
|
||||
});
|
||||
|
||||
dlog(
|
||||
'[startVideoPlayerNew] *** ✅ START - bannerId:',
|
||||
bannerId,
|
||||
@@ -215,6 +239,9 @@ export const startVideoPlayerNew =
|
||||
|
||||
// 기존 PlayerPanel이 있으면 완전히 초기화: 타이머 정리 후 pop → 새로 push
|
||||
if (existingPlayerPanel) {
|
||||
console.log('[PTRACE-SPN] popping existing player before push', {
|
||||
stack: panels.map((p) => p.name),
|
||||
});
|
||||
dlog('[startVideoPlayerNew] *** 🔄 Resetting existing PLAYER_PANEL before start');
|
||||
clearAllVideoTimers();
|
||||
dispatch(popPanel(panel_names.PLAYER_PANEL));
|
||||
|
||||
@@ -132,6 +132,60 @@ export const panelsReducer = (state = initialState, action) => {
|
||||
case types.UPDATE_PANEL: {
|
||||
let lastIndex = -1;
|
||||
let lastAction = 'update';
|
||||
const hasDetailPanel = state.panels.some((p) => p.name === panel_names.DETAIL_PANEL);
|
||||
const isPlayerPanel =
|
||||
action.payload.name === panel_names.PLAYER_PANEL ||
|
||||
action.payload.name === panel_names.PLAYER_PANEL_NEW;
|
||||
const existingPanel = state.panels.find((p) => p.name === action.payload.name);
|
||||
let nextPanelInfo = action.payload.panelInfo || {};
|
||||
|
||||
// lockModalFalse 플래그 처리: DetailPanel이 스택에 있거나 lock이 이미 true면 modal=true 업데이트를 차단
|
||||
if (isPlayerPanel && existingPanel) {
|
||||
const lockFlag =
|
||||
existingPanel.panelInfo?.lockModalFalse === true || nextPanelInfo.lockModalFalse === true;
|
||||
|
||||
// unlock 명시 시 그대로 진행
|
||||
if (nextPanelInfo.lockModalFalse === false) {
|
||||
// do nothing
|
||||
} else if (lockFlag && nextPanelInfo.modal === true) {
|
||||
nextPanelInfo = {
|
||||
...nextPanelInfo,
|
||||
modal: false,
|
||||
modalContainerId: undefined,
|
||||
lockModalFalse: true,
|
||||
modalStyle: undefined,
|
||||
modalScale: undefined,
|
||||
shouldShrinkTo1px: false,
|
||||
isHidden: false,
|
||||
};
|
||||
} else if (lockFlag && nextPanelInfo.modal === undefined && hasDetailPanel) {
|
||||
nextPanelInfo = {
|
||||
...nextPanelInfo,
|
||||
modal:
|
||||
existingPanel.panelInfo?.modal === true ? false : existingPanel.panelInfo?.modal,
|
||||
modalContainerId:
|
||||
existingPanel.panelInfo?.modal === true
|
||||
? undefined
|
||||
: existingPanel.panelInfo?.modalContainerId,
|
||||
lockModalFalse: true,
|
||||
modalStyle: existingPanel.panelInfo?.modal === true ? undefined : nextPanelInfo.modalStyle,
|
||||
modalScale: existingPanel.panelInfo?.modal === true ? undefined : nextPanelInfo.modalScale,
|
||||
shouldShrinkTo1px: false,
|
||||
isHidden: false,
|
||||
};
|
||||
} else if (hasDetailPanel && nextPanelInfo.modal === true) {
|
||||
// DetailPanel 존재 시 modal=true 업데이트 차단
|
||||
nextPanelInfo = {
|
||||
...nextPanelInfo,
|
||||
modal: false,
|
||||
modalContainerId: undefined,
|
||||
modalStyle: undefined,
|
||||
modalScale: undefined,
|
||||
shouldShrinkTo1px: false,
|
||||
isHidden: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
// 배열의 끝에서부터 시작하여 조건에 맞는 마지막 인덱스 찾기
|
||||
for (let i = state.panels.length - 1; i >= 0; i--) {
|
||||
if (state.panels[i].name === action.payload.name) {
|
||||
@@ -143,7 +197,7 @@ export const panelsReducer = (state = initialState, action) => {
|
||||
index === lastIndex
|
||||
? {
|
||||
...panel,
|
||||
panelInfo: { ...panel.panelInfo, ...action.payload.panelInfo },
|
||||
panelInfo: { ...panel.panelInfo, ...nextPanelInfo },
|
||||
}
|
||||
: panel
|
||||
);
|
||||
|
||||
@@ -331,6 +331,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
detailPanelClosedAt: Date.now(), // ✅ 시점 기록
|
||||
detailPanelClosedFromSource: sourceMenu, // ✅ 출처
|
||||
lastFocusedTargetId: panelInfo?.lastFocusedTargetId, // ✅ 포커스 복원 타겟 전달
|
||||
lockModalFalse: false, // Detail 종료 시 lock 해제
|
||||
},
|
||||
})
|
||||
);
|
||||
@@ -1117,6 +1118,24 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
dispatch(finishVideoPreview());
|
||||
} else if (hasPlayerPanel && launchedFromPlayer) {
|
||||
console.log('[DetailPanel] PlayerPanel modal=true detected - launched from Player, skip finishVideoPreview');
|
||||
|
||||
// Detail 동안 modal=true로 바뀌지 않도록 lockModalFalse 설정
|
||||
const playerPanelEntry = panels.find(
|
||||
(p) => p.name === panel_names.PLAYER_PANEL || p.name === panel_names.PLAYER_PANEL_NEW
|
||||
);
|
||||
if (playerPanelEntry?.panelInfo?.modal === true) {
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: playerPanelEntry.name,
|
||||
panelInfo: {
|
||||
...playerPanelEntry.panelInfo,
|
||||
modal: false,
|
||||
modalContainerId: undefined,
|
||||
lockModalFalse: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [panels, dispatch, panelInfo?.fromPlayer, panelInfo?.sourcePanel]);
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ export default function HomeBanner({
|
||||
const bannerDataList = useSelector((state) => state.home.bannerData?.bannerInfos);
|
||||
|
||||
const popupVisible = useSelector((state) => state.common.popup.popupVisible);
|
||||
const panels = useSelector((state) => state.panels.panels);
|
||||
// 🔽 useFocusHistory - 경량화된 범용 포커스 히스토리
|
||||
const focusHistory = useFocusHistory({
|
||||
enableLogging: true,
|
||||
@@ -163,7 +164,10 @@ export default function HomeBanner({
|
||||
videoData = targetBannerData.bannerDetailInfos?.[0];
|
||||
}
|
||||
|
||||
if (videoData && (videoData.shptmBanrTpNm === 'LIVE' || videoData.shptmBanrTpNm === 'VOD')) {
|
||||
// DetailPanel이 떠 있는 동안에는 배너 자동 재생을 스킵 (PlayerPanel 모달 재설정 방지)
|
||||
const hasDetailPanel = panels.some((p) => p.name === panel_names.DETAIL_PANEL);
|
||||
|
||||
if (!hasDetailPanel && videoData && (videoData.shptmBanrTpNm === 'LIVE' || videoData.shptmBanrTpNm === 'VOD')) {
|
||||
console.log('[HomeBanner] 초기 비디오 자동 재생:', defaultFocus);
|
||||
|
||||
dispatch(
|
||||
@@ -175,12 +179,13 @@ export default function HomeBanner({
|
||||
shptmBanrTpNm: videoData.shptmBanrTpNm,
|
||||
lgCatCd: videoData.lgCatCd,
|
||||
chanId: videoData.brdcChnlId,
|
||||
// 기본: 배너는 modal=true로 재생
|
||||
modal: true,
|
||||
modalContainerId: defaultFocus,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [bannerDataList, defaultFocus, dispatch]);
|
||||
}, [bannerDataList, defaultFocus, dispatch, panels]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
(index, isHorizontal) => {
|
||||
|
||||
Reference in New Issue
Block a user