[251115] fix: DetailPanel FullScree issue

🕐 커밋 시간: 2025. 11. 15. 20:10:38

📊 변경 통계:
  • 총 파일: 7개
  • 추가: +134줄
  • 삭제: -63줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/actions/actionTypes.js
  ~ com.twin.app.shoptime/src/actions/homeActions.js
  ~ com.twin.app.shoptime/src/components/VideoPlayer/TReactPlayer.jsx
  ~ com.twin.app.shoptime/src/reducers/homeReducer.js
  ~ com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx
  ~ com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx
  ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/actions/homeActions.js (javascript):
     Added: setDefaultFocus()
  📄 com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx (javascript):
    🔄 Modified: SpotlightContainerDecorator()
  📄 com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx (javascript):
    🔄 Modified: normalizeModalStyle()

🔧 주요 변경 내용:
  • 타입 시스템 안정성 강화
  • 핵심 비즈니스 로직 개선
  • UI 컴포넌트 아키텍처 개선
This commit is contained in:
2025-11-15 20:10:39 +09:00
parent 2ac217fb10
commit 70381438ac
7 changed files with 345 additions and 286 deletions

View File

@@ -112,6 +112,7 @@ export const types = {
CHECK_ENTER_THROUGH_GNB: 'CHECK_ENTER_THROUGH_GNB', CHECK_ENTER_THROUGH_GNB: 'CHECK_ENTER_THROUGH_GNB',
SET_DEFAULT_FOCUS: 'SET_DEFAULT_FOCUS', SET_DEFAULT_FOCUS: 'SET_DEFAULT_FOCUS',
SET_BANNER_INDEX: 'SET_BANNER_INDEX', SET_BANNER_INDEX: 'SET_BANNER_INDEX',
SET_VIDEO_TRANSITION_LOCK: 'SET_VIDEO_TRANSITION_LOCK',
RESET_HOME_INFO: 'RESET_HOME_INFO', RESET_HOME_INFO: 'RESET_HOME_INFO',
UPDATE_HOME_INFO: 'UPDATE_HOME_INFO', UPDATE_HOME_INFO: 'UPDATE_HOME_INFO',

View File

@@ -483,6 +483,11 @@ export const setDefaultFocus = (focus) => ({
payload: focus, payload: focus,
}); });
export const setVideoTransitionLock = (isLocked) => ({
type: types.SET_VIDEO_TRANSITION_LOCK,
payload: Boolean(isLocked),
});
export const checkEnterThroughGNB = (boolean) => ({ export const checkEnterThroughGNB = (boolean) => ({
type: types.CHECK_ENTER_THROUGH_GNB, type: types.CHECK_ENTER_THROUGH_GNB,
payload: boolean, payload: boolean,

View File

@@ -1,21 +1,21 @@
import React, { useCallback, useMemo, useRef, useEffect } from "react"; import React, { useCallback, useMemo, useRef, useEffect } from 'react';
import ReactPlayer from "react-player"; import ReactPlayer from 'react-player';
import handle from "@enact/core/handle"; import handle from '@enact/core/handle';
var handledMediaEventsMap = [ var handledMediaEventsMap = [
"onReady", 'onReady',
"onStart", 'onStart',
"onPlay", 'onPlay',
"onProgress", 'onProgress',
"onDuration", 'onDuration',
"onPause", 'onPause',
"onBuffer", 'onBuffer',
"onBufferEnd", 'onBufferEnd',
"onSeek", 'onSeek',
"onEnded", 'onEnded',
"onError", 'onError',
]; ];
export default function TReactPlayer({ export default function TReactPlayer({
@@ -29,21 +29,21 @@ export default function TReactPlayer({
const handleEvent = useCallback( const handleEvent = useCallback(
(type) => (ev) => { (type) => (ev) => {
if (type === "onReady") { if (type === 'onReady') {
if (videoRef) { if (videoRef) {
const videoNode = playerRef.current.getInternalPlayer(); const videoNode = playerRef.current.getInternalPlayer();
videoRef(videoNode); videoRef(videoNode);
const iframeEl = const iframeEl =
typeof playerRef.current?.getInternalPlayer === "function" typeof playerRef.current?.getInternalPlayer === 'function'
? playerRef.current.getInternalPlayer("iframe") ? playerRef.current.getInternalPlayer('iframe')
: null; : null;
if (iframeEl) { if (iframeEl) {
iframeEl.setAttribute("tabIndex", "-1"); iframeEl.setAttribute('tabIndex', '-1');
iframeEl.setAttribute("aria-hidden", "true"); iframeEl.setAttribute('aria-hidden', 'true');
} }
if ( if (
videoNode.tagName && videoNode.tagName &&
!Object.prototype.hasOwnProperty.call(videoNode, "proportionPlayed") !Object.prototype.hasOwnProperty.call(videoNode, 'proportionPlayed')
) { ) {
Object.defineProperties(videoNode, { Object.defineProperties(videoNode, {
error: { error: {
@@ -60,8 +60,7 @@ export default function TReactPlayer({
get: function () { get: function () {
return ( return (
videoNode.buffered.length && videoNode.buffered.length &&
videoNode.buffered.end(videoNode.buffered.length - 1) / videoNode.buffered.end(videoNode.buffered.length - 1) / videoNode.duration
videoNode.duration
); );
}, },
}, },
@@ -71,9 +70,7 @@ export default function TReactPlayer({
}, },
}, },
}); });
} else if ( } else if (!Object.prototype.hasOwnProperty.call(videoNode, 'proportionPlayed')) {
!Object.prototype.hasOwnProperty.call(videoNode, "proportionPlayed")
) {
videoNode.play = videoNode.playVideo; videoNode.play = videoNode.playVideo;
videoNode.pause = videoNode.pauseVideo; videoNode.pause = videoNode.pauseVideo;
videoNode.seek = videoNode.seekTo; videoNode.seek = videoNode.seekTo;
@@ -130,9 +127,9 @@ export default function TReactPlayer({
}); });
} }
} }
handle.forward("onLoadStart", { type, ev }, rest); handle.forward('onLoadStart', { type, ev }, rest);
} }
handle.forward("onUpdate", { type, ev }, rest); handle.forward('onUpdate', { type, ev }, rest);
}, },
[videoRef] [videoRef]
); );
@@ -151,7 +148,7 @@ export default function TReactPlayer({
const videoNode = playerRef.current?.getInternalPlayer(); const videoNode = playerRef.current?.getInternalPlayer();
if (videoNode && videoNode.pause) { if (videoNode && videoNode.pause) {
videoNode.pause(); videoNode.pause();
videoNode.src = ""; videoNode.src = '';
videoNode.srcObject = null; videoNode.srcObject = null;
} }
}; };
@@ -162,6 +159,7 @@ export default function TReactPlayer({
ref={playerRef} ref={playerRef}
url={url} url={url}
progressInterval={1000} progressInterval={1000}
config={rest.config}
{...handledMediaEvents} {...handledMediaEvents}
{...rest} {...rest}
playsinline // Add playsinline attribute here playsinline // Add playsinline attribute here

View File

@@ -28,6 +28,7 @@ const initialState = {
termsIdMap: {}, // added new property to initialState termsIdMap: {}, // added new property to initialState
optionalTermsAvailable: false, // 선택약관 존재 여부 optionalTermsAvailable: false, // 선택약관 존재 여부
persistentVideoInfo: null, // 영구재생 비디오 정보 persistentVideoInfo: null, // 영구재생 비디오 정보
videoTransitionLocked: false,
}; };
export const homeReducer = (state = initialState, action) => { export const homeReducer = (state = initialState, action) => {
@@ -192,6 +193,12 @@ export const homeReducer = (state = initialState, action) => {
}; };
} }
case types.SET_VIDEO_TRANSITION_LOCK:
return {
...state,
videoTransitionLocked: action.payload,
};
case types.CHECK_ENTER_THROUGH_GNB: { case types.CHECK_ENTER_THROUGH_GNB: {
return { return {
...state, ...state,

View File

@@ -15,7 +15,7 @@ import emptyVerImage from '../../../../assets/images/img-home-banner-empty-ver.p
import defaultImageItem from '../../../../assets/images/img-thumb-empty-product@3x.png'; import defaultImageItem from '../../../../assets/images/img-thumb-empty-product@3x.png';
import liveShow from '../../../../assets/images/tag-liveshow.png'; import liveShow from '../../../../assets/images/tag-liveshow.png';
import { changeAppStatus } from '../../../actions/commonActions'; import { changeAppStatus } from '../../../actions/commonActions';
import { updateHomeInfo } from '../../../actions/homeActions'; import { updateHomeInfo, setVideoTransitionLock } from '../../../actions/homeActions';
import { sendLogTopContents, sendLogTotalRecommend } from '../../../actions/logActions'; import { sendLogTopContents, sendLogTotalRecommend } from '../../../actions/logActions';
import { pushPanel } from '../../../actions/panelActions'; import { pushPanel } from '../../../actions/panelActions';
import { import {
@@ -83,8 +83,13 @@ export default function RandomUnit({
const [isFocused, setIsFocused] = useState(false); const [isFocused, setIsFocused] = useState(false);
const [videoError, setVideoError] = useState(false); const [videoError, setVideoError] = useState(false);
const [liveIndicies, setLiveIndicies] = useState([]); const [liveIndicies, setLiveIndicies] = useState([]);
const defaultFocus = useSelector((state) => state.home.defaultFocus);
const isVideoTransitionLocked = useSelector((state) => state.home.videoTransitionLocked);
const timerRef = useRef(); const timerRef = useRef();
const keepTimerOnBlurRef = useRef(false);
const hasAutoPlayStartedRef = useRef(false);
const isDefaultAutoPlayTarget = defaultFocus === spotlightId;
const bannerDataRef = useRef(bannerData); const bannerDataRef = useRef(bannerData);
const randomDataRef = useRef( const randomDataRef = useRef(
bannerDetailInfos && randomNumber !== undefined && bannerDetailInfos.length > 0 bannerDetailInfos && randomNumber !== undefined && bannerDetailInfos.length > 0
@@ -92,12 +97,36 @@ export default function RandomUnit({
: null : null
); );
// ✅ 현재 PlayerPanel의 modal 상태 추적
const playerPanelInfo = useSelector((state) => { const playerPanelInfo = useSelector((state) => {
const playerPanel = state.panels.panels.find((p) => p.name === panel_names.PLAYER_PANEL); const playerPanel = state.panels.panels.find((p) => p.name === panel_names.PLAYER_PANEL);
return playerPanel?.panelInfo; return playerPanel?.panelInfo;
}); });
const handleStartVideo = useCallback(
(videoProps) => {
dispatch(setVideoTransitionLock(true));
dispatch(startVideoPlayerNew(videoProps));
},
[dispatch]
);
const finishAndUnlock = useCallback(() => {
dispatch(finishVideoPreview());
dispatch(setVideoTransitionLock(false));
}, [dispatch]);
useEffect(() => {
if (isVideoTransitionLocked && isCurrentBannerVideoPlaying) {
dispatch(setVideoTransitionLock(false));
}
}, [dispatch, isCurrentBannerVideoPlaying, isVideoTransitionLocked]);
useEffect(() => {
if (isVideoTransitionLocked && videoError) {
dispatch(setVideoTransitionLock(false));
}
}, [dispatch, isVideoTransitionLocked, videoError]);
const topContentsLogInfo = useMemo(() => { const topContentsLogInfo = useMemo(() => {
if (randomDataRef.current) { if (randomDataRef.current) {
const currentRandomData = randomDataRef.current; const currentRandomData = randomDataRef.current;
@@ -403,8 +432,8 @@ export default function RandomUnit({
let action = linkType === 'DSP00507' ? startVideoPlayer : pushPanel; let action = linkType === 'DSP00507' ? startVideoPlayer : pushPanel;
const isNavigatingToDetail = linkInfo.name === panel_names.DETAIL_PANEL; const isNavigatingToDetail = linkInfo.name === panel_names.DETAIL_PANEL;
if (isNavigatingToDetail && playerPanelInfo?.modal !== false && isCurrentBannerVideoPlaying) { if (isNavigatingToDetail && playerPanelInfo?.modal !== false) {
dispatch(finishVideoPreview()); finishAndUnlock();
} }
dispatch(action(linkInfo)); dispatch(action(linkInfo));
@@ -428,13 +457,13 @@ export default function RandomUnit({
topContentsLogInfo, topContentsLogInfo,
playerPanelInfo?.modal, playerPanelInfo?.modal,
sendBannerLog, sendBannerLog,
isCurrentBannerVideoPlaying, finishAndUnlock,
]); ]);
// 투데이즈딜 클릭 // 투데이즈딜 클릭
const todayDealClick = useCallback(() => { const todayDealClick = useCallback(() => {
if (playerPanelInfo?.modal !== false && isCurrentBannerVideoPlaying) { if (playerPanelInfo?.modal !== false) {
dispatch(finishVideoPreview()); finishAndUnlock();
} }
dispatch( dispatch(
@@ -463,7 +492,7 @@ export default function RandomUnit({
topContentsLogInfo, topContentsLogInfo,
sendBannerLog, sendBannerLog,
playerPanelInfo?.modal, playerPanelInfo?.modal,
isCurrentBannerVideoPlaying, finishAndUnlock,
]); ]);
// 비디오 클릭 // 비디오 클릭
@@ -491,20 +520,18 @@ export default function RandomUnit({
playerPanelInfo?.modal playerPanelInfo?.modal
); );
dispatch( handleStartVideo({
startVideoPlayerNew({ bannerId: spotlightId,
bannerId: spotlightId, showUrl: randomData.showUrl,
showUrl: randomData.showUrl, patnrId: randomData.patnrId,
patnrId: randomData.patnrId, showId: randomData.showId,
showId: randomData.showId, shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : 'MEDIA',
shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : 'MEDIA', lgCatCd: randomData.lgCatCd,
lgCatCd: randomData.lgCatCd, chanId: randomData.brdcChnlId,
chanId: randomData.brdcChnlId, modal: false,
modal: false, modalContainerId: spotlightId,
modalContainerId: spotlightId, modalClassName: css.videoModal,
modalClassName: css.videoModal, });
})
);
dispatch( dispatch(
sendLogTopContents({ sendLogTopContents({
@@ -526,6 +553,7 @@ export default function RandomUnit({
onBlur, onBlur,
playerPanelInfo?.modal, playerPanelInfo?.modal,
dispatch, dispatch,
handleStartVideo,
]); ]);
// 투데이즈 딜 가격 정보 // 투데이즈 딜 가격 정보
@@ -574,34 +602,55 @@ export default function RandomUnit({
useEffect(() => { useEffect(() => {
if (isFocused && !videoError) { if (isFocused && !videoError) {
timerRef.current = setTimeout( if (timerRef.current) {
() => clearTimeout(timerRef.current);
dispatch( }
startVideoPlayerNew({ keepTimerOnBlurRef.current = isDefaultAutoPlayTarget && !hasAutoPlayStartedRef.current;
bannerId: spotlightId, timerRef.current = setTimeout(() => {
showUrl: randomData.showUrl, handleStartVideo({
patnrId: randomData.patnrId, bannerId: spotlightId,
showId: randomData.showId, showUrl: randomData.showUrl,
shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : 'MEDIA', patnrId: randomData.patnrId,
lgCatCd: randomData.lgCatCd, showId: randomData.showId,
chanId: randomData.brdcChnlId, shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : 'MEDIA',
modal: true, lgCatCd: randomData.lgCatCd,
modalContainerId: spotlightId, chanId: randomData.brdcChnlId,
modalClassName: css.videoModal, modal: true,
isVerticalModal: !isHorizontal, modalContainerId: spotlightId,
}) modalClassName: css.videoModal,
), isVerticalModal: !isHorizontal,
1000 });
); if (isDefaultAutoPlayTarget) {
hasAutoPlayStartedRef.current = true;
}
keepTimerOnBlurRef.current = false;
timerRef.current = null;
}, 1000);
} }
if (!isFocused) { if (!isFocused) {
setVideoError(false); setVideoError(false);
// dispatch(finishVideoPreview()); if (timerRef.current && !keepTimerOnBlurRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
} }
return () => { return () => {
clearTimeout(timerRef.current); if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
keepTimerOnBlurRef.current = false;
}; };
}, [isFocused]); }, [
isFocused,
videoError,
isHorizontal,
randomData,
dispatch,
isDefaultAutoPlayTarget,
spotlightId,
handleStartVideo,
]);
useEffect(() => { useEffect(() => {
if (isFocused && broadcast?.type === 'videoError') { if (isFocused && broadcast?.type === 'videoError') {

View File

@@ -1,16 +1,7 @@
import React, { import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { import { useDispatch, useSelector } from 'react-redux';
useDispatch,
useSelector,
} from 'react-redux';
import { applyMiddleware } from 'redux'; import { applyMiddleware } from 'redux';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
@@ -33,14 +24,8 @@ import {
getHomeMainContents, getHomeMainContents,
updateHomeInfo, updateHomeInfo,
} from '../../actions/homeActions'; } from '../../actions/homeActions';
import { import { sendLogGNB, sendLogTotalRecommend } from '../../actions/logActions';
sendLogGNB, import { getSubCategory, getTop20Show } from '../../actions/mainActions';
sendLogTotalRecommend,
} from '../../actions/logActions';
import {
getSubCategory,
getTop20Show,
} from '../../actions/mainActions';
import { getHomeOnSaleInfo } from '../../actions/onSaleActions'; import { getHomeOnSaleInfo } from '../../actions/onSaleActions';
import { updatePanel } from '../../actions/panelActions'; import { updatePanel } from '../../actions/panelActions';
import { import {
@@ -53,8 +38,7 @@ import TBody from '../../components/TBody/TBody';
import TButton, { TYPES } from '../../components/TButton/TButton'; import TButton, { TYPES } from '../../components/TButton/TButton';
import TPanel from '../../components/TPanel/TPanel'; import TPanel from '../../components/TPanel/TPanel';
import TPopUp from '../../components/TPopUp/TPopUp'; import TPopUp from '../../components/TPopUp/TPopUp';
import TVerticalPagenator import TVerticalPagenator from '../../components/TVerticalPagenator/TVerticalPagenator';
from '../../components/TVerticalPagenator/TVerticalPagenator';
import useDebugKey from '../../hooks/useDebugKey'; import useDebugKey from '../../hooks/useDebugKey';
import { useFocusHistory } from '../../hooks/useFocusHistory/useFocusHistory'; import { useFocusHistory } from '../../hooks/useFocusHistory/useFocusHistory';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
@@ -193,6 +177,7 @@ const HomePanel = ({ isOnTop }) => {
const focusedContainerIdRef = usePrevious(focusedContainerId); const focusedContainerIdRef = usePrevious(focusedContainerId);
const loadingComplete = useSelector((state) => state.common?.loadingComplete); const loadingComplete = useSelector((state) => state.common?.loadingComplete);
const isVideoTransitionLocked = useSelector((state) => state.home.videoTransitionLocked);
const onCancel = useCallback(() => { const onCancel = useCallback(() => {
const currentSpot = Spotlight.getCurrent(); const currentSpot = Spotlight.getCurrent();
@@ -225,7 +210,7 @@ const HomePanel = ({ isOnTop }) => {
visible: false, visible: false,
}) })
); );
}, [dispatch]); }, [dispatch, isVideoTransitionLocked]);
const onClose = useCallback(() => { const onClose = useCallback(() => {
dispatch(setHidePopup()); dispatch(setHidePopup());
@@ -482,69 +467,74 @@ const HomePanel = ({ isOnTop }) => {
}, []); }, []);
// ✅ useCallback: 의존성은 dispatch만 // ✅ useCallback: 의존성은 dispatch만
const _onScroll = useCallback((e) => { const _onScroll = useCallback(
const currentScrollTop = e.scrollTop; (e) => {
const prevScrollTop = prevScrollTopRef.current; const currentScrollTop = e.scrollTop;
const prevScrollTop = prevScrollTopRef.current;
// ✅ 최상단 도달: 1px 비디오 복구 시도 (shouldShrinkRef.current로 읽음) // ✅ 최상단 도달: 1px 비디오 복구 시도 (shouldShrinkRef.current로 읽음)
if (currentScrollTop <= 1) { if (currentScrollTop <= 1) {
if (shouldShrinkRef.current && !expandIntervalRef.current) { if (shouldShrinkRef.current && !expandIntervalRef.current) {
// console.log('[HomePanel] At top (scrollTop <= 1) - starting video expansion'); // console.log('[HomePanel] At top (scrollTop <= 1) - starting video expansion');
expandAttemptRef.current = 0; expandAttemptRef.current = 0;
// Interval 시작: 200ms마다 복구 시도 // Interval 시작: 200ms마다 복구 시도
expandIntervalRef.current = setInterval(() => { expandIntervalRef.current = setInterval(() => {
// 종료 조건: 최대 3회 시도 // 종료 조건: 최대 3회 시도
if (expandAttemptRef.current >= 3) { if (expandAttemptRef.current >= 3) {
// console.log('[HomePanel] Max expansion attempts reached (3)'); // console.log('[HomePanel] Max expansion attempts reached (3)');
clearInterval(expandIntervalRef.current); clearInterval(expandIntervalRef.current);
expandIntervalRef.current = null; expandIntervalRef.current = null;
return; return;
} }
// console.log('[HomePanel] Expansion attempt', expandAttemptRef.current + 1); // console.log('[HomePanel] Expansion attempt', expandAttemptRef.current + 1);
dispatch(expandVideoFrom1px());
expandAttemptRef.current++;
}, 200);
}
}
// 최상단 벗어남: interval 정리
else if (currentScrollTop > 1 && expandIntervalRef.current) {
// console.log('[HomePanel] Left top - clearing expand interval');
clearInterval(expandIntervalRef.current);
expandIntervalRef.current = null;
}
// 기존 로직: 아래로 스크롤
if (currentScrollTop > prevScrollTop) {
// 아래로 스크롤: 비디오를 1px로 축소
// console.log('[HomePanel] Scrolling down - shrinking video');
if (!isVideoTransitionLocked) {
dispatch(shrinkVideoTo1px());
}
// 기존 타이머 취소
if (scrollExpandTimerRef.current) {
clearTimeout(scrollExpandTimerRef.current);
scrollExpandTimerRef.current = null;
}
}
// 기존 로직: 위로 스크롤 (0이 아닌)
else if (currentScrollTop < prevScrollTop && currentScrollTop > 1) {
// 위로 스크롤 (최상단 아님): 1초 후 복구
// console.log('[HomePanel] Scrolling up - will expand after 1s');
// 기존 타이머 취소
if (scrollExpandTimerRef.current) {
clearTimeout(scrollExpandTimerRef.current);
}
// 1초 후 자동으로 크기 조정
scrollExpandTimerRef.current = setTimeout(() => {
// console.log('[HomePanel] 1s passed - auto expanding video');
dispatch(expandVideoFrom1px()); dispatch(expandVideoFrom1px());
expandAttemptRef.current++; scrollExpandTimerRef.current = null;
}, 200); }, 1000);
} }
}
// 최상단 벗어남: interval 정리
else if (currentScrollTop > 1 && expandIntervalRef.current) {
// console.log('[HomePanel] Left top - clearing expand interval');
clearInterval(expandIntervalRef.current);
expandIntervalRef.current = null;
}
// 기존 로직: 아래로 스크롤 // 이전 scrollTop 업데이트
if (currentScrollTop > prevScrollTop) { prevScrollTopRef.current = currentScrollTop;
// 아래로 스크롤: 비디오를 1px로 축소 },
// console.log('[HomePanel] Scrolling down - shrinking video'); [dispatch]
dispatch(shrinkVideoTo1px()); );
// 기존 타이머 취소
if (scrollExpandTimerRef.current) {
clearTimeout(scrollExpandTimerRef.current);
scrollExpandTimerRef.current = null;
}
}
// 기존 로직: 위로 스크롤 (0이 아닌)
else if (currentScrollTop < prevScrollTop && currentScrollTop > 1) {
// 위로 스크롤 (최상단 아님): 1초 후 복구
// console.log('[HomePanel] Scrolling up - will expand after 1s');
// 기존 타이머 취소
if (scrollExpandTimerRef.current) {
clearTimeout(scrollExpandTimerRef.current);
}
// 1초 후 자동으로 크기 조정
scrollExpandTimerRef.current = setTimeout(() => {
// console.log('[HomePanel] 1s passed - auto expanding video');
dispatch(expandVideoFrom1px());
scrollExpandTimerRef.current = null;
}, 1000);
}
// 이전 scrollTop 업데이트
prevScrollTopRef.current = currentScrollTop;
}, [dispatch]);
const _onFocusedContainerId = useCallback( const _onFocusedContainerId = useCallback(
(containerId) => { (containerId) => {
@@ -584,7 +574,16 @@ const HomePanel = ({ isOnTop }) => {
}, 0); }, 0);
} }
}, },
[panelInfo, firstSpot, enterThroughGNB, defaultFocus, cbChangePageRef, dispatch, isOnTop, panels] [
panelInfo,
firstSpot,
enterThroughGNB,
defaultFocus,
cbChangePageRef,
dispatch,
isOnTop,
panels,
]
); );
const bestSellerLoaded = useCallback(() => { const bestSellerLoaded = useCallback(() => {

View File

@@ -941,7 +941,7 @@ const MediaPanel = React.forwardRef(
// fullscreen 전환 완료 후 플래그 초기화 // fullscreen 전환 완료 후 플래그 초기화
isTransitioningToFullscreen.current = false; isTransitioningToFullscreen.current = false;
}; };
}, [panelInfo?.modal, isOnTop]); }, [isOnTop]);
useEffect(() => { useEffect(() => {
if (showNowInfos && panelInfo.shptmBanrTpNm === 'LIVE') { if (showNowInfos && panelInfo.shptmBanrTpNm === 'LIVE') {