[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:
2025-12-17 19:51:27 +09:00
parent 4ecb03002f
commit 1fae88878f
2 changed files with 117 additions and 0 deletions

View File

@@ -183,6 +183,57 @@ const ButtonStackContainer = SpotlightContainerDecorator(
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(
(productType, themeProductInfo, themeProducts, selectedIndex, productInfo) =>
pipe(
@@ -304,6 +355,9 @@ export default function ProductAllSection({
// handleScrollToImages의 timeout을 추적하기 위한 ref
const scrollToImagesTimeoutRef = useRef(null);
// 🔽 [251217] 스크롤 컨테이너 초기 위치 저장 ref (VideoPlayer modal 전환 시 위치 검증용)
const scrollPositionOnMountRef = useRef(null);
// ProductAllSection 초기 로딩 시 Skeleton 표시를 위한 상태
const [isInitialLoading, setIsInitialLoading] = useState(true);
@@ -344,6 +398,19 @@ export default function ProductAllSection({
);
}, [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(() => {
// 필수 값이 모두 있을 때만 호출
if (selectedPatnrId && selectedPrdtId) {

View File

@@ -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) => {
if (type === 'LIVE') {
switch (nowMenu) {
@@ -1107,6 +1137,26 @@ const MediaPanel = React.forwardRef(
}, [dispatch]);
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;
dispatch(switchMediaToFullscreen());
}, [dispatch]);