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); }; };