From 5278151102c73ae6993c507f72a1c4cb4d00416e Mon Sep 17 00:00:00 2001 From: optrader Date: Sat, 22 Nov 2025 05:46:17 +0900 Subject: [PATCH] [251122] fix: MediaPanel in VOD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ• 컀밋 μ‹œκ°„: 2025. 11. 22. 05:46:17 πŸ“Š λ³€κ²½ 톡계: β€’ 총 파일: 2개 β€’ μΆ”κ°€: +85쀄 β€’ μ‚­μ œ: -42쀄 πŸ“ μˆ˜μ •λœ 파일: ~ com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx πŸ”§ ν•¨μˆ˜ λ³€κ²½ λ‚΄μš©: πŸ“„ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx (javascript): πŸ”„ Modified: normalizeModalStyle() πŸ”§ μ£Όμš” λ³€κ²½ λ‚΄μš©: β€’ UI μ»΄ν¬λ„ŒνŠΈ μ•„ν‚€ν…μ²˜ κ°œμ„  --- .../components/VideoPlayer/VideoPlayer.v3.js | 6 +- .../src/views/MediaPanel/MediaPanel.v3.jsx | 115 ++++++++++++------ 2 files changed, 83 insertions(+), 38 deletions(-) diff --git a/com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js b/com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js index 4c2c2ca5..b1bda180 100644 --- a/com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js +++ b/com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js @@ -561,7 +561,7 @@ const VideoPlayerBase = class extends React.Component { /** * Disables seek function. * - * Note that jump by arrow keys will also be disabled when `true`. + * Note that jump by arrow keys will also be disabled when `true`. * * @type {Boolean} * @public @@ -2314,6 +2314,10 @@ const VideoPlayerBase = class extends React.Component { mediaProps.height = height; mediaProps.videoRef = this.setVideoRef; mediaProps.config = reactPlayerConfig; + // μ›Ή/TV μ „μ²΄ν™”λ©΄μ—μ„œ ReactPlayer(YouTube) iframe이 자체 μ»¨νŠΈλ‘€μ„ ν™œμ„±ν™”ν•˜μ§€ μ•Šλ„λ‘ 포인터 이벀트 차단 + if (!panelInfo.modal) { + mediaProps.style = { ...(mediaProps.style || {}), pointerEvents: 'none' }; + } delete mediaProps.mediaComponent; delete mediaProps.ref; // mediaProps.isYoutube = isYoutube; diff --git a/com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx b/com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx index 8e9c7613..da0e1510 100644 --- a/com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx +++ b/com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx @@ -211,6 +211,7 @@ const MediaPanel = React.forwardRef( }); const videoPlayer = useRef(null); + const focusReturnRef = useRef(null); const isTransitioningToFullscreen = useRef(false); const [playListInfo, setPlayListInfo] = USE_STATE('playListInfo', ''); const [shopNowInfo, setShopNowInfo] = USE_STATE('shopNowInfo'); @@ -2004,42 +2005,79 @@ const MediaPanel = React.forwardRef( }; }, []); - const onEnded = useCallback((e) => { - if (panelInfoRef.current.shptmBanrTpNm === 'MEDIA') { - // ⚠️ λ°°κ²½ μ„€μ • 볡원 μ·¨μ†Œ - DetailPanel μ—…λ°μ΄νŠΈ 없이 λ°”λ‘œ νŒ¨λ„ 제거 - // dispatch( - // updatePanel({ - // name: panel_names.DETAIL_PANEL, - // panelInfo: { - // launchedFromPlayer: true, - // isPlayerFinished: true, - // }, - // }) - // ); - console.log('[MediaPanel] 🚫 Skipping background restoration for ended media'); - Spotlight.pause(); - setTimeout(() => { - Spotlight.resume(); - dispatch(PanelActions.popPanel()); - }, VIDEO_END_ACTION_DELAY); + const focusBackToPanel = useCallback(() => { + if (focusReturnRef.current) { + focusReturnRef.current.focus(); + return true; + } + return false; + }, []); + + const focusBackButtonOrFallback = useCallback(() => { + if (Spotlight.focus('player-back-button')) { + return true; + } + return focusBackToPanel(); + }, [focusBackToPanel]); + + const stopExternalPlayer = useCallback(() => { + const playerInstance = videoPlayer.current; + const media = playerInstance?.video; + + if (!media) { return; } - if (panelInfoRef.current.shptmBanrTpNm === 'VOD') { - Spotlight.pause(); - setTimeout(() => { - Spotlight.resume(); - if (panelInfoRef.current.modal) { - videoPlayer.current.play(); - } else { - dispatch(PanelActions.popPanel(panel_names.MEDIA_PANEL)); - } - }, VIDEO_END_ACTION_DELAY); - e?.stopPropagation(); - e?.preventDefault(); - return; + + if (typeof media.stopVideo === 'function') { + media.stopVideo(); + } + if (typeof media.seekTo === 'function') { + media.seekTo(0); + } + if (typeof media.pause === 'function') { + media.pause(); } }, []); + const onEnded = useCallback( + (e) => { + const currentInfo = panelInfoRef.current; + + // MEDIA: κΈ°μ‘΄ λ™μž‘ μœ μ§€ (λ°°κ²½ 볡원 없이 μ¦‰μ‹œ pop) + if (currentInfo.shptmBanrTpNm === 'MEDIA') { + console.log('[MediaPanel] 🚫 Skipping background restoration for ended media'); + Spotlight.pause(); + setTimeout(() => { + Spotlight.resume(); + dispatch(PanelActions.popPanel()); + }, VIDEO_END_ACTION_DELAY); + return; + } + + // VOD: modal 여뢀에 따라 λ™μž‘ 뢄리 + if (currentInfo.shptmBanrTpNm === 'VOD') { + Spotlight.pause(); + setTimeout(() => { + stopExternalPlayer(); + if (currentInfo.modal) { + // λͺ¨λ‹¬: ν™”λ©΄ μœ μ§€ + Back 포컀슀 회수 + videoPlayer.current?.showControls?.(); + Spotlight.resume(); + focusBackButtonOrFallback(); + } else { + // 전체화면: λ°”λ‘œ μ’…λ£Œ(pop)ν•˜μ—¬ ν¬μ»€μŠ€κ°€ VOD 컨트둀둜 남지 μ•Šκ²Œ 함 + Spotlight.resume(); + dispatch(PanelActions.popPanel(panel_names.MEDIA_PANEL)); + } + }, VIDEO_END_ACTION_DELAY); + e?.stopPropagation(); + e?.preventDefault(); + return; + } + }, + [dispatch, focusBackButtonOrFallback, stopExternalPlayer] + ); + const onKeyDown = (ev) => { if (ev.keyCode === 34) { handleIndicatorDownClick(); @@ -2263,14 +2301,17 @@ const MediaPanel = React.forwardRef( > { - // if (!panelInfo?.modal && isOnTop && panelInfo?.shptmBanrTpNm !== 'MEDIA') { - // setBelowContentsVisible((prev) => !prev); - // } - // }} > +