Files
shoptime/com.twin.app.shoptime/src/actions/panelActions.js
optrader af30f8c688 [251115] fix: MediaPanel.v3.jsx 비디오재생-1
🕐 커밋 시간: 2025. 11. 15. 12:22:59

📊 변경 통계:
  • 총 파일: 12개
  • 추가: +246줄
  • 삭제: -27줄

📁 추가된 파일:
  + com.twin.app.shoptime/src/utils/focusPanelGuide.js

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/actions/actionTypes.js
  ~ com.twin.app.shoptime/src/actions/mediaActions.js
  ~ com.twin.app.shoptime/src/actions/panelActions.js
  ~ com.twin.app.shoptime/src/reducers/panelReducer.js
  ~ com.twin.app.shoptime/src/utils/SpotlightIds.js
  ~ com.twin.app.shoptime/src/views/DetailPanel/DetailPanel.jsx
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.module.less
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v3.jsx
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx
  ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/actions/panelActions.js (javascript):
     Added: resetPanels()
  📄 com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx (javascript):
    🔄 Modified: extractProductMeta()
  📄 com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v3.jsx (javascript):
    🔄 Modified: Spottable()
  📄 com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/YouMayAlsoLike/YouMayAlsoLike.jsx (javascript):
    🔄 Modified: SpotlightContainerDecorator()
  📄 com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx (javascript):
    🔄 Modified: normalizeModalStyle()
  📄 com.twin.app.shoptime/src/utils/focusPanelGuide.js (javascript):
     Added: DetailPanel(), handleProductSelect()

🔧 주요 변경 내용:
  • 타입 시스템 안정성 강화
  • 핵심 비즈니스 로직 개선
  • 공통 유틸리티 함수 최적화
2025-11-15 12:23:00 +09:00

113 lines
3.3 KiB
JavaScript

import { types } from './actionTypes';
import Spotlight from '@enact/spotlight';
/*
name: panel_names.PLAYER_PANEL,
panelInfo: {
modal: true //only for video player
etc...
},
*/
export const pushPanel = (panel, duplicatable = false) => ({
type: types.PUSH_PANEL,
payload: panel,
duplicatable: duplicatable,
});
export const popPanel = (panelName) => ({
type: types.POP_PANEL,
payload: panelName,
});
export const updatePanel = (panelInfo) => ({
type: types.UPDATE_PANEL,
payload: panelInfo,
});
export const resetPanels = (panels) => ({
type: types.RESET_PANELS,
payload: panels,
});
/**
* [251114] 명시적 포커스 이동
* Panel의 비동기 작업(useEffect, 타이머 등)이 포커스를 탈취하는 것을 방지
* @param {string} panelName - 대상 Panel 이름
* @param {string} focusTarget - 포커스할 요소 ID
* @returns {Function} Redux thunk
*/
export const focusPanel = (panelName, focusTarget) => {
return (dispatch, getState) => {
const state = getState();
const panels = state.panels.panels;
console.log('[focusPanel] 포커스 이동 시도', {
panelName,
focusTarget,
currentPanels: panels.map((p) => p.name),
timestamp: Date.now(),
});
// 안전성 체크 1: Panel이 존재하고 최상단 또는 그 아래에 있는가?
const targetPanelIndex = panels.findIndex((p) => p.name === panelName);
const targetPanel = panels[targetPanelIndex];
const topPanel = panels[panels.length - 1];
if (!targetPanel) {
console.warn(`[focusPanel] ❌ Panel을 찾을 수 없음: ${panelName}`);
return;
}
// Panel이 최상단 또는 그 아래 레이어에 있는지 확인
// MediaPanel(최상단) 위에 다른 Modal이 있는 경우는 허용하지 않음
const panelsAboveTarget = panels.slice(targetPanelIndex + 1);
const hasBlockingModalAbove = panelsAboveTarget.some(
(panel) => panel?.panelInfo?.modal === true && panel.name !== panelName
);
if (hasBlockingModalAbove) {
const blockingModal = panelsAboveTarget.find((panel) => panel?.panelInfo?.modal === true);
console.warn(
`[focusPanel] ⚠️ 상위에 Modal이 있음. ` +
`${panelName}(${targetPanelIndex}층)에 포커스할 수 없음. ` +
`상단 Modal: ${blockingModal?.name}(${panelsAboveTarget.indexOf(blockingModal) + targetPanelIndex + 1}층)`
);
return;
}
console.log(
`[focusPanel] ✅ Panel 위치 확인: ${panelName}(${targetPanelIndex}층), ` +
`전체 Panel: ${panels.length}`
);
// 포커스 이동
setTimeout(() => {
const element = document.getElementById(focusTarget);
if (!element) {
console.warn(`[focusPanel] ❌ 요소를 찾을 수 없음: ${focusTarget}`);
return;
}
if (element.offsetParent === null) {
console.warn(`[focusPanel] ⚠️ 요소가 숨겨져있음: ${focusTarget}`);
return;
}
// ✅ 포커스 이동
Spotlight.focus(focusTarget);
console.log(`[focusPanel] ✅ 포커스 이동 성공: ${panelName}${focusTarget}`);
// Reducer에 반영
dispatch({
type: types.FOCUS_PANEL,
payload: {
panelName,
focusTarget,
timestamp: Date.now(),
},
});
}, 0);
};
};