diff --git a/com.twin.app.shoptime/src/actions/playActions.js b/com.twin.app.shoptime/src/actions/playActions.js index 3ccbeb93..564a3485 100644 --- a/com.twin.app.shoptime/src/actions/playActions.js +++ b/com.twin.app.shoptime/src/actions/playActions.js @@ -1,10 +1,10 @@ -import Spotlight from "@enact/spotlight"; +import Spotlight from '@enact/spotlight'; -import { URLS } from "../api/apiConfig"; -import { TAxios } from "../api/TAxios"; -import { panel_names } from "../utils/Config"; -import { types } from "./actionTypes"; -import { popPanel, pushPanel, updatePanel } from "./panelActions"; +import { URLS } from '../api/apiConfig'; +import { TAxios } from '../api/TAxios'; +import { panel_names } from '../utils/Config'; +import { types } from './actionTypes'; +import { popPanel, pushPanel, updatePanel } from './panelActions'; //yhcho /* @@ -30,7 +30,7 @@ export const startVideoPlayer = const panels = getState().panels.panels; const topPanel = panels[panels.length - 1]; let panelWorkingAction = pushPanel; - + const panelName = useNewPlayer ? panel_names.PLAYER_PANEL_NEW : panel_names.PLAYER_PANEL; if (topPanel && topPanel.name === panelName) { @@ -57,6 +57,7 @@ export const startVideoPlayer = }, 0); } }; + export const finishVideoPreview = () => (dispatch, getState) => { const panels = getState().panels.panels; const topPanel = panels[panels.length - 1]; @@ -68,12 +69,77 @@ export const finishVideoPreview = () => (dispatch, getState) => { dispatch(popPanel()); } }; + +export const finishModalVideoForce = () => (dispatch, getState) => { + const panels = getState().panels.panels; + + // modal PlayerPanel이 존재하는지 확인 (스택 어디에 있든) + const hasModalPlayerPanel = panels.some( + (panel) => panel.name === panel_names.PLAYER_PANEL && panel.panelInfo?.modal + ); + + if (hasModalPlayerPanel) { + if (startVideoFocusTimer) { + clearTimeout(startVideoFocusTimer); + startVideoFocusTimer = null; + } + // panelName을 지정하면 스택 어디에 있든 해당 패널을 제거 + dispatch(popPanel(panel_names.PLAYER_PANEL)); + } +}; + +// 모달 비디오를 일시정지 (패널은 유지) +export const pauseModalVideo = () => (dispatch, getState) => { + const panels = getState().panels.panels; + + // modal PlayerPanel 찾기 + const modalPlayerPanel = panels.find( + (panel) => panel.name === panel_names.PLAYER_PANEL && panel.panelInfo?.modal + ); + + if (modalPlayerPanel) { + console.log('[pauseModalVideo] Pausing modal video'); + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + ...modalPlayerPanel.panelInfo, + isPaused: true, // 일시정지 플래그 추가 + }, + }) + ); + } +}; + +// 모달 비디오를 재생 (일시정지 해제) +export const resumeModalVideo = () => (dispatch, getState) => { + const panels = getState().panels.panels; + + // modal PlayerPanel 찾기 + const modalPlayerPanel = panels.find( + (panel) => panel.name === panel_names.PLAYER_PANEL && panel.panelInfo?.modal + ); + + if (modalPlayerPanel && modalPlayerPanel.panelInfo?.isPaused) { + console.log('[resumeModalVideo] Resuming modal video'); + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + ...modalPlayerPanel.panelInfo, + isPaused: false, // 일시정지 해제 + }, + }) + ); + } +}; + // 채팅 로그 가져오기 IF-LGSP-371 export const getChatLog = ({ patnrId, showId }) => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getChatLog onSuccess", response.data); + console.log('getChatLog onSuccess', response.data); dispatch({ type: types.GET_CHAT_LOG, @@ -82,10 +148,10 @@ export const getChatLog = }; const onFail = (error) => { - console.error("getChatLog onFail", error); + console.error('getChatLog onFail', error); }; - TAxios(dispatch, getState, "get", URLS.CHAT_LOG, { patnrId, showId }, {}, onSuccess, onFail); + TAxios(dispatch, getState, 'get', URLS.CHAT_LOG, { patnrId, showId }, {}, onSuccess, onFail); }; // VOD 자막 가져오기 IF-LGSP-072 @@ -93,7 +159,7 @@ export const getSubTitle = ({ showSubtitleUrl }) => (dispatch, getState) => { const onSuccess = (response) => { - console.log("getSubTitle onSuccess", response.data); + console.log('getSubTitle onSuccess', response.data); dispatch({ type: types.GET_SUBTITLE, @@ -102,15 +168,15 @@ export const getSubTitle = }; const onFail = (error) => { - console.error("getSubTitle onFail", error); + console.error('getSubTitle onFail', error); dispatch({ type: types.GET_SUBTITLE, - payload: { url: showSubtitleUrl, data: "Error" }, + payload: { url: showSubtitleUrl, data: 'Error' }, }); }; if (!getState().play.subTitleBlobs[showSubtitleUrl]) { - TAxios(dispatch, getState, "get", URLS.SUBTITLE, { showSubtitleUrl }, {}, onSuccess, onFail); + TAxios(dispatch, getState, 'get', URLS.SUBTITLE, { showSubtitleUrl }, {}, onSuccess, onFail); } else { console.log("playActions getSubTitle no Nothing it's exist", showSubtitleUrl); } @@ -129,33 +195,35 @@ export const CLEAR_PLAYER_INFO = () => ({ * @param {object} videoInfo - 재생할 비디오 정보 (url, id 등) */ export const requestPlayControl = (ownerId, videoInfo) => (dispatch, getState) => { - const { playerControl } = getState().home; - const currentOwnerId = playerControl.ownerId; + const { playerControl } = getState().home; + const currentOwnerId = playerControl.ownerId; - if (currentOwnerId === ownerId) return; // 이미 제어권 소유 + if (currentOwnerId === ownerId) return; // 이미 제어권 소유 - if (currentOwnerId) { - // 현재 제어중인 컴포넌트가 영구재생 배너이면 '일시정지' - if (currentOwnerId === 'banner0_persistent') { - dispatch(pausePlayerControl()); - } else { - // 다른 미리보기라면 완전히 숨김 - dispatch(releasePlayControl(currentOwnerId, true)); - } + if (currentOwnerId) { + // 현재 제어중인 컴포넌트가 영구재생 배너이면 '일시정지' + if (currentOwnerId === 'banner0_persistent') { + dispatch(pausePlayerControl()); + } else { + // 다른 미리보기라면 완전히 숨김 + dispatch(releasePlayControl(currentOwnerId, true)); } - - // 1. 매니저 상태 업데이트 - dispatch({ type: types.SET_PLAYER_CONTROL, payload: { ownerId } }); - - // 2. 공유 PlayerPanel의 상태 업데이트 - dispatch(updatePanel({ - name: panel_names.PLAYER_PANEL, - panelInfo: { - isHidden: false, - modal: true, - ...videoInfo - } - })); + } + + // 1. 매니저 상태 업데이트 + dispatch({ type: types.SET_PLAYER_CONTROL, payload: { ownerId } }); + + // 2. 공유 PlayerPanel의 상태 업데이트 + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + isHidden: false, + modal: true, + ...videoInfo, + }, + }) + ); }; /** @@ -163,28 +231,34 @@ export const requestPlayControl = (ownerId, videoInfo) => (dispatch, getState) = * @param {string} ownerId - 제어권을 해제하는 컴포넌트의 고유 ID * @param {boolean} fromPreemption - 다른 요청에 의해 강제로 중단되었는지 여부 */ -export const releasePlayControl = (ownerId, fromPreemption = false) => (dispatch, getState) => { +export const releasePlayControl = + (ownerId, fromPreemption = false) => + (dispatch, getState) => { const { playerControl } = getState().home; if (fromPreemption || playerControl.ownerId === ownerId) { - // 1. 공유 PlayerPanel을 다시 숨김 - dispatch(updatePanel({ - name: panel_names.PLAYER_PANEL, - panelInfo: { - isHidden: true, - } - })); + // 1. 공유 PlayerPanel을 다시 숨김 + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + isHidden: true, + }, + }) + ); - // 2. 매니저 상태 업데이트 (현재 소유주 없음) - dispatch({ type: types.CLEAR_PLAYER_CONTROL }); + // 2. 매니저 상태 업데이트 (현재 소유주 없음) + dispatch({ type: types.CLEAR_PLAYER_CONTROL }); - // 3. 만약 '일시정지'된 영구재생 비디오가 있었다면, 제어권을 되돌려주고 다시 재생 - if (playerControl.isPaused && playerControl.ownerId === 'banner0_persistent') { - const persistentVideoInfo = { /* 영구 비디오 정보를 가져오는 로직 (필요시) */ }; - dispatch(requestPlayControl('banner0_persistent', persistentVideoInfo)); - } + // 3. 만약 '일시정지'된 영구재생 비디오가 있었다면, 제어권을 되돌려주고 다시 재생 + if (playerControl.isPaused && playerControl.ownerId === 'banner0_persistent') { + const persistentVideoInfo = { + /* 영구 비디오 정보를 가져오는 로직 (필요시) */ + }; + dispatch(requestPlayControl('banner0_persistent', persistentVideoInfo)); + } } -}; + }; /** * 현재 재생 중인 비디오를 '일시정지' 상태로 변경하는 액션. @@ -224,25 +298,25 @@ export const resumePlayerControl = (ownerId) => (dispatch, getState) => { * 이 액션은 어떤 배너에서든 클릭 시 호출됩니다. */ export const goToFullScreen = () => (dispatch, getState) => { - // 공유 PlayerPanel의 'modal' 상태를 false로 변경하여 전체화면으로 전환 - dispatch(updatePanel({ - name: panel_names.PLAYER_PANEL, - panelInfo: { - modal: false, - isHidden: false, // 혹시 숨겨져 있었다면 보이도록 - } - })); + // 공유 PlayerPanel의 'modal' 상태를 false로 변경하여 전체화면으로 전환 + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + modal: false, + isHidden: false, // 혹시 숨겨져 있었다면 보이도록 + }, + }) + ); }; - /** * 영구재생 비디오를 일시정지 상태로 만듭니다. (내부 사용) */ export const pausePlayerControl = () => ({ - type: types.PAUSE_PLAYER_CONTROL + type: types.PAUSE_PLAYER_CONTROL, }); - /** * 전체화면 플레이어에서 미리보기 상태로 복귀할 때 호출됩니다. * 중앙 'playerControl' 상태를 확인하여 올바른 위치와 비디오로 복원합니다. @@ -270,4 +344,4 @@ export const returnToPreview = () => (dispatch, getState) => { // 돌아갈 곳이 없으면 그냥 플레이어를 닫음 dispatch(finishVideoPreview()); } -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx index 13aac021..dcf54e9f 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx @@ -495,7 +495,7 @@ export default function HomeBanner({ firstSpot, spotlightId, handleItemFocus, ha // ); const renderItem = useCallback( - (index, isHorizontal) => { + (index, isHorizontal, videoPlayerable = false) => { const data = bannerDataList?.[index] ?? {}; return (
-
- {$L("Click the screen to see more products!")} -
+{$L('Click the screen to see more products!')}
-