[251217] fix: LiveChannelContents Navigation
🕐 커밋 시간: 2025. 12. 17. 14:17:24 📊 변경 통계: • 총 파일: 1개 • 추가: +100줄 • 삭제: -9줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx 🔧 주요 변경 내용: • 소규모 기능 개선
This commit is contained in:
@@ -1248,12 +1248,12 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
return () => {
|
||||
// 패널이 2개 존재할때만 popPanel 진행
|
||||
// 현재 스택의 top이 PlayerPanel일 때만 pop 수행 (다른 패널이 올라온 상태에서 오작동 방지)
|
||||
console.log('[PP-TRACE] cleanup start', {
|
||||
modal: panelInfo.modal,
|
||||
isOnTop,
|
||||
topPanel: panels[panels.length - 1]?.name,
|
||||
stack: panels.map((p) => p.name),
|
||||
});
|
||||
// console.log('[PP-TRACE] cleanup start', {
|
||||
// modal: panelInfo.modal,
|
||||
// isOnTop,
|
||||
// topPanel: panels[panels.length - 1]?.name,
|
||||
// stack: panels.map((p) => p.name),
|
||||
// });
|
||||
|
||||
// 🔽 [251221] PlayerPanel unmount 시 DeepLink 플래그 리셋
|
||||
dispatch(
|
||||
@@ -1272,7 +1272,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
topPanelName === panel_names.PLAYER_PANEL &&
|
||||
panels.length === 1 // 다른 패널 존재 시 pop 금지 (DetailPanel 제거 방지)
|
||||
) {
|
||||
console.log('[PP-TRACE] popPanel - useEffect cleanup (top is PlayerPanel)');
|
||||
// console.log('[PP-TRACE] popPanel - useEffect cleanup (top is PlayerPanel)');
|
||||
dispatch(PanelActions.popPanel());
|
||||
} else {
|
||||
Spotlight.focus('tbody');
|
||||
@@ -2536,14 +2536,105 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
);
|
||||
|
||||
const onKeyDown = (ev) => {
|
||||
if (ev.keyCode === 34) {
|
||||
// tabIndex === 1 (LiveChannelContents 표시)이고 비디오 배너에 포커스가 있는 경우
|
||||
const currentFocused = Spotlight.getCurrent();
|
||||
const spotlightId = currentFocused?.getAttribute('data-spotlight-id');
|
||||
const isVideoItemFocused = spotlightId?.startsWith('tabChannel-video');
|
||||
|
||||
// LiveChannelContents의 비디오 배너에 포커스가 있는 경우: PageUp/PageDown을 좌우 이동으로 변환
|
||||
if (tabIndexV2 === 1 && isVideoItemFocused) {
|
||||
// DOM에서 실제로 렌더링된 모든 비디오 배너 찾기 (가상화 대응)
|
||||
const allVideoBanners = Array.from(
|
||||
document.querySelectorAll('[data-spotlight-id^="tabChannel-video-"]')
|
||||
);
|
||||
|
||||
if (allVideoBanners.length > 0) {
|
||||
// 현재 포커스된 배너의 인덱스 찾기
|
||||
const currentBannerIndex = allVideoBanners.findIndex(
|
||||
(el) => el === currentFocused
|
||||
);
|
||||
|
||||
if (currentBannerIndex !== -1) {
|
||||
if (ev.keyCode === 34) { // PageDown -> 오른쪽 배너로 포커스 이동
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
// DOM에 렌더링된 다음 배너로 이동 (마지막이면 무시 또는 첫 번째로)
|
||||
if (currentBannerIndex < allVideoBanners.length - 1) {
|
||||
// 다음 배너가 DOM에 있으면 이동
|
||||
const nextBanner = allVideoBanners[currentBannerIndex + 1];
|
||||
const nextSpotlightId = nextBanner.getAttribute('data-spotlight-id');
|
||||
|
||||
dlog('[PlayerPanel] 🎯 PageDown (비디오 배너) -> 오른쪽으로 이동', {
|
||||
current: spotlightId,
|
||||
next: nextSpotlightId,
|
||||
currentBannerIndex,
|
||||
totalVisibleBanners: allVideoBanners.length,
|
||||
});
|
||||
|
||||
Spotlight.focus(nextSpotlightId);
|
||||
} else {
|
||||
// 마지막 배너면 첫 번째로 이동 시도 (DOM에 있으면)
|
||||
const firstBanner = allVideoBanners[0];
|
||||
const firstSpotlightId = firstBanner.getAttribute('data-spotlight-id');
|
||||
|
||||
dlog('[PlayerPanel] 🎯 PageDown (마지막 배너) -> 첫 번째 배너로 이동 시도', {
|
||||
current: spotlightId,
|
||||
next: firstSpotlightId,
|
||||
isWrapAround: true,
|
||||
});
|
||||
|
||||
Spotlight.focus(firstSpotlightId);
|
||||
}
|
||||
return;
|
||||
} else if (ev.keyCode === 33) { // PageUp -> 왼쪽 배너로 포커스 이동
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
// DOM에 렌더링된 이전 배너로 이동 (첫 번째면 무시 또는 마지막으로)
|
||||
if (currentBannerIndex > 0) {
|
||||
// 이전 배너가 DOM에 있으면 이동
|
||||
const prevBanner = allVideoBanners[currentBannerIndex - 1];
|
||||
const prevSpotlightId = prevBanner.getAttribute('data-spotlight-id');
|
||||
|
||||
dlog('[PlayerPanel] 🎯 PageUp (비디오 배너) -> 왼쪽으로 이동', {
|
||||
current: spotlightId,
|
||||
prev: prevSpotlightId,
|
||||
currentBannerIndex,
|
||||
totalVisibleBanners: allVideoBanners.length,
|
||||
});
|
||||
|
||||
Spotlight.focus(prevSpotlightId);
|
||||
} else {
|
||||
// 첫 번째 배너면 마지막으로 이동 시도 (DOM에 있으면)
|
||||
const lastBanner = allVideoBanners[allVideoBanners.length - 1];
|
||||
const lastSpotlightId = lastBanner.getAttribute('data-spotlight-id');
|
||||
|
||||
dlog('[PlayerPanel] 🎯 PageUp (첫 번째 배너) -> 마지막 배너로 이동 시도', {
|
||||
current: spotlightId,
|
||||
prev: lastSpotlightId,
|
||||
isWrapAround: true,
|
||||
});
|
||||
|
||||
Spotlight.focus(lastSpotlightId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 기존 로직: LiveChannelButton 또는 다른 경우에는 상/하 이동
|
||||
if (ev.keyCode === 34) { // PageDown
|
||||
handleIndicatorDownClick();
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
} else if (ev.keyCode === 33) {
|
||||
dlog('[PlayerPanel] 📺 PageDown (버튼 또는 다른 경우) -> 다음 비디오');
|
||||
} else if (ev.keyCode === 33) { // PageUp
|
||||
handleIndicatorUpClick();
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
dlog('[PlayerPanel] 📺 PageUp (버튼 또는 다른 경우) -> 이전 비디오');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user