Files
shoptime/com.twin.app.shoptime/src/actions/mediaActions.js
optrader 741c4338ca [251124] fix: Log정리-5
🕐 커밋 시간: 2025. 11. 24. 12:43:58

📊 변경 통계:
  • 총 파일: 40개
  • 추가: +774줄
  • 삭제: -581줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/actions/appDataActions.js
  ~ com.twin.app.shoptime/src/actions/billingActions.js
  ~ com.twin.app.shoptime/src/actions/brandActions.js
  ~ com.twin.app.shoptime/src/actions/cancelActions.js
  ~ com.twin.app.shoptime/src/actions/cardActions.js
  ~ com.twin.app.shoptime/src/actions/cartActions.js
  ~ com.twin.app.shoptime/src/actions/checkoutActions.js
  ~ com.twin.app.shoptime/src/actions/commonActions.js
  ~ com.twin.app.shoptime/src/actions/convertActions.js
  ~ com.twin.app.shoptime/src/actions/couponActions.js
  ~ com.twin.app.shoptime/src/actions/deviceActions.js
  ~ com.twin.app.shoptime/src/actions/empActions.js
  ~ com.twin.app.shoptime/src/actions/eventActions.js
  ~ com.twin.app.shoptime/src/actions/forYouActions.js
  ~ com.twin.app.shoptime/src/actions/homeActions.js
  ~ com.twin.app.shoptime/src/actions/logActions.js
  ~ com.twin.app.shoptime/src/actions/mediaActions.js
  ~ com.twin.app.shoptime/src/actions/mockCartActions.js
  ~ com.twin.app.shoptime/src/actions/myPageActions.js
  ~ com.twin.app.shoptime/src/actions/onSaleActions.js
  ~ com.twin.app.shoptime/src/actions/orderActions.js
  ~ com.twin.app.shoptime/src/actions/panelActions.js
  ~ com.twin.app.shoptime/src/actions/panelNavigationActions.js
  ~ com.twin.app.shoptime/src/actions/pinCodeActions.js
  ~ com.twin.app.shoptime/src/actions/productActions.js
  ~ com.twin.app.shoptime/src/actions/queuedPanelActions.js
  ~ com.twin.app.shoptime/src/actions/searchActions.js
  ~ com.twin.app.shoptime/src/actions/shippingActions.js
  ~ com.twin.app.shoptime/src/actions/voiceActions.js
  ~ com.twin.app.shoptime/src/actions/webSpeechActions.js
  ~ com.twin.app.shoptime/src/reducers/localSettingsReducer.js
  ~ com.twin.app.shoptime/src/reducers/mediaOverlayReducer.js
  ~ com.twin.app.shoptime/src/reducers/mockCartReducer.js
  ~ com.twin.app.shoptime/src/reducers/playReducer.js
  ~ com.twin.app.shoptime/src/reducers/productReducer.js
  ~ com.twin.app.shoptime/src/reducers/videoOverlayReducer.js
  ~ com.twin.app.shoptime/src/views/UserReview/ShowUserReviews.jsx
  ~ com.twin.app.shoptime/src/views/UserReview/UserReviewPanel.jsx
  ~ com.twin.app.shoptime/src/views/UserReview/components/UserReviewsList.jsx
  ~ com.twin.app.shoptime/src/views/UserReview/components/VirtualScrollBar.jsx

🔧 함수 변경 내용:
  📊 Function-level changes summary across 40 files:
    • Functions added: 14
    • Functions modified: 34
    • Functions deleted: 18
  📋 By language:
    • javascript: 40 files, 66 function changes

🔧 주요 변경 내용:
  • 핵심 비즈니스 로직 개선
  • 로깅 시스템 개선
  • 설정 관리 시스템 개선
  • UI 컴포넌트 아키텍처 개선
2025-11-24 12:47:57 +09:00

348 lines
10 KiB
JavaScript

import Spotlight from '@enact/spotlight';
import { panel_names } from '../utils/Config';
import { popPanel, pushPanel, updatePanel } from './panelActions';
import { createDebugHelpers } from '../utils/debug';
// 디버그 헬퍼 설정
const DEBUG_MODE = false;
const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE);
let startMediaFocusTimer = null;
/**
* MediaPanel을 시작합니다 (modal 또는 fullscreen 모드)
* @param {Object} params
* @param {boolean} params.modal - true: 부분화면, false: 전체화면
* @param {string} params.modalContainerId - modal 모드일 때 컨테이너 ID
* @param {string} params.modalClassName - 추가 CSS 클래스
* @param {boolean} params.spotlightDisable - spotlight 비활성화 여부
* @param {string} params.showUrl - 비디오 URL
* @param {string} params.thumbnailUrl - 썸네일 URL
* @param {string} params.subtitle - 자막 URL (선택)
*/
export const startMediaPlayer =
({ modal, modalContainerId, modalClassName, spotlightDisable, ...rest }) =>
(dispatch, getState) => {
const panels = getState().panels.panels;
const topPanel = panels[panels.length - 1];
let panelWorkingAction = pushPanel;
dlog('[startMediaPlayer]-LoadingVideo 🚀 시작:', {
showUrl: rest?.showUrl?.substring(0, 50),
showNm: rest?.showNm,
prdtId: rest?.prdtId,
modal,
modalContainerId,
});
if (topPanel && topPanel.name === panel_names.MEDIA_PANEL) {
panelWorkingAction = updatePanel;
}
const allParams = {
modal,
modalContainerId,
modalClassName,
spotlightDisable,
...rest,
};
dispatch(
panelWorkingAction(
{
name: panel_names.MEDIA_PANEL,
panelInfo: allParams,
},
true
)
);
dlog('[startMediaPlayer]-LoadingVideo ✅ MediaPanel dispatch 완료');
if (modal && modalContainerId && !spotlightDisable) {
Spotlight.setPointerMode(false);
startMediaFocusTimer = setTimeout(() => {
Spotlight.focus(modalContainerId);
}, 0);
}
};
/**
* MediaPanel의 modal 모드를 종료합니다
*/
export const finishMediaPreview = () => (dispatch, getState) => {
const panels = getState().panels.panels;
const topPanel = panels[panels.length - 1];
// dlog('[finishMediaPreview] ========== Called ==========');
// dlog('[finishMediaPreview] Current panels:', JSON.stringify(panels, null, 2));
// dlog('[finishMediaPreview] topPanel:', JSON.stringify(topPanel, null, 2));
if (topPanel && topPanel.name === panel_names.MEDIA_PANEL && topPanel.panelInfo.modal) {
// dlog('[finishMediaPreview] Closing modal MediaPanel');
if (startMediaFocusTimer) {
clearTimeout(startMediaFocusTimer);
startMediaFocusTimer = null;
}
dispatch(popPanel());
// dlog('[finishMediaPreview] popPanel dispatched');
} else {
// dlog('[finishMediaPreview] Not closing - no modal MediaPanel on top');
}
};
/**
* 강제로 DetailPanel ProductVideo MediaPanel을 종료합니다 (modal/fullscreen 모두)
*/
export const finishModalMediaForce = () => (dispatch, getState) => {
const panels = getState().panels.panels;
const hasProductVideoPanel = panels.some(
(panel) =>
panel.name === panel_names.MEDIA_PANEL &&
(panel.panelInfo?.modal || panel.panelInfo?.modalContainerId === 'product-video-player')
);
if (hasProductVideoPanel) {
if (startMediaFocusTimer) {
clearTimeout(startMediaFocusTimer);
startMediaFocusTimer = null;
}
dispatch(popPanel(panel_names.MEDIA_PANEL));
}
};
/**
* Modal MediaPanel을 일시정지합니다 (패널은 유지)
*/
export const pauseModalMedia = () => (dispatch, getState) => {
const panels = getState().panels.panels;
const modalMediaPanel = panels.find(
(panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal
);
if (modalMediaPanel) {
// dlog('[pauseModalMedia] Pausing modal MediaPanel');
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: {
...modalMediaPanel.panelInfo,
isPaused: true,
},
})
);
}
};
/**
* Modal MediaPanel을 재생합니다 (일시정지 해제)
*/
export const resumeModalMedia = () => (dispatch, getState) => {
const panels = getState().panels.panels;
const modalMediaPanel = panels.find(
(panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal
);
if (modalMediaPanel && modalMediaPanel.panelInfo?.isPaused) {
// dlog('[resumeModalMedia] Resuming modal MediaPanel');
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: {
...modalMediaPanel.panelInfo,
isPaused: false,
},
})
);
}
};
/**
* MediaPanel을 fullscreen 모드로 전환합니다
*/
export const switchMediaToFullscreen = () => (dispatch, getState) => {
const panels = getState().panels.panels;
// dlog('[switchMediaToFullscreen] ========== Called ==========');
// dlog('[switchMediaToFullscreen] Current panels:', JSON.stringify(panels, null, 2));
const modalMediaPanel = panels.find(
(panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal
);
// dlog(
// '[switchMediaToFullscreen] modalMediaPanel found:',
// JSON.stringify(modalMediaPanel, null, 2)
// );
if (modalMediaPanel) {
// dlog('[switchMediaToFullscreen] Switching to fullscreen - updating modal to false');
// dlog(
// '[switchMediaToFullscreen] Existing panelInfo:',
// JSON.stringify(modalMediaPanel.panelInfo, null, 2)
// );
const newPanelInfo = {
...modalMediaPanel.panelInfo,
modal: false,
};
// dlog(
// '[switchMediaToFullscreen] New panelInfo to dispatch:',
// JSON.stringify(newPanelInfo, null, 2)
// );
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: newPanelInfo,
})
);
// dlog('[switchMediaToFullscreen] updatePanel dispatched');
} else {
// dlog(
// '[switchMediaToFullscreen] No modal MediaPanel found - cannot switch to fullscreen'
// );
}
};
/**
* MediaPanel을 modal 모드로 전환합니다
*/
export const switchMediaToModal = (modalContainerId, modalClassName) => (dispatch, getState) => {
const panels = getState().panels.panels;
const mediaPanel = panels.find((panel) => panel.name === panel_names.MEDIA_PANEL);
if (mediaPanel && !mediaPanel.panelInfo?.modal) {
// dlog('[switchMediaToModal] Switching to modal');
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: {
...mediaPanel.panelInfo,
modal: true,
modalContainerId,
modalClassName,
},
})
);
}
};
/**
* Modal MediaPanel을 최소화합니다 (1px 크기로 축소, 재생은 계속)
* modal=false로 변경하여 background 클래스 적용 (modalContainerId는 복원을 위해 유지)
*/
export const minimizeModalMedia = () => (dispatch, getState) => {
const panels = getState().panels.panels;
dlog('[Minimize] ========== Called ==========');
dlog('[Minimize] Total panels:', panels.length);
dlog(
'[Minimize] All panels:',
panels
// JSON.stringify(
// panels.map((p) => ({ name: p.name, modal: p.panelInfo?.modal })),
// null,
// 2
// )
);
const modalMediaPanel = panels.find(
(panel) => panel.name === panel_names.MEDIA_PANEL && panel.panelInfo?.modal
);
// dlog('[Minimize] Found modalMediaPanel:', !!modalMediaPanel);
if (modalMediaPanel) {
dlog(
'[Minimize] modalMediaPanel.panelInfo:',
JSON.stringify(modalMediaPanel.panelInfo, null, 2)
);
// dlog('[Minimize] ✅ Minimizing modal MediaPanel (modal=false, isMinimized=true)');
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: {
...modalMediaPanel.panelInfo,
// modal: false, // fullscreen 모드로 전환
isMinimized: true, // modal-minimized 클래스 적용 (1px 크기)
shouldShrinkTo1px: true, // shrink 플래그 추가
// modalContainerId, modalClassName 등은 복원을 위해 유지
// isPaused는 변경하지 않음 - 재생은 계속됨
},
})
);
} else {
dlog('[Minimize] ❌ No modal MediaPanel found - cannot minimize');
}
};
/**
* Modal MediaPanel을 복원합니다 (최소화 해제)
* modal=true, isMinimized=false로 변경하여 원래 modal 위치로 복원
*/
export const restoreModalMedia = () => (dispatch, getState) => {
const panels = getState().panels.panels;
if (typeof window !== 'undefined' && window.detailPanelScrollTop !== 0) {
dlog(
'[restoreModalMedia] Blocked restore because detail panel scroll not zero:',
window.detailPanelScrollTop
);
return;
}
// dlog('[Restore]] ========== Called ==========');
// dlog('[Restore] Total panels:', panels.length);
// dlog(
// '[Restore] All panels:',
// JSON.stringify(
// panels.map((p) => ({
// name: p.name,
// modal: p.panelInfo?.modal,
// isMinimized: p.panelInfo?.isMinimized,
// })),
// null,
// 2
// )
// );
// modal=true AND isMinimized=true인 MediaPanel을 찾음 (최소화 상태)
const minimizedMediaPanel = panels.find(
(panel) =>
panel.name === panel_names.MEDIA_PANEL &&
panel.panelInfo?.modal &&
panel.panelInfo?.isMinimized
);
// dlog('[restoreModalMedia] Found minimizedMediaPanel:', !!minimizedMediaPanel);
if (minimizedMediaPanel) {
// dlog(
// '[restoreModalMedia] minimizedMediaPanel.panelInfo:',
// JSON.stringify(minimizedMediaPanel.panelInfo, null, 2)
// );
// dlog(
// '[restoreModalMedia] ✅ Restoring modal MediaPanel (modal=true, isMinimized=false)'
// );
dispatch(
updatePanel({
name: panel_names.MEDIA_PANEL,
panelInfo: {
...minimizedMediaPanel.panelInfo,
modal: true, // modal 모드로 복원 (원래 위치로 복귀)
isMinimized: false, // 최소화 해제
shouldShrinkTo1px: false, // shrink 플래그 초기화
},
})
);
} else {
// dlog('[restoreModalMedia] ❌ No minimized MediaPanel found - cannot restore');
}
};