[251217] fix: MediaPanel.v3.jsx 비디오복원 방어로직 추가
🕐 커밋 시간: 2025. 12. 17. 19:51:27 📊 변경 통계: • 총 파일: 2개 • 추가: +117줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx 🔧 주요 변경 내용: • 중간 규모 기능 개선
This commit is contained in:
@@ -183,6 +183,57 @@ const ButtonStackContainer = SpotlightContainerDecorator(
|
|||||||
|
|
||||||
const SpottableComponent = Spottable('div');
|
const SpottableComponent = Spottable('div');
|
||||||
|
|
||||||
|
// 🔽 [251217] ProductAllSection 스크롤 컨테이너 위치 저장/검증 함수
|
||||||
|
// PlayerPanel의 배너 위치 검증 패턴을 ProductAllSection에 적용
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductAllSection의 스크롤 컨테이너 위치 수집 함수
|
||||||
|
* @returns {Object|null} 스크롤 컨테이너의 위치 정보 (top, left) 또는 null
|
||||||
|
*/
|
||||||
|
const collectProductScrollPosition = () => {
|
||||||
|
const scrollContainer = document.querySelector('[data-spotlight-id="main-content-scroller"]');
|
||||||
|
|
||||||
|
if (scrollContainer) {
|
||||||
|
const { top, left } = scrollContainer.getBoundingClientRect();
|
||||||
|
const position = {
|
||||||
|
top: Math.round(top),
|
||||||
|
left: Math.round(left)
|
||||||
|
};
|
||||||
|
console.log('[ProductAllSection] 스크롤 컨테이너 위치 수집:', position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn('[ProductAllSection] 스크롤 컨테이너를 찾을 수 없음');
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductAllSection 스크롤 컨테이너 위치 검증 함수
|
||||||
|
* @param {Object} savedPosition - 저장된 초기 위치
|
||||||
|
* @param {Object} currentPosition - 현재 위치
|
||||||
|
* @returns {boolean} 위치가 일치하는지 여부
|
||||||
|
*/
|
||||||
|
const isProductScrollPositionValid = (savedPosition, currentPosition) => {
|
||||||
|
if (!savedPosition || !currentPosition) {
|
||||||
|
console.warn('[ProductAllSection] 저장된 위치 또는 현재 위치가 없음');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tolerance = 1; // 1px 오차 범위
|
||||||
|
const isMatching =
|
||||||
|
Math.abs(currentPosition.top - savedPosition.top) <= tolerance &&
|
||||||
|
Math.abs(currentPosition.left - savedPosition.left) <= tolerance;
|
||||||
|
|
||||||
|
console.log('[ProductAllSection] 스크롤 위치 검증:', {
|
||||||
|
expected: savedPosition,
|
||||||
|
current: currentPosition,
|
||||||
|
matching: isMatching,
|
||||||
|
tolerance
|
||||||
|
});
|
||||||
|
|
||||||
|
return isMatching;
|
||||||
|
};
|
||||||
|
|
||||||
const getProductData = curry(
|
const getProductData = curry(
|
||||||
(productType, themeProductInfo, themeProducts, selectedIndex, productInfo) =>
|
(productType, themeProductInfo, themeProducts, selectedIndex, productInfo) =>
|
||||||
pipe(
|
pipe(
|
||||||
@@ -304,6 +355,9 @@ export default function ProductAllSection({
|
|||||||
// handleScrollToImages의 timeout을 추적하기 위한 ref
|
// handleScrollToImages의 timeout을 추적하기 위한 ref
|
||||||
const scrollToImagesTimeoutRef = useRef(null);
|
const scrollToImagesTimeoutRef = useRef(null);
|
||||||
|
|
||||||
|
// 🔽 [251217] 스크롤 컨테이너 초기 위치 저장 ref (VideoPlayer modal 전환 시 위치 검증용)
|
||||||
|
const scrollPositionOnMountRef = useRef(null);
|
||||||
|
|
||||||
// ProductAllSection 초기 로딩 시 Skeleton 표시를 위한 상태
|
// ProductAllSection 초기 로딩 시 Skeleton 표시를 위한 상태
|
||||||
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
||||||
|
|
||||||
@@ -344,6 +398,19 @@ export default function ProductAllSection({
|
|||||||
);
|
);
|
||||||
}, [selectedPatnrId, selectedPrdtId, userNumber, dispatch]);
|
}, [selectedPatnrId, selectedPrdtId, userNumber, dispatch]);
|
||||||
|
|
||||||
|
// 🔽 [251217] ProductAllSection 마운트 시 스크롤 컨테이너 위치 저장
|
||||||
|
useEffect(() => {
|
||||||
|
// 초기 렌더링 후 스크롤 컨테이너의 위치를 저장 (1회만 실행)
|
||||||
|
// 이 위치는 나중에 VideoPlayer의 modal 전환 시 유효성 검증에 사용됨
|
||||||
|
const savedPosition = collectProductScrollPosition();
|
||||||
|
if (savedPosition) {
|
||||||
|
scrollPositionOnMountRef.current = savedPosition;
|
||||||
|
// 🔽 window 객체에도 저장하여 MediaPanel.v3.jsx에서 접근 가능하게 함
|
||||||
|
window.productScrollPositionOnMount = savedPosition;
|
||||||
|
console.log('[ProductAllSection] ✅ 초기 스크롤 위치 저장 완료:', savedPosition);
|
||||||
|
}
|
||||||
|
}, []); // 마운트 시 1회만 실행
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 필수 값이 모두 있을 때만 호출
|
// 필수 값이 모두 있을 때만 호출
|
||||||
if (selectedPatnrId && selectedPrdtId) {
|
if (selectedPatnrId && selectedPrdtId) {
|
||||||
|
|||||||
@@ -93,6 +93,36 @@ const findSelector = (selector, maxAttempts = 5, currentAttempts = 0) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 🔽 [251217] ProductAllSection 스크롤 컨테이너 위치 수집 함수
|
||||||
|
const collectProductScrollPosition = () => {
|
||||||
|
const scrollContainer = document.querySelector('[data-spotlight-id="main-content-scroller"]');
|
||||||
|
|
||||||
|
if (scrollContainer) {
|
||||||
|
const { top, left } = scrollContainer.getBoundingClientRect();
|
||||||
|
const position = {
|
||||||
|
top: Math.round(top),
|
||||||
|
left: Math.round(left)
|
||||||
|
};
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🔽 [251217] ProductAllSection 스크롤 컨테이너 위치 검증 함수
|
||||||
|
const isProductScrollPositionValid = (savedPosition, currentPosition) => {
|
||||||
|
if (!savedPosition || !currentPosition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tolerance = 1; // 1px 오차 범위
|
||||||
|
const isMatching =
|
||||||
|
Math.abs(currentPosition.top - savedPosition.top) <= tolerance &&
|
||||||
|
Math.abs(currentPosition.left - savedPosition.left) <= tolerance;
|
||||||
|
|
||||||
|
return isMatching;
|
||||||
|
};
|
||||||
|
|
||||||
const getLogTpNo = (type, nowMenu) => {
|
const getLogTpNo = (type, nowMenu) => {
|
||||||
if (type === 'LIVE') {
|
if (type === 'LIVE') {
|
||||||
switch (nowMenu) {
|
switch (nowMenu) {
|
||||||
@@ -1107,6 +1137,26 @@ const MediaPanel = React.forwardRef(
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const enterFullscreen = useCallback(() => {
|
const enterFullscreen = useCallback(() => {
|
||||||
|
// 🔽 [251217] ProductAllSection 스크롤 위치 검증
|
||||||
|
// DetailPanel에서 ProductAllSection의 초기 위치와 현재 위치를 비교하여 검증
|
||||||
|
const savedPosition = window.productScrollPositionOnMount;
|
||||||
|
const currentPosition = collectProductScrollPosition();
|
||||||
|
|
||||||
|
if (savedPosition && currentPosition) {
|
||||||
|
const isValid = isProductScrollPositionValid(savedPosition, currentPosition);
|
||||||
|
if (!isValid) {
|
||||||
|
console.warn('[MediaPanel] ⚠️ ProductAllSection 스크롤 위치 검증 실패 - 전체화면 재생 가능하지만 경고 표시', {
|
||||||
|
savedPosition,
|
||||||
|
currentPosition,
|
||||||
|
});
|
||||||
|
// 사용자 피드백: 위치가 일치하지 않음을 콘솔에 기록 (비디오는 계속 재생)
|
||||||
|
} else {
|
||||||
|
console.log('[MediaPanel] ✅ ProductAllSection 스크롤 위치 검증 성공');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('[MediaPanel] ⚠️ ProductAllSection 위치 정보 없음 - 검증 스킵');
|
||||||
|
}
|
||||||
|
|
||||||
isTransitioningToFullscreen.current = true;
|
isTransitioningToFullscreen.current = true;
|
||||||
dispatch(switchMediaToFullscreen());
|
dispatch(switchMediaToFullscreen());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|||||||
Reference in New Issue
Block a user