From 3fd3b66cb39653ce8ef7294d9b2346363c184283 Mon Sep 17 00:00:00 2001 From: optrader Date: Wed, 17 Dec 2025 13:43:33 +0900 Subject: [PATCH] =?UTF-8?q?[251217]=20fix:=20PlayerPanel=20activity=20chec?= =?UTF-8?q?k=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ• 컀밋 μ‹œκ°„: 2025. 12. 17. 13:43:33 πŸ“Š λ³€κ²½ 톡계: β€’ 총 파일: 1개 β€’ μΆ”κ°€: +133쀄 β€’ μ‚­μ œ: -6쀄 πŸ“ μˆ˜μ •λœ 파일: ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx πŸ”§ μ£Όμš” λ³€κ²½ λ‚΄μš©: β€’ 쀑간 규λͺ¨ κΈ°λŠ₯ κ°œμ„  --- .../src/views/PlayerPanel/PlayerPanel.jsx | 139 +++++++++++++++++- 1 file changed, 133 insertions(+), 6 deletions(-) diff --git a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx index ec7e7134..8d80a0a1 100644 --- a/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx +++ b/com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx @@ -1845,6 +1845,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props if (watchIntervalLive.current) clearInterval(watchIntervalLive.current); if (watchIntervalVod.current) clearInterval(watchIntervalVod.current); if (watchIntervalMedia.current) clearInterval(watchIntervalMedia.current); + if (activityCheckIntervalRef.current) clearInterval(activityCheckIntervalRef.current); }; }, []); @@ -2345,7 +2346,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props setPrevChannelIndex(selectedIndex); } setSideContentsVisible(true); - }, [dispatch, playListInfo, selectedIndex, sideContentsVisible, initialEnter]); + }, [dispatch, playListInfo, selectedIndex, sideContentsVisible, initialEnter, tabContainerVersion, tabIndexV2]); const handleIndicatorUpClick = useCallback(() => { if (!initialEnter) { @@ -2393,7 +2394,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props setPrevChannelIndex(selectedIndex); } setSideContentsVisible(true); - }, [dispatch, playListInfo, selectedIndex, sideContentsVisible, initialEnter]); + }, [dispatch, playListInfo, selectedIndex, sideContentsVisible, initialEnter, tabContainerVersion, tabIndexV2]); useEffect(() => { if (panelInfo.shptmBanrTpNm === 'VOD' && panelInfo.patnrId && panelInfo.showId) { @@ -2553,6 +2554,11 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props const timerIdTabAutoAdvance = useRef(null); const prevTabIndexV2 = useRef(null); + // Activity Check for tabIndex auto-advance + const lastActivityTimeRef = useRef(Date.now()); + const activityCheckIntervalRef = useRef(null); + const ACTIVITY_TIMEOUT = 1000; // 1초 λ™μ•ˆ ν™œλ™μ΄ μ—†μœΌλ©΄ 타이머 μ§„ν–‰ + const showSideContents = useMemo(() => { return ( sideContentsVisible && @@ -2664,17 +2670,62 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props timerIdTabAutoAdvance.current = null; }, []); + // Activity 감지 ν•¨μˆ˜ + const onActivityDetected = useCallback(() => { + lastActivityTimeRef.current = Date.now(); + dlog('[PlayerPanel] 🎯 Activity detected - timer will be delayed', { + timestamp: new Date().toISOString(), + }); + }, []); + + // Activity μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” ν•¨μˆ˜ (1초 νƒ€μž„μ•„μ›ƒ 체크) + const isInactive = useCallback(() => { + const now = Date.now(); + const timeSinceLastActivity = now - lastActivityTimeRef.current; + return timeSinceLastActivity > ACTIVITY_TIMEOUT; + }, []); + const resetTimerTabAutoAdvance = useCallback( (timeout) => { if (timerIdTabAutoAdvance.current) { clearTimerTabAutoAdvance(); } - timerIdTabAutoAdvance.current = setTimeout(() => { - setTabIndexV2(2); - }, timeout); + // Activity check interval μ„€μ • (λ§€ 100msλ§ˆλ‹€ 체크) + if (activityCheckIntervalRef.current) { + clearInterval(activityCheckIntervalRef.current); + } + + let elapsedTime = 0; + + activityCheckIntervalRef.current = setInterval(() => { + // ν™œλ™μ΄ 없을 λ•Œλ§Œ κ²½κ³Ό μ‹œκ°„ 증가 + if (isInactive()) { + elapsedTime += 100; + dlog('[PlayerPanel] ⏱️ TabIndex auto-advance: inactive', { + elapsedTime, + requiredTime: timeout, + }); + + // ν•„μš”ν•œ μ‹œκ°„λ§ŒνΌ κ²½κ³Όν–ˆμœΌλ©΄ 타이머 μ‹€ν–‰ + if (elapsedTime >= timeout) { + dlog('[PlayerPanel] βœ… TabIndex auto-advance executing - setTabIndexV2(2)', { + totalElapsed: elapsedTime, + timeout, + }); + clearInterval(activityCheckIntervalRef.current); + setTabIndexV2(2); + } + } else { + // ν™œλ™μ΄ κ°μ§€λ˜λ©΄ κ²½κ³Ό μ‹œκ°„ 리셋 + dlog('[PlayerPanel] πŸ”„ Activity detected - resetting elapsed time', { + previousElapsed: elapsedTime, + }); + elapsedTime = 0; + } + }, 100); }, - [clearTimerTabAutoAdvance] + [clearTimerTabAutoAdvance, isInactive] ); // Redux둜 μ˜€λ²„λ ˆμ΄ μˆ¨κΉ€ @@ -2699,6 +2750,10 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props if (timerIdTabAutoAdvance.current) { clearTimerTabAutoAdvance(); } + if (activityCheckIntervalRef.current) { + clearInterval(activityCheckIntervalRef.current); + activityCheckIntervalRef.current = null; + } dispatch(resetPlayerOverlays()); } @@ -2913,6 +2968,53 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props panelInfo?.modal, ]); + // PageUp/PageDown으둜 λΉ„λ””μ˜€ λ³€κ²½ μ‹œ ν˜„μž¬ μž¬μƒ λ°°λ„ˆλ‘œ 포컀슀 이동 + useEffect(() => { + if (tabContainerVersion === 2 && + tabIndexV2 === 1 && + panelInfo?.isIndicatorByClick && + selectedIndex !== null && + selectedIndex >= 0) { + + dlog('[PlayerPanel] 🎯 PageUp/PageDown ν›„ 포컀슀 이동 μ€€λΉ„', { + selectedIndex, + tabContainerVersion, + tabIndexV2, + isIndicatorByClick: panelInfo.isIndicatorByClick + }); + + const bannerSpotlightId = `banner${selectedIndex}`; + + setTimeout(() => { + dlog('[PlayerPanel] πŸ” 포컀슀 이동 μ‹œλ„:', bannerSpotlightId); + + const bannerElement = document.querySelector(`[data-spotlight-id="${bannerSpotlightId}"]`); + + if (bannerElement) { + dlog('[PlayerPanel] βœ… λ°°λ„ˆ μš”μ†Œ 찾음, 포컀슀 이동 μ‹€ν–‰'); + Spotlight.focus(bannerElement); + } else { + dlog('[PlayerPanel] ⚠️ λ°°λ„ˆ μš”μ†Œ μ°Ύμ§€ λͺ»ν•¨:', bannerSpotlightId); + // λͺ¨λ“  λ°°λ„ˆ μš”μ†Œ λͺ©λ‘ 좜λ ₯ + const allBanners = document.querySelectorAll('[data-spotlight-id^="banner"]'); + dlog('[PlayerPanel] πŸ” μ‚¬μš© κ°€λŠ₯ν•œ λ°°λ„ˆ λͺ©λ‘:', + Array.from(allBanners).map(el => el.getAttribute('data-spotlight-id')) + ); + } + + // ν”Œλž˜κ·Έ 리셋 + dispatch( + updatePanel({ + name: panel_names.PLAYER_PANEL, + panelInfo: { + isIndicatorByClick: false + }, + }) + ); + }, 200); // DOM μ—…λ°μ΄νŠΈ λŒ€κΈ° + } + }, [selectedIndex, tabContainerVersion, tabIndexV2, panelInfo?.isIndicatorByClick, dispatch]); + // TabIndex 1 μžλ™ λ‹€μŒ λ‹¨κ³„λ‘œ 이동 useEffect(() => { // tabIndex === 1일 λ•Œλ§Œ μ‹€ν–‰ @@ -2939,6 +3041,31 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props clearTimerTabAutoAdvance, ]); + // Activity detection for tabIndex auto-advance (mousemove, keydown, click) + useEffect(() => { + // tabIndex === 1일 λ•Œλ§Œ Activity 감지 ν™œμ„±ν™” + if (tabIndexV2 !== 1 || !belowContentsVisible) { + return; + } + + dlog('[PlayerPanel] πŸŽ™οΈ Activity listener registered for tabIndex=1'); + + const handleMouseMove = onActivityDetected; + const handleKeyDown = onActivityDetected; + const handleClick = onActivityDetected; + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('keydown', handleKeyDown); + document.addEventListener('click', handleClick); + + return () => { + dlog('[PlayerPanel] πŸŽ™οΈ Activity listener unregistered'); + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('keydown', handleKeyDown); + document.removeEventListener('click', handleClick); + }; + }, [tabIndexV2, belowContentsVisible, onActivityDetected]); + useLayoutEffect(() => { const videoContainer = document.querySelector(`.${css.videoContainer}`);