Compare commits
3 Commits
backup-202
...
backup-202
| Author | SHA1 | Date | |
|---|---|---|---|
| 07a042cca6 | |||
|
|
d93960f40a | ||
| 4dfa15b4c0 |
@@ -34,7 +34,7 @@
|
|||||||
padding: @slider-padding-v 0;
|
padding: @slider-padding-v 0;
|
||||||
height: @sand-mediaplayer-slider-height;
|
height: @sand-mediaplayer-slider-height;
|
||||||
right: 154px;
|
right: 154px;
|
||||||
width: 1466px;
|
width: 1558px;
|
||||||
// Add a tap area that extends to the edges of the screen, to make the slider more accessible
|
// Add a tap area that extends to the edges of the screen, to make the slider more accessible
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
font-family: @baseFont;
|
font-family: @baseFont;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
right: 90px;
|
right: 20px;
|
||||||
bottom: -5px;
|
bottom: -5px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -16,12 +16,12 @@
|
|||||||
letter-spacing: -1px;
|
letter-spacing: -1px;
|
||||||
.separator {
|
.separator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 105px;
|
right: 95px;
|
||||||
bottom: -5px;
|
bottom: -5px;
|
||||||
}
|
}
|
||||||
.currentTime {
|
.currentTime {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 130px;
|
right: 120px;
|
||||||
bottom: -5px;
|
bottom: -5px;
|
||||||
}
|
}
|
||||||
.totalTime {
|
.totalTime {
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ export default function ProductDescription({ productInfo }) {
|
|||||||
|
|
||||||
const _onClose = useCallback(()=>{
|
const _onClose = useCallback(()=>{
|
||||||
dispatch(setHidePopup());
|
dispatch(setHidePopup());
|
||||||
|
// Restore focus to the description content after popup closes
|
||||||
|
setTimeout(() => {
|
||||||
|
Spotlight.focus('product-description-content');
|
||||||
|
}, 100);
|
||||||
},[dispatch])
|
},[dispatch])
|
||||||
|
|
||||||
// ProductDescription: Container 직접 사용 패턴
|
// ProductDescription: Container 직접 사용 패턴
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ function PlayerOverlayContents({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// tabIndexV2가 2일 때만 LiveChannelNext로 포커스
|
// tabIndexV2가 2일 때만 LiveChannelNext로 포커스
|
||||||
if (tabContainerVersion === 2 && tabIndexV2 === 2) {
|
if (tabContainerVersion === 2 && tabIndexV2 === 2) {
|
||||||
Spotlight.focus('live-channel-next-button');
|
Spotlight.focus('below-tab-shop-now-button');
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onSpotlightDown={(e) => {
|
onSpotlightDown={(e) => {
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
background-image: url("../../../../assets/images/btn/btn-video-cc-nor@3x.png");
|
background-image: url("../../../../assets/images/btn/btn-video-cc-nor@3x.png");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 60px;
|
right: 300px;
|
||||||
top: 800px;
|
top: 680px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
&.videoVericalSubtitleButton {
|
&.videoVericalSubtitleButton {
|
||||||
|
|||||||
@@ -91,6 +91,51 @@ const findSelector = (selector, maxAttempts = 5, currentAttempts = 0) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 배너 위치 수집 함수 (top, left만 저장)
|
||||||
|
const collectBannerPositions = () => {
|
||||||
|
const positions = [];
|
||||||
|
|
||||||
|
// banner0, banner1 등의 배너 위치 수집
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
const bannerId = `banner${i}`;
|
||||||
|
const node = document.querySelector(`[data-spotlight-id="${bannerId}"]`);
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
const { top, left } = node.getBoundingClientRect();
|
||||||
|
positions.push({
|
||||||
|
bannerId,
|
||||||
|
position: { top: Math.round(top), left: Math.round(left) }
|
||||||
|
});
|
||||||
|
dlog(`[PlayerPanel] 배너 위치 수집: ${bannerId}`, { top: Math.round(top), left: Math.round(left) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return positions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 위치 검증 함수 (오차 범위: 1px)
|
||||||
|
const isPositionMatching = (bannerPositions, bannerId, currentPosition) => {
|
||||||
|
const validPosition = bannerPositions.find(p => p.bannerId === bannerId);
|
||||||
|
|
||||||
|
if (!validPosition) {
|
||||||
|
dlog(`[PlayerPanel] 배너 위치 검증 실패: ${bannerId} 배너를 찾을 수 없음`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tolerance = 1; // 1px 오차 범위
|
||||||
|
const isMatching =
|
||||||
|
Math.abs(currentPosition.top - validPosition.position.top) <= tolerance &&
|
||||||
|
Math.abs(currentPosition.left - validPosition.position.left) <= tolerance;
|
||||||
|
|
||||||
|
dlog(`[PlayerPanel] 배너 위치 검증: ${bannerId}`, {
|
||||||
|
expected: validPosition.position,
|
||||||
|
current: currentPosition,
|
||||||
|
matching: isMatching
|
||||||
|
});
|
||||||
|
|
||||||
|
return isMatching;
|
||||||
|
};
|
||||||
|
|
||||||
const getLogTpNo = (type, nowMenu) => {
|
const getLogTpNo = (type, nowMenu) => {
|
||||||
if (type === 'LIVE') {
|
if (type === 'LIVE') {
|
||||||
switch (nowMenu) {
|
switch (nowMenu) {
|
||||||
@@ -219,6 +264,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
|||||||
const [tabIndexV2, setTabIndexV2] = USE_STATE('tabIndexV2', 1); // 0: ShopNow, 1: LiveChannel, 2: ShopNowButton
|
const [tabIndexV2, setTabIndexV2] = USE_STATE('tabIndexV2', 1); // 0: ShopNow, 1: LiveChannel, 2: ShopNowButton
|
||||||
const [tabContainerVersion, setTabContainerVersion] = USE_STATE('tabContainerVersion', 2); // 1: TabContainer (우측), 2: TabContainerV2 (하단)
|
const [tabContainerVersion, setTabContainerVersion] = USE_STATE('tabContainerVersion', 2); // 1: TabContainer (우측), 2: TabContainerV2 (하단)
|
||||||
const [isModalClosed, setIsModalClosed] = USE_STATE('isModalClosed', true); // 모달이 false 상태인지 나타내는 플래그
|
const [isModalClosed, setIsModalClosed] = USE_STATE('isModalClosed', true); // 모달이 false 상태인지 나타내는 플래그
|
||||||
|
const [validBannerPositions, setValidBannerPositions] = USE_STATE('validBannerPositions', []); // 유효한 배너 위치 (top, left)
|
||||||
|
|
||||||
const panels = USE_SELECTOR('panels', (state) => state.panels.panels);
|
const panels = USE_SELECTOR('panels', (state) => state.panels.panels);
|
||||||
const chatData = USE_SELECTOR('chatData', (state) => state.play.chatData);
|
const chatData = USE_SELECTOR('chatData', (state) => state.play.chatData);
|
||||||
@@ -1937,6 +1983,30 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
|||||||
panelInfo: { modalStyle: modalStyle, modalScale: scale },
|
panelInfo: { modalStyle: modalStyle, modalScale: scale },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 🔽 배너 위치 수집 (초기 로드 시에만 실행)
|
||||||
|
if (validBannerPositions.length === 0) {
|
||||||
|
const positions = collectBannerPositions();
|
||||||
|
if (positions.length > 0) {
|
||||||
|
setValidBannerPositions(positions);
|
||||||
|
dlog('[PlayerPanel] ✅ 배너 위치 초기 수집 완료:', positions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 배너 위치 검증 (위치가 맞지 않으면 비디오 재생 중단)
|
||||||
|
if (validBannerPositions.length > 0) {
|
||||||
|
const currentPosition = { top: Math.round(top), left: Math.round(left) };
|
||||||
|
const isValidPosition = isPositionMatching(validBannerPositions, panelInfo.modalContainerId, currentPosition);
|
||||||
|
|
||||||
|
if (!isValidPosition) {
|
||||||
|
dlog('[PlayerPanel] ⚠️ 배너 위치 검증 실패 - 비디오 재생 중단', {
|
||||||
|
bannerId: panelInfo.modalContainerId,
|
||||||
|
currentPosition,
|
||||||
|
validBannerPositions
|
||||||
|
});
|
||||||
|
return; // 비디오 재생 중단
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dlog('[PlayerPanel] Condition 1: Node not found, using saved modalStyle');
|
dlog('[PlayerPanel] Condition 1: Node not found, using saved modalStyle');
|
||||||
setModalStyle(panelInfo.modalStyle);
|
setModalStyle(panelInfo.modalStyle);
|
||||||
|
|||||||
@@ -21,8 +21,16 @@ export default function ShopNowButton({ onClick }) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// tabIndexV2가 2일 때만 CC 버튼으로 내려가기
|
// tabIndexV2가 2일 때만 CC 버튼으로 내려가기
|
||||||
Spotlight.focus('player-subtitlebutton');
|
Spotlight.focus('live-channel-next-button');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSpotlightLeft = (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
// tabIndexV2가 2일 때만 CC 버튼으로 내려가기
|
||||||
|
Spotlight.focus('player-subtitlebutton');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
<SpottableDiv
|
<SpottableDiv
|
||||||
@@ -31,6 +39,7 @@ export default function ShopNowButton({ onClick }) {
|
|||||||
spotlightId="below-tab-shop-now-button"
|
spotlightId="below-tab-shop-now-button"
|
||||||
onSpotlightUp={handleSpotlightUp}
|
onSpotlightUp={handleSpotlightUp}
|
||||||
onSpotlightDown={handleSpotlightDown}
|
onSpotlightDown={handleSpotlightDown}
|
||||||
|
onSpotlightLeft={handleSpotlightLeft}
|
||||||
>
|
>
|
||||||
<span className={css.buttonText}>SHOP NOW</span>
|
<span className={css.buttonText}>SHOP NOW</span>
|
||||||
</SpottableDiv>
|
</SpottableDiv>
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ export default function TabContainerV2({
|
|||||||
// tabIndex = 2 (ShopNowButton)
|
// tabIndex = 2 (ShopNowButton)
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
Spotlight.focus('below-tab-shop-now-button');
|
Spotlight.focus('below-tab-shop-now-button');
|
||||||
}, 100);
|
}, 10);
|
||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
Reference in New Issue
Block a user