[251111] fix: MediaPlayer 전체화면 toggle 구현중

🕐 커밋 시간: 2025. 11. 11. 15:06:28

📊 변경 통계:
  • 총 파일: 2개
  • 추가: +149줄
  • 삭제: -45줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/reducers/videoOverlayReducer.js
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductContentSection/ProductVideo/ProductVideo.v2.jsx

🔧 주요 변경 내용:
  • 핵심 비즈니스 로직 개선
  • 중간 규모 기능 개선
This commit is contained in:
2025-11-11 15:06:30 +09:00
parent 22550bdb39
commit bca5e4afde
2 changed files with 149 additions and 45 deletions

View File

@@ -95,7 +95,7 @@ const handlers = {
[VIDEO_OVERLAY_ACTIONS.TOGGLE_CONTROLS]: (state, action) => {
const isCurrentlyVisible = state.controls.visible;
return {
const newState = {
...state,
controls: {
...state.controls,
@@ -110,6 +110,13 @@ const handlers = {
timestamp: action.payload.timestamp,
lastAction: VIDEO_OVERLAY_ACTIONS.TOGGLE_CONTROLS,
};
console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 상태 변화');
console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이전 visible:', isCurrentlyVisible);
console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 이후 visible:', newState.controls.visible);
console.log('🔄 [videoOverlayReducer.TOGGLE_CONTROLS] 전체 상태:', newState);
return newState;
},
[VIDEO_OVERLAY_ACTIONS.START_AUTO_CLOSE]: (state, action) => ({

View File

@@ -13,6 +13,7 @@ import {
switchToFullscreen,
showControls,
hideControls,
toggleControls,
startAutoClose,
stopAutoClose,
resetAutoClose,
@@ -271,39 +272,130 @@ export function ProductVideoV2({
[isPlaying, isFullscreen, toggleFullscreen]
);
// 비디오 재생 중 클릭 핸들러 - 전체화면 토글
// 비디오 재생 중 클릭 핸들러
// const handleVideoPlayerClick = useCallback(
// (e) => {
// console.log('🎬 [ProductVideoV2] handleVideoPlayerClick 실행됨', {
// isPlaying,
// isFullscreen,
// eventType: e.type,
// target: e.target?.className,
// currentTarget: e.currentTarget?.className,
// bubbles: e.bubbles,
// cancelable: e.cancelable,
// composed: e.composed,
// });
// if (!isPlaying) {
// return; // 비디오 재생 중이 아닐 때는 무시
// }
// if (isFullscreen) {
// // 전체 화면 모드: 오버레이 토글
// console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] 전체 화면 모드 - 오버레이 토글 시작');
// console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] 현재 오버레이 상태:', overlayState.controls?.visible);
// try {
// const result = dispatch(toggleControls());
// console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] toggleControls 액션 디스패치 결과:', result);
// } catch (error) {
// console.error('🖥️ [ProductVideoV2.OVERLAY-ERROR] toggleControls 디스패치 에러:', error);
// }
// // 이벤트 전파 중단
// e.preventDefault?.();
// e.stopPropagation?.();
// } else {
// // 일반 모드: 전체 화면으로 전환
// console.log('🎬 [ProductVideoV2] ✅ Click detected - toggling fullscreen');
// // 이벤트 전파 중단 (capture phase에서도 중단)
// e.preventDefault?.();
// e.stopPropagation?.();
// toggleFullscreen();
// }
// },
// [isPlaying, isFullscreen, toggleFullscreen, overlayState.controls?.visible, dispatch, toggleControls]
// );
const handleVideoPlayerClick = useCallback(
(e) => {
console.log('🎬 [ProductVideoV2] handleVideoPlayerClick 실행됨', {
isPlaying,
isFullscreen,
eventType: e.type,
target: e.target?.className,
currentTarget: e.currentTarget?.className,
bubbles: e.bubbles,
cancelable: e.cancelable,
composed: e.composed,
});
if (!isPlaying) return;
// 비디오 재생 중이고 전체화면이 아닐 때만 작동
if (!isPlaying || isFullscreen) {
console.log('🎬 [ProductVideoV2] 조건 불만족 - 반환됨', {
isPlaying,
isFullscreen,
});
if (!isFullscreen) {
e.preventDefault?.();
e.stopPropagation?.();
toggleFullscreen();
return;
}
// 이벤트 전파 중단 (capture phase에서도 중단)
// fullscreen: overlay toggle
e.preventDefault?.();
e.stopPropagation?.();
console.log('🎬 [ProductVideoV2] ✅ Click detected - toggling fullscreen');
toggleFullscreen();
// Redux overlayState 사용
const isCurrentlyVisible = overlayState.controls?.visible;
if (isCurrentlyVisible) {
dispatch(hideControls());
videoPlayerRef.current.hideControls?.();
} else {
dispatch(showControls());
videoPlayerRef.current.showControls?.();
videoPlayerRef.current.startAutoCloseTimeout?.();
}
},
[isPlaying, isFullscreen, toggleFullscreen]
[isPlaying, isFullscreen, toggleFullscreen, dispatch, overlayState.controls?.visible]
);
// 오버레이 토글 통합 함수 (ESC와 동일한 효과)
const toggleOverlayVisibility = useCallback(() => {
console.log('🖥️ [toggleOverlayVisibility] 오버레이 토글 시작');
console.log('🖥️ [toggleOverlayVisibility] 현재 오버레이 상태:', overlayState.controls?.visible);
const isOverlayVisible = overlayState.controls?.visible;
if (isOverlayVisible) {
console.log('🖥️ [toggleOverlayVisibility] 오버레이 숨기기 (ESC와 동일)');
dispatch(hideControls());
videoPlayerRef.current?.hideControls?.();
} else {
console.log('🖥️ [toggleOverlayVisibility] 오버레이 보이기');
dispatch(showControls());
videoPlayerRef.current?.showControls?.();
videoPlayerRef.current?.startAutoCloseTimeout?.();
}
}, [overlayState.controls?.visible, dispatch]);
// 전체 화면 컨테이너용 마우스 다운 핸들러 (Capture Phase)
const handleFullscreenContainerMouseDownCapture = useCallback((e) => {
if (!isPlaying || !isFullscreen) return;
console.log('🖥️ [Fullscreen Container] 마우스 클릭 - 토글 실행');
e.preventDefault();
e.stopPropagation();
toggleOverlayVisibility();
}, [isPlaying, isFullscreen, toggleOverlayVisibility]);
// 전체 화면 키보드 핸들러
const handleFullscreenKeyDown = useCallback((e) => {
if (!isPlaying || !isFullscreen) return;
if (e.key === 'Enter' || e.keyCode === 13) {
console.log('🖥️ [Fullscreen Container] Enter 키 - 토글 실행');
e.preventDefault();
e.stopPropagation();
toggleOverlayVisibility();
}
if (e.key === 'Escape' || e.keyCode === 27) {
console.log('🖥️ [Fullscreen Container] ESC 키 - 토글 실행');
e.preventDefault();
e.stopPropagation();
toggleOverlayVisibility();
}
}, [isPlaying, isFullscreen, toggleOverlayVisibility]);
// 마우스 다운 (클릭) 이벤트 - capture phase에서 처리
const handleVideoPlayerMouseDown = useCallback(
(e) => {
@@ -319,22 +411,6 @@ export function ProductVideoV2({
[isPlaying, isFullscreen]
);
// 전체화면 모드용 키보드 이벤트 핸들러 (window 레벨)
const handleFullscreenKeyDown = useCallback(
(e) => {
// 전체화면 모드에서만 작동
if (!isPlaying || !isFullscreen) return;
// 엔터키(13) 또는 OK 버튼
if (e.keyCode === 13 || e.key === 'Enter') {
e.preventDefault();
e.stopPropagation();
toggleFullscreen();
}
},
[isPlaying, isFullscreen, toggleFullscreen]
);
// 전체화면 모드일 때만 window 레벨 이벤트 리스너 등록
useEffect(() => {
if (isPlaying && isFullscreen) {
@@ -506,15 +582,34 @@ export function ProductVideoV2({
isFullscreen,
});
toggleFullscreen();
// 전체 화면 모드가 아닐 때만 toggleFullscreen 호출
if (!isFullscreen) {
toggleFullscreen();
// TScrollerDetail의 onClick 실행을 막기 위해 preventDefault 호출
if (isPlaying && !isFullscreen) {
console.log('🔓 [ProductVideoV2] TScrollerDetail onClick 실행 차단');
e.preventDefault();
e.stopPropagation();
// TScrollerDetail의 onClick 실행을 막기 위해 preventDefault 호출
if (isPlaying) {
console.log('🔓 [ProductVideoV2] TScrollerDetail onClick 실행 차단');
e.preventDefault();
e.stopPropagation();
}
} else {
// 전체 화면 모드에서는 오버레이(컨트롤)만 토글
console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] 전체 화면 모드 - 오버레이 토글 시작');
console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] 현재 오버레이 상태:', overlayState.controls?.visible);
try {
const result = dispatch(toggleControls());
console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] toggleControls 액션 디스패치 결과:', result);
// 디스패치 후 상태 변화 확인 (setTimeout으로 비동기 처리)
setTimeout(() => {
console.log('🖥️ [ProductVideoV2.OVERLAY-Toggle] 액션 디스패치 후 상태 확인 필요');
}, 10);
} catch (error) {
console.error('🖥️ [ProductVideoV2.OVERLAY-ERROR] toggleControls 디스패치 에러:', error);
}
}
}, [isPlaying, isFullscreen]);
}, [isPlaying, isFullscreen, dispatch, toggleControls]);
// Early return: 비디오 재생 불가능한 경우
if (!canPlayVideo) return null;
@@ -701,6 +796,8 @@ export function ProductVideoV2({
<SpotlightContainer
spotlightRestrict="self-only"
spotlightId="product-video-v2-fullscreen-portal"
onMouseDownCapture={handleFullscreenContainerMouseDownCapture}
onKeyDown={handleFullscreenKeyDown}
>
<div
ref={fullscreenContainerRef}