[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:
@@ -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) => ({
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user