[251026] feat: modal 모드에서 비디오 1px 축소/복구 기능 구현
- PlayerPanel useEffect에서 shouldShrinkTo1px 플래그로 인라인 스타일 제거 - shrinkVideoTo1px/expandVideoFrom1px 액션 추가 (배너 정보 playerState에 저장) - PlayerPanel.module.less에 .shrinkTo1px 클래스 추가 - HomePanel onScroll에서 스크롤 방향 감지하여 축소/확대 제어 - RandomUnit onBlur에서의 축소 로직은 주석 처리 (스크롤로 제어)
This commit is contained in:
@@ -240,6 +240,83 @@ export const resumeFullscreenVideo = () => (dispatch, getState) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 모달 비디오를 1px로 축소 (배너 정보 저장)
|
||||
export const shrinkVideoTo1px = () => (dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
|
||||
// modal PlayerPanel 찾기
|
||||
const modalPlayerPanel = panels.find(
|
||||
(panel) => panel.name === panel_names.PLAYER_PANEL && panel.panelInfo?.modal
|
||||
);
|
||||
|
||||
if (modalPlayerPanel) {
|
||||
const panelInfo = modalPlayerPanel.panelInfo;
|
||||
console.log('[shrinkVideoTo1px] Shrinking modal video to 1px');
|
||||
|
||||
// 축소 전 배너 정보를 playerState에 저장
|
||||
const updatedPlayerState = {
|
||||
...(panelInfo.playerState || {}),
|
||||
shrinkInfo: {
|
||||
// 복구 시 필요한 정보
|
||||
modalContainerId: panelInfo.modalContainerId,
|
||||
modalClassName: panelInfo.modalClassName,
|
||||
modalStyle: panelInfo.modalStyle,
|
||||
modalScale: panelInfo.modalScale,
|
||||
currentBannerId: panelInfo.playerState?.currentBannerId,
|
||||
patnrId: panelInfo.patnrId,
|
||||
showId: panelInfo.showId,
|
||||
shptmBanrTpNm: panelInfo.shptmBanrTpNm,
|
||||
lgCatCd: panelInfo.lgCatCd,
|
||||
},
|
||||
};
|
||||
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
...panelInfo,
|
||||
shouldShrinkTo1px: true, // 축소 플래그 설정
|
||||
playerState: updatedPlayerState,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 축소된 모달 비디오를 원래 크기로 복구
|
||||
export const expandVideoFrom1px = () => (dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
|
||||
// 축소된 modal PlayerPanel 찾기
|
||||
const shrunkModalPlayerPanel = panels.find(
|
||||
(panel) => panel.name === panel_names.PLAYER_PANEL && panel.panelInfo?.modal && panel.panelInfo?.shouldShrinkTo1px
|
||||
);
|
||||
|
||||
if (shrunkModalPlayerPanel) {
|
||||
const panelInfo = shrunkModalPlayerPanel.panelInfo;
|
||||
const shrinkInfo = panelInfo.playerState?.shrinkInfo;
|
||||
|
||||
console.log('[expandVideoFrom1px] Expanding modal video from 1px', shrinkInfo);
|
||||
|
||||
dispatch(
|
||||
updatePanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
...panelInfo,
|
||||
shouldShrinkTo1px: false, // 축소 플래그 해제
|
||||
// 저장된 정보로 복구
|
||||
...(shrinkInfo && {
|
||||
modalContainerId: shrinkInfo.modalContainerId,
|
||||
modalClassName: shrinkInfo.modalClassName,
|
||||
modalStyle: shrinkInfo.modalStyle,
|
||||
modalScale: shrinkInfo.modalScale,
|
||||
}),
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 채팅 로그 가져오기 IF-LGSP-371
|
||||
export const getChatLog =
|
||||
({ patnrId, showId }) =>
|
||||
|
||||
@@ -18,7 +18,7 @@ import { changeAppStatus } from '../../../actions/commonActions';
|
||||
import { updateHomeInfo } from '../../../actions/homeActions';
|
||||
import { sendLogTopContents, sendLogTotalRecommend } from '../../../actions/logActions';
|
||||
import { pushPanel } from '../../../actions/panelActions';
|
||||
import { finishVideoPreview, startVideoPlayer, startVideoPlayerNew } from '../../../actions/playActions';
|
||||
import { finishVideoPreview, startVideoPlayer, startVideoPlayerNew, shrinkVideoTo1px } from '../../../actions/playActions';
|
||||
import CustomImage from '../../../components/CustomImage/CustomImage';
|
||||
import usePriceInfo from '../../../hooks/usePriceInfo';
|
||||
import {
|
||||
@@ -203,17 +203,34 @@ export default function RandomUnit({
|
||||
|
||||
// 포커스 인
|
||||
const onFocus = useCallback(() => {
|
||||
console.log('[RandomUnit] onFocus called', {
|
||||
spotlightId,
|
||||
videoPlayerable,
|
||||
currentVideoBannerId,
|
||||
randomData: randomData?.showId || 'no-show-id',
|
||||
});
|
||||
|
||||
setIsFocused(true);
|
||||
|
||||
// video가 플레이 가능한 경우: 다른 배너에서 비디오 재생 중이면 종료
|
||||
if (videoPlayerable && currentVideoBannerId && currentVideoBannerId !== spotlightId) {
|
||||
console.log('[RandomUnit] videoPlayerable=true and different banner, finishing video');
|
||||
dispatch(finishVideoPreview());
|
||||
}
|
||||
|
||||
// video가 플레이 불가능한 경우: 재생 중인 비디오를 1px로 축소
|
||||
if (!videoPlayerable && currentVideoBannerId) {
|
||||
console.log('[RandomUnit] videoPlayerable=false, shrinking video to 1px', {
|
||||
videoPlayerable,
|
||||
currentVideoBannerId,
|
||||
});
|
||||
dispatch(shrinkVideoTo1px());
|
||||
}
|
||||
|
||||
if (handleItemFocus) {
|
||||
handleItemFocus();
|
||||
}
|
||||
}, [handleItemFocus, videoPlayerable, spotlightId, currentVideoBannerId]);
|
||||
}, [handleItemFocus, videoPlayerable, spotlightId, currentVideoBannerId, dispatch, randomData]);
|
||||
|
||||
const shelfFocus = useCallback(() => {
|
||||
if (handleShelfFocus) {
|
||||
@@ -225,6 +242,13 @@ export default function RandomUnit({
|
||||
const onBlur = useCallback(() => {
|
||||
setIsFocused(false);
|
||||
clearTimeout(timerRef.current);
|
||||
|
||||
// 현재 비디오가 재생 중이면 1px로 축소 (주석: HomePanel 스크롤로 처리)
|
||||
// if (currentVideoBannerId && videoPlayerable) {
|
||||
// console.log('[RandomUnit] onBlur: shrinking video to 1px');
|
||||
// dispatch(shrinkVideoTo1px());
|
||||
// }
|
||||
|
||||
// dispatch(finishVideoPreview());
|
||||
}, [isFocused]);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
import { sendLogGNB, sendLogTotalRecommend } from '../../actions/logActions';
|
||||
import { getSubCategory, getTop20Show } from '../../actions/mainActions';
|
||||
import { getHomeOnSaleInfo } from '../../actions/onSaleActions';
|
||||
import { finishVideoPreview } from '../../actions/playActions';
|
||||
import { finishVideoPreview, shrinkVideoTo1px, expandVideoFrom1px } from '../../actions/playActions';
|
||||
import { getBestSeller } from '../../actions/productActions';
|
||||
import TBody from '../../components/TBody/TBody';
|
||||
import TButton, { TYPES } from '../../components/TButton/TButton';
|
||||
@@ -152,6 +152,7 @@ const HomePanel = ({ isOnTop }) => {
|
||||
}, [sortedHomeLayoutInfo]);
|
||||
|
||||
const cbChangePageRef = useRef(null);
|
||||
const prevScrollTopRef = useRef(0); // 이전 scrollTop 추적
|
||||
|
||||
const focusedContainerIdRef = usePrevious(focusedContainerId);
|
||||
|
||||
@@ -410,9 +411,22 @@ const HomePanel = ({ isOnTop }) => {
|
||||
}, []);
|
||||
|
||||
const _onScroll = (e) => {
|
||||
if (e.scrollTop !== 0) {
|
||||
dispatch(finishVideoPreview());
|
||||
const currentScrollTop = e.scrollTop;
|
||||
const prevScrollTop = prevScrollTopRef.current;
|
||||
|
||||
// 스크롤 방향 감지
|
||||
if (currentScrollTop > prevScrollTop) {
|
||||
// 아래로 스크롤: 비디오를 1px로 축소
|
||||
console.log('[HomePanel] Scrolling down - shrinking video');
|
||||
dispatch(shrinkVideoTo1px());
|
||||
} else if (currentScrollTop < prevScrollTop && currentScrollTop > 0) {
|
||||
// 위로 스크롤 (0이 아닌): 비디오를 원래 크기로 복구
|
||||
console.log('[HomePanel] Scrolling up - expanding video');
|
||||
dispatch(expandVideoFrom1px());
|
||||
}
|
||||
|
||||
// 이전 scrollTop 업데이트
|
||||
prevScrollTopRef.current = currentScrollTop;
|
||||
};
|
||||
|
||||
const _onFocusedContainerId = useCallback(
|
||||
|
||||
@@ -1426,6 +1426,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
useEffect(() => {
|
||||
if (
|
||||
panelInfo.modal &&
|
||||
!panelInfo.shouldShrinkTo1px &&
|
||||
panelInfo.modalContainerId &&
|
||||
(lastPanelAction === 'previewPush' || lastPanelAction === 'previewUpdate')
|
||||
) {
|
||||
@@ -1457,6 +1458,10 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
setModalScale(panelInfo.modalScale);
|
||||
console.error('PlayerPanel modalContainerId node not found', panelInfo.modalContainerId);
|
||||
}
|
||||
} else if (panelInfo.shouldShrinkTo1px) {
|
||||
// 축소 상태: 인라인 스타일 제거 (CSS만 적용)
|
||||
setModalStyle({});
|
||||
setModalScale(1);
|
||||
} else if (isOnTop && !panelInfo.modal && videoPlayer.current) {
|
||||
if (videoPlayer.current?.getMediaState()?.paused) {
|
||||
videoPlayer.current.play();
|
||||
@@ -2166,6 +2171,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
className={classNames(
|
||||
css.videoContainer,
|
||||
panelInfo.modal && css.modal,
|
||||
panelInfo.shouldShrinkTo1px && css.shrinkTo1px,
|
||||
// PlayerPanel이 최상단 아니고, 최상단이 DetailPanel(from Player)이면 비디오 보이도록
|
||||
!isOnTop && isTopPanelDetailFromPlayer && css['background-visible'],
|
||||
// PlayerPanel이 최상단 아니고, 위 조건 아니면 1px로 숨김
|
||||
|
||||
@@ -55,6 +55,23 @@
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
&.shrinkTo1px {
|
||||
/* 모달 비디오를 1px로 축소 */
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
left: -1px;
|
||||
top: -1px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
background-color: @videoBackgroundColor;
|
||||
overflow: visible;
|
||||
.tabContainer,
|
||||
.arrow,
|
||||
.toOpenBtn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.modal,
|
||||
&.modal-minimized,
|
||||
&.background {
|
||||
|
||||
Reference in New Issue
Block a user