From e21f6a10728680d14f0304605d398bc558d4f9f7 Mon Sep 17 00:00:00 2001 From: optrader Date: Thu, 20 Nov 2025 10:24:56 +0900 Subject: [PATCH] [251120] fix: LiveShow BackButton ArrorDown handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🕐 커밋 시간: 2025. 11. 20. 10:24:56 📊 변경 통계: • 총 파일: 2개 • 추가: +77줄 • 삭제: -15줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx 🔧 주요 변경 내용: • 소규모 기능 개선 --- .../PlayerOverlay/PlayerOverlayContents.jsx | 48 +++++++++++++++---- .../PlayerTabContents/v2/TabContainer.v2.jsx | 44 +++++++++++++++-- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx index a2fcff54..b6660d54 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx @@ -160,22 +160,54 @@ function PlayerOverlayContents({ e.stopPropagation(); e.preventDefault(); + console.log(`[onSpotlightMoveBelowTab] tabIndexV2: ${tabIndexV2}`); + // tabIndexV2에 따라 다른 버튼으로 포커스 이동 if (tabIndexV2 === 0) { // ShopNow 탭: Close 버튼으로 // Spotlight.focus('below-tab-close-button'); - Spotlight.focus('shownow_close_button'); + const result = Spotlight.focus('shownow_close_button'); + console.log(`[onSpotlightMoveBelowTab] tabIndexV2=0, focus result:`, result); } else if (tabIndexV2 === 1) { // LIVE CHANNEL 탭: LIVE CHANNEL 버튼으로 - Spotlight.focus('below-tab-live-channel-button'); + const result = Spotlight.focus('below-tab-live-channel-button'); + console.log(`[onSpotlightMoveBelowTab] tabIndexV2=1, focus result:`, result); } else if (tabIndexV2 === 2) { // ShopNowButton: ShopNowButton으로 - Spotlight.focus('below-tab-shop-now-button'); + const result = Spotlight.focus('below-tab-shop-now-button'); + console.log(`[onSpotlightMoveBelowTab] tabIndexV2=2, focus result:`, result); } }, [tabIndexV2] ); + // Back Button arrow down 전용 핸들러 - tabIndex에 따라 다르게 포커스 설정 + const handleBackButtonDown = useCallback( + (e) => { + e.stopPropagation(); + e.preventDefault(); + + if (tabContainerVersion === 2 && belowContentsVisible) { + console.log(`[handleBackButtonDown] tabIndexV2: ${tabIndexV2}`); + + if (tabIndexV2 === 0) { + const result = Spotlight.focus('shownow_close_button'); + console.log(`[handleBackButtonDown] tabIndexV2=0, focus result:`, result); + } else if (tabIndexV2 === 1) { + const result = Spotlight.focus('below-tab-live-channel-button'); + console.log(`[handleBackButtonDown] tabIndexV2=1, focus result:`, result); + } else if (tabIndexV2 === 2) { + const result = Spotlight.focus('live-channel-next-button'); + // const result = Spotlight.focus('below-tab-shop-now-button'); + console.log(`[handleBackButtonDown] tabIndexV2=2, focus result:`, result); + } + } else { + onSpotlightMoveMediaButton(e); + } + }, + [tabContainerVersion, belowContentsVisible, tabIndexV2, onSpotlightMoveMediaButton] + ); + const onSpotlightMoveBackButton = useCallback(() => { return Spotlight.focus(SpotlightIds.PLAYER_BACK_BUTTON); }, []); @@ -186,7 +218,7 @@ function PlayerOverlayContents({ if (ev.keyCode === 40 && currentId === SpotlightIds.PLAYER_BACK_BUTTON) { ev.preventDefault(); ev.stopPropagation(); - return onSpotlightMoveMediaButton(ev); + return handleBackButtonDown(ev); } if (ev.keyCode === 39 && currentId === SpotlightIds.PLAYER_BACK_BUTTON) { ev.preventDefault(); @@ -204,7 +236,7 @@ function PlayerOverlayContents({ return onSpotlightMoveBackButton(); } }, - [onSpotlightMoveBackButton, onSpotlightMoveMediaButton, onSpotlightMoveSubtitleButton] + [onSpotlightMoveBackButton, onSpotlightMoveMediaButton, onSpotlightMoveSubtitleButton, handleBackButtonDown] ); const shouldShowExtendedControls = useMemo( @@ -319,11 +351,7 @@ function PlayerOverlayContents({ onClick={onClickBack} className={css.backIcon} spotlightId="player-back-button" - onSpotlightDown={ - tabContainerVersion === 2 && belowContentsVisible - ? onSpotlightMoveBelowTab - : onSpotlightMoveMediaButton - } + onSpotlightDown={handleBackButtonDown} onSpotlightRight={onSpotlightMoveSubtitleButton} onSpotlightUp={onSpotlightMoveSubtitleButton} aria-label="Video Player Close" diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx index f675c6e6..a9dabf68 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx @@ -13,6 +13,7 @@ import icon_shop_now from '../../../../../assets/images/player/icon_tabcontainer import { LOG_MENU } from '../../../../utils/Config'; import { $L } from '../../../../utils/helperMethods'; import { SpotlightIds } from '../../../../utils/SpotlightIds'; +import usePrevious from '../../../../hooks/usePrevious'; import LiveChannelContents from '../TabContents/LiveChannelContents'; import ShopNowContents from '../TabContents/ShopNowContents'; import ShopNowButton from './ShopNowButton'; @@ -146,16 +147,46 @@ export default function TabContainerV2({ Spotlight.focus(SpotlightIds.PLAYER_BACK_BUTTON); }, []); - // tabIndex가 2(ShopNowButton)로 변경되면 자동으로 포커스 이동 - useEffect(() => { - if (tabIndex === 2) { + // 이전 tabIndex 값 추적 + const prevTabIndexRef = usePrevious(tabIndex); + const prevTabIndex = prevTabIndexRef.current; + + // 하나의 함수에서 모든 tabIndex 변화 처리 + const handleTabIndexChange = useCallback((newTabIndex, oldTabIndex) => { + console.log(`[TabIndexChange] Tab changed from ${oldTabIndex} to ${newTabIndex}`); + + if (newTabIndex === 0) { + // tabIndex = 0 (ShopNow) + const timeoutId = setTimeout(() => { + Spotlight.focus('shownow_close_button'); + }, 100); + return () => clearTimeout(timeoutId); + } + + if (newTabIndex === 1) { + // tabIndex = 1 (LiveChannel) + const timeoutId = setTimeout(() => { + Spotlight.focus('below-tab-live-channel-button'); + }, 100); + return () => clearTimeout(timeoutId); + } + + if (newTabIndex === 2) { + // tabIndex = 2 (ShopNowButton) const timeoutId = setTimeout(() => { Spotlight.focus('below-tab-shop-now-button'); }, 100); - return () => clearTimeout(timeoutId); } - }, [tabIndex]); + }, []); + + // tabIndex 변화 감지 및 처리 + useEffect(() => { + // 초기 렌더링이 아닐 때만 실행 (prevTabIndex가 정의되었을 때) + if (prevTabIndex !== undefined && prevTabIndex !== tabIndex) { + handleTabIndexChange(tabIndex, prevTabIndex); + } + }, [tabIndex, prevTabIndex, handleTabIndexChange]); return ( { + console.log('[TabContainerV2] below-tab-live-channel-button focused'); + }} > LIVE CHANNEL