From c9d943bffbb1daac0f2916abb05da5bb12495412 Mon Sep 17 00:00:00 2001 From: optrader Date: Sun, 19 Oct 2025 13:15:36 +0900 Subject: [PATCH] =?UTF-8?q?[251019]=20feat:=20ProductVideoV2=EC=97=90=20Re?= =?UTF-8?q?dux=20=EC=98=A4=EB=B2=84=EB=A0=88=EC=9D=B4=20=EC=A0=9C=EC=96=B4?= =?UTF-8?q?=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ProductVideoV2 컴포넌트에서 비디오 재생/종료/Back 버튼 시 Redux 오버레이 제어를 활용하여 자동 숨김 타이머 관리 Changes: - 비디오 재생 시: showControls + startAutoClose(3000) - 비디오 종료 시: stopAutoClose + hideControls - Back 버튼 시: stopAutoClose + hideControls + switchToModal - 컴포넌트 언마운트 시: Redux 상태 정리 이제 modal=true 상태에서도 3초 후 자동으로 controls가 숨겨지는 기능 구현됨 --- .../ProductVideo/ProductVideo.v2.jsx | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx index 2e2c44d4..bb126122 100644 --- a/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx +++ b/com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx @@ -1,5 +1,6 @@ import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; import ReactDOM from 'react-dom'; +import { useDispatch, useSelector } from 'react-redux'; import Spottable from '@enact/spotlight/Spottable'; import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator'; import CustomImage from '../../../../components/CustomImage/CustomImage'; @@ -7,6 +8,14 @@ import { VideoPlayer } from '../../../../components/VideoPlayer/MediaPlayer'; import Media from '../../../../components/VideoPlayer/Media'; import TReactPlayer from '../../../../components/VideoPlayer/TReactPlayer'; import playImg from '../../../../../assets/images/btn/btn-play-thumb-nor.png'; +import { + switchToModal, + switchToFullscreen, + showControls, + hideControls, + startAutoClose, + stopAutoClose, +} from '../../../../actions/videoOverlayActions'; import css from './ProductVideo.module.less'; const SpottableComponent = Spottable('div'); @@ -45,6 +54,11 @@ export default function ProductVideoV2({ autoPlay = false, onScrollToImages, }) { + // Redux 상태 및 dispatch + const dispatch = useDispatch(); + const overlayState = useSelector((state) => state.videoOverlay); + + // Local state const [isPlaying, setIsPlaying] = useState(false); const [focused, setFocused] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false); @@ -125,18 +139,24 @@ export default function ProductVideoV2({ } }, [canPlayVideo, isPlaying]); - // 썸네일 클릭 핸들러 - 비디오 재생 시작 + // 썸네일 클릭 핸들러 - 비디오 재생 시작 + Redux dispatch const handleThumbnailClick = useCallback(() => { if (canPlayVideo && !isPlaying) { setIsPlaying(true); + // Redux: 오버레이 상태 초기화 및 autoClose 시작 + dispatch(showControls()); + dispatch(startAutoClose(3000)); } - }, [canPlayVideo, isPlaying]); + }, [canPlayVideo, isPlaying, dispatch]); - // 비디오 종료 핸들러 - 썸네일로 복귀 + // 비디오 종료 핸들러 - 썸네일로 복귀 + Redux cleanup const handleVideoEnded = useCallback(() => { setIsPlaying(false); setIsFullscreen(false); // 전체화면도 해제 - }, []); + // Redux: 오버레이 상태 정리 + dispatch(stopAutoClose()); + dispatch(hideControls()); + }, [dispatch]); // Spotlight Down 키 핸들러 - 비디오 다음 이미지로 스크롤 const handleSpotlightDown = useCallback( @@ -152,16 +172,19 @@ export default function ProductVideoV2({ [canPlayVideo, onScrollToImages] ); - // Back 버튼 핸들러 - 전체화면 해제 또는 비디오 종료 + // Back 버튼 핸들러 - 전체화면 해제 또는 비디오 종료 + Redux cleanup const handleBackButton = useCallback(() => { if (isFullscreen) { // 전체화면이면 일반 모드로 setIsFullscreen(false); + dispatch(switchToModal()); } else if (isPlaying) { // 일반 모드에서 재생 중이면 썸네일로 setIsPlaying(false); + dispatch(stopAutoClose()); + dispatch(hideControls()); } - }, [isFullscreen, isPlaying]); + }, [isFullscreen, isPlaying, dispatch]); // 더미 함수들 (VideoPlayer가 요구하는 props) const setIsVODPaused = useCallback(() => {}, []); @@ -272,6 +295,15 @@ export default function ProductVideoV2({ } }, [isFullscreen, isPlaying]); + // 컴포넌트 언마운트 시 Redux 상태 정리 + useEffect(() => { + return () => { + console.log('[ProductVideoV2] Component unmounting - cleaning up Redux state'); + dispatch(stopAutoClose()); + dispatch(hideControls()); + }; + }, [dispatch]); + if (!canPlayVideo) return null; // 컨테이너 컴포넌트 결정