live > vod(핑크퐁) 클릭시 vod channel 리스트 추가 및 자동재생
This commit is contained in:
@@ -178,7 +178,17 @@ const PlayerPanel = ({
|
||||
|
||||
const videoPlayer = useRef(null);
|
||||
const [playListInfo, setPlayListInfo] = USE_STATE("playListInfo", "");
|
||||
const playListInfoRef = useRef([]);
|
||||
const sortedFilteredListRef = useRef(null); // 정렬된 필터링 리스트 저장
|
||||
const currentPlayingShowIdRef = useRef(null);
|
||||
const [shopNowInfo, setShopNowInfo] = USE_STATE("shopNowInfo");
|
||||
const [isFilteredByPatnr19, setIsFilteredByPatnr19] = USE_STATE(
|
||||
"isFilteredByPatnr19",
|
||||
false
|
||||
);
|
||||
const isFilteredByPatnr19Ref = useRef(false);
|
||||
const [clickedShowId, setClickedShowId] = USE_STATE("clickedShowId", null);
|
||||
const hasSetInitialIndex = useRef(false);
|
||||
const [backupInitialIndex, setBackupInitialIndex] = USE_STATE(
|
||||
"backupInitialIndex",
|
||||
0
|
||||
@@ -863,6 +873,7 @@ const PlayerPanel = ({
|
||||
const onClickBack = useCallback(
|
||||
(ev, isEnd) => {
|
||||
//modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감.
|
||||
console.log("###onClickBack", backupInitialIndex, isEnd);
|
||||
if (
|
||||
sideContentsVisible &&
|
||||
!videoVerticalVisible &&
|
||||
@@ -966,7 +977,7 @@ const PlayerPanel = ({
|
||||
// 아이템클릭 진입시 포커스
|
||||
let hasProperSpot = false;
|
||||
let targetId;
|
||||
if (!isInitialFocusOccurred || panelInfo.targetId) {
|
||||
if (!isInitialFocusOccurred) {
|
||||
targetId = panelInfo.targetId;
|
||||
|
||||
initialFocusTimeoutJob.current.start(() => {
|
||||
@@ -988,11 +999,6 @@ const PlayerPanel = ({
|
||||
if (retryTarget) {
|
||||
Spotlight.focus(retryTarget);
|
||||
setIsInitialFocusOccurred(true);
|
||||
} else {
|
||||
if (shopNowInfo?.length > 0) {
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
setIsInitialFocusOccurred(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1003,7 +1009,6 @@ const PlayerPanel = ({
|
||||
panelInfo.targetId,
|
||||
panelInfo.modal,
|
||||
videoVerticalVisible,
|
||||
shopNowInfo,
|
||||
]);
|
||||
|
||||
const videoInitialFocused = useCallback(() => {
|
||||
@@ -1028,15 +1033,15 @@ const PlayerPanel = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) {
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!panelInfo.modal && !videoVerticalVisible && !hasProperSpot) {
|
||||
Spotlight.focus(SpotlightIds.PLAYER_TAB_BUTTON);
|
||||
return;
|
||||
}
|
||||
//비디오 진입시 포커스
|
||||
if (panelInfo.isIndicatorByClick && shopNowInfo?.length > 0) {
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
return;
|
||||
}
|
||||
}, [
|
||||
shopNowInfo,
|
||||
videoVerticalVisible,
|
||||
@@ -1107,6 +1112,49 @@ const PlayerPanel = ({
|
||||
panelInfo?.shptmBanrTpNm,
|
||||
]);
|
||||
|
||||
// 라이브 채널 클릭 시 필터링 상태 설정
|
||||
useEffect(() => {
|
||||
if (panelInfo.shptmBanrTpNm === "LIVE" && panelInfo.isUpdatedByClick) {
|
||||
if (panelInfo.patnrId === "19") {
|
||||
// 이미 필터링 상태가 아닐 때만 리셋 (최초 진입)
|
||||
const wasNotFiltered = !isFilteredByPatnr19Ref.current;
|
||||
|
||||
setIsFilteredByPatnr19(true);
|
||||
isFilteredByPatnr19Ref.current = true;
|
||||
|
||||
if (wasNotFiltered && panelInfo.showId) {
|
||||
// 최초 필터링 진입 시에만 리셋
|
||||
setClickedShowId(panelInfo.showId);
|
||||
hasSetInitialIndex.current = false;
|
||||
sortedFilteredListRef.current = null;
|
||||
}
|
||||
} else {
|
||||
setIsFilteredByPatnr19(false);
|
||||
isFilteredByPatnr19Ref.current = false;
|
||||
setClickedShowId(null);
|
||||
hasSetInitialIndex.current = false;
|
||||
sortedFilteredListRef.current = null;
|
||||
}
|
||||
}
|
||||
}, [panelInfo]);
|
||||
|
||||
// selectedIndex가 변경될 때마다 현재 재생 중인 showId 업데이트
|
||||
useEffect(() => {
|
||||
if (
|
||||
isFilteredByPatnr19 &&
|
||||
playListInfo &&
|
||||
playListInfo.length > 0 &&
|
||||
selectedIndex !== null &&
|
||||
selectedIndex >= 0 &&
|
||||
selectedIndex < playListInfo.length
|
||||
) {
|
||||
const currentShowId = playListInfo[selectedIndex]?.showId;
|
||||
if (currentShowId) {
|
||||
currentPlayingShowIdRef.current = currentShowId;
|
||||
}
|
||||
}
|
||||
}, [selectedIndex, playListInfo, isFilteredByPatnr19]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
panelInfo.shptmBanrTpNm === "VOD" &&
|
||||
@@ -1134,6 +1182,7 @@ const PlayerPanel = ({
|
||||
setShopNowInfo(showDetailInfo[0].productInfos);
|
||||
saveToLocalSettings(showDetailInfo[0].showId, showDetailInfo[0].patnrId);
|
||||
}
|
||||
// console.log("###showDetailInfo", showDetailInfo);
|
||||
}, [showDetailInfo]);
|
||||
|
||||
//LIVE
|
||||
@@ -1187,17 +1236,13 @@ const PlayerPanel = ({
|
||||
videoInitialFocused();
|
||||
}
|
||||
}
|
||||
}, [playListInfo, panelInfo.targetId]);
|
||||
}, [playListInfo]);
|
||||
|
||||
//10초 후 닫힐때 TabButton 포커스
|
||||
useEffect(() => {
|
||||
if (playListInfo && playListInfo.length > 0) {
|
||||
if (panelInfo.targetId) {
|
||||
videoItemFocused();
|
||||
} else {
|
||||
videoInitialFocused();
|
||||
}
|
||||
}
|
||||
}, [sideContentsVisible, panelInfo.modal]);
|
||||
|
||||
// liveChannel initial selectedIndex
|
||||
@@ -1290,21 +1335,8 @@ const PlayerPanel = ({
|
||||
|
||||
playlist.forEach((item) => {
|
||||
if (item.showType === "vod" && Array.isArray(item.vodInfos)) {
|
||||
// vodInfos를 정렬 (showId 기준)
|
||||
const sortedVodInfos = [...item.vodInfos].sort((a, b) => {
|
||||
// showId가 있으면 showId로 정렬
|
||||
if (a.showId && b.showId) {
|
||||
return a.showId.localeCompare(b.showId);
|
||||
}
|
||||
// strtDt가 있으면 시작일로 정렬
|
||||
if (a.strtDt && b.strtDt) {
|
||||
return new Date(a.strtDt) - new Date(b.strtDt);
|
||||
}
|
||||
// 정렬 기준이 없으면 원래 순서 유지
|
||||
return 0;
|
||||
});
|
||||
|
||||
const mergedVodInfos = sortedVodInfos.map((vod) => ({
|
||||
// 정렬 없이 vodInfos를 그대로 사용
|
||||
const mergedVodInfos = item.vodInfos.map((vod) => ({
|
||||
...vod,
|
||||
patnrId: item.patnrId,
|
||||
patncNm: item.patncNm,
|
||||
@@ -1318,7 +1350,65 @@ const PlayerPanel = ({
|
||||
}
|
||||
});
|
||||
|
||||
setPlayListInfo(modifiedList);
|
||||
// 필터링 상태에 따라 리스트 결정
|
||||
let finalList = modifiedList;
|
||||
|
||||
if (isFilteredByPatnr19) {
|
||||
// 이미 정렬된 리스트가 있으면 그것을 사용
|
||||
if (sortedFilteredListRef.current) {
|
||||
finalList = sortedFilteredListRef.current;
|
||||
|
||||
// 클릭 시 현재 재생 중인 아이템의 인덱스 찾기
|
||||
if (panelInfo.isUpdatedByClick && panelInfo.showId) {
|
||||
const newIndex = finalList.findIndex(
|
||||
(item) => item.showId === panelInfo.showId
|
||||
);
|
||||
if (newIndex >= 0) {
|
||||
setSelectedIndex(newIndex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 없으면 새로 필터링하고 정렬
|
||||
const filtered = modifiedList.filter(
|
||||
(item) => item.patnrId === "19"
|
||||
);
|
||||
if (filtered.length > 0) {
|
||||
// 클릭한 아이템을 맨 앞으로 배치
|
||||
if (clickedShowId) {
|
||||
const clickedIndex = filtered.findIndex(
|
||||
(item) => item.showId === clickedShowId
|
||||
);
|
||||
|
||||
if (clickedIndex > 0) {
|
||||
// 클릭한 아이템이 있고 첫 번째가 아니면, 맨 앞으로 이동
|
||||
const clickedItem = filtered[clickedIndex];
|
||||
finalList = [
|
||||
clickedItem,
|
||||
...filtered.slice(0, clickedIndex),
|
||||
...filtered.slice(clickedIndex + 1),
|
||||
];
|
||||
} else {
|
||||
// 이미 첫 번째거나 찾지 못한 경우 그대로 사용
|
||||
finalList = filtered;
|
||||
}
|
||||
} else {
|
||||
finalList = filtered;
|
||||
}
|
||||
|
||||
// 정렬된 리스트 저장
|
||||
sortedFilteredListRef.current = finalList;
|
||||
|
||||
// 초기 인덱스 설정
|
||||
if (!hasSetInitialIndex.current) {
|
||||
setSelectedIndex(0); // 클릭한 아이템이 맨 앞이므로 항상 0
|
||||
hasSetInitialIndex.current = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setPlayListInfo(finalList);
|
||||
playListInfoRef.current = finalList;
|
||||
|
||||
if (showNowInfos?.prdtChgYn === "N") {
|
||||
return;
|
||||
@@ -1346,6 +1436,8 @@ const PlayerPanel = ({
|
||||
liveShowInfos,
|
||||
showNowInfos,
|
||||
dispatch,
|
||||
isFilteredByPatnr19,
|
||||
clickedShowId,
|
||||
]);
|
||||
|
||||
const liveTotalTime = useMemo(() => {
|
||||
@@ -1826,7 +1918,6 @@ const PlayerPanel = ({
|
||||
},
|
||||
})
|
||||
);
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
}
|
||||
}
|
||||
if (!sideContentsVisible) {
|
||||
@@ -1839,7 +1930,6 @@ const PlayerPanel = ({
|
||||
selectedIndex,
|
||||
sideContentsVisible,
|
||||
initialEnter,
|
||||
panelInfo,
|
||||
]);
|
||||
|
||||
const handleIndicatorUpClick = useCallback(() => {
|
||||
@@ -1881,7 +1971,6 @@ const PlayerPanel = ({
|
||||
},
|
||||
})
|
||||
);
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
}
|
||||
}
|
||||
if (!sideContentsVisible) {
|
||||
@@ -1894,7 +1983,6 @@ const PlayerPanel = ({
|
||||
selectedIndex,
|
||||
sideContentsVisible,
|
||||
initialEnter,
|
||||
panelInfo,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -1983,30 +2071,38 @@ const PlayerPanel = ({
|
||||
return;
|
||||
}
|
||||
|
||||
// LIVE 타입이면서 patnrId가 19일 때 자동재생 처리
|
||||
// LIVE 타입이면서 필터링된 상태(patnrId 19)일 때 자동재생 처리
|
||||
if (
|
||||
panelInfoRef.current.shptmBanrTpNm === "LIVE" &&
|
||||
panelInfoRef.current.patnrId === "19"
|
||||
isFilteredByPatnr19Ref.current
|
||||
) {
|
||||
const currentIndex = selectedIndex;
|
||||
const currentPlayList = playListInfoRef.current;
|
||||
|
||||
// 현재 재생 중인 비디오의 showId를 기준으로 인덱스 찾기
|
||||
const currentShowId = currentPlayingShowIdRef.current;
|
||||
const currentIndex = currentPlayList.findIndex(
|
||||
(item) => item.showId === currentShowId
|
||||
);
|
||||
const nextIndex = currentIndex + 1;
|
||||
|
||||
if (
|
||||
playListInfo &&
|
||||
nextIndex < playListInfo.length &&
|
||||
playListInfo[nextIndex]?.showId
|
||||
currentPlayList &&
|
||||
currentIndex >= 0 &&
|
||||
nextIndex < currentPlayList.length &&
|
||||
currentPlayList[nextIndex]?.showId
|
||||
) {
|
||||
// 다음 비디오가 있으면 자동으로 다음 비디오 재생
|
||||
// selectedIndex 변경 시 currentPlayingShowIdRef가 자동 업데이트됨
|
||||
setSelectedIndex(nextIndex);
|
||||
|
||||
// LIVE 비디오의 경우 startVideoPlayer 호출
|
||||
dispatch(
|
||||
startVideoPlayer({
|
||||
chanId: playListInfo[nextIndex]?.chanId,
|
||||
chanId: currentPlayList[nextIndex]?.chanId,
|
||||
modal: panelInfoRef.current.modal || false,
|
||||
patnrId: playListInfo[nextIndex]?.patnrId,
|
||||
showId: playListInfo[nextIndex]?.showId,
|
||||
showUrl: playListInfo[nextIndex]?.showUrl,
|
||||
patnrId: currentPlayList[nextIndex]?.patnrId,
|
||||
showId: currentPlayList[nextIndex]?.showId,
|
||||
showUrl: currentPlayList[nextIndex]?.showUrl,
|
||||
shptmBanrTpNm: "LIVE",
|
||||
})
|
||||
);
|
||||
@@ -2023,7 +2119,7 @@ const PlayerPanel = ({
|
||||
return;
|
||||
}
|
||||
},
|
||||
[selectedIndex, playListInfo, dispatch]
|
||||
[selectedIndex, dispatch]
|
||||
);
|
||||
|
||||
const onKeyDown = (ev) => {
|
||||
@@ -2375,6 +2471,7 @@ const PlayerPanel = ({
|
||||
handleItemFocus={handleItemFocus}
|
||||
prevChannelIndex={prevChannelIndex}
|
||||
currentTime={currentTime}
|
||||
isFilteredByPatnr19={isFilteredByPatnr19}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -33,13 +33,16 @@ export default function TabContainer({
|
||||
prevChannelIndex,
|
||||
currentTime,
|
||||
spotlightId,
|
||||
isFilteredByPatnr19,
|
||||
}) {
|
||||
const [tab, setTab] = useState(0);
|
||||
|
||||
const tabList = [
|
||||
$L("SHOP NOW"),
|
||||
panelInfo?.shptmBanrTpNm === "LIVE"
|
||||
? $L("LIVE CHANNEL")
|
||||
? isFilteredByPatnr19
|
||||
? $L("VOD CHANNEL")
|
||||
: $L("LIVE CHANNEL")
|
||||
: $L("FEATURED SHOWS"),
|
||||
];
|
||||
|
||||
@@ -172,6 +175,7 @@ export default function TabContainer({
|
||||
handleItemFocus={_handleItemFocus}
|
||||
panelInfo={panelInfo}
|
||||
currentTime={currentTime}
|
||||
isFilteredByPatnr19={isFilteredByPatnr19}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@ import Spotlight from "@enact/spotlight";
|
||||
|
||||
import { updatePanel } from "../../../../actions/panelActions";
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import { LOG_CONTEXT_NAME, LOG_MENU, LOG_MESSAGE_ID, panel_names } from "../../../../utils/Config";
|
||||
import {
|
||||
LOG_CONTEXT_NAME,
|
||||
LOG_MENU,
|
||||
LOG_MESSAGE_ID,
|
||||
panel_names,
|
||||
} from "../../../../utils/Config";
|
||||
import { $L } from "../../../../utils/helperMethods";
|
||||
import PlayerItemCard, { TYPES } from "../../PlayerItemCard/PlayerItemCard";
|
||||
import ListEmptyContents from "../TabContents/ListEmptyContents/ListEmptyContents";
|
||||
@@ -22,10 +27,12 @@ export default function LiveChannelContents({
|
||||
tabIndex,
|
||||
handleItemFocus,
|
||||
tabTitle,
|
||||
panelInfo
|
||||
panelInfo,
|
||||
isFilteredByPatnr19,
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
const isClickBlocked = useRef(false);
|
||||
const scrollToRef = useRef(null);
|
||||
const handleFocus = useCallback(
|
||||
() => () => {
|
||||
if (handleItemFocus) {
|
||||
@@ -35,6 +42,18 @@ export default function LiveChannelContents({
|
||||
[handleItemFocus]
|
||||
);
|
||||
|
||||
// cbScrollTo 콜백으로 scrollTo 함수 받기
|
||||
const handleScrollTo = useCallback((scrollToFn) => {
|
||||
scrollToRef.current = scrollToFn;
|
||||
}, []);
|
||||
|
||||
// VOD Channel로 전환될 때 스크롤을 최상단으로 이동
|
||||
useEffect(() => {
|
||||
if (isFilteredByPatnr19 && scrollToRef.current) {
|
||||
scrollToRef.current({ index: 0, animate: false, focus: false });
|
||||
}
|
||||
}, [isFilteredByPatnr19]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const {
|
||||
@@ -63,8 +82,8 @@ export default function LiveChannelContents({
|
||||
category: catNm,
|
||||
partner: patncNm,
|
||||
contextName: LOG_CONTEXT_NAME.SHOW,
|
||||
messageId: LOG_MESSAGE_ID.CONTENTCLICK
|
||||
}
|
||||
messageId: LOG_MESSAGE_ID.CONTENTCLICK,
|
||||
};
|
||||
dispatch(sendLogTotalRecommend(params));
|
||||
//중복클릭방지
|
||||
if (isClickBlocked.current) {
|
||||
@@ -122,6 +141,7 @@ export default function LiveChannelContents({
|
||||
startDt={strtDt}
|
||||
endDt={endDt}
|
||||
currentTime={currentTime}
|
||||
currentVideoVisible={currentVideoShowId === liveInfos[index].showId}
|
||||
/>
|
||||
);
|
||||
},
|
||||
@@ -140,6 +160,7 @@ export default function LiveChannelContents({
|
||||
<div className={css.container}>
|
||||
{liveInfos && liveInfos.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
cbScrollTo={handleScrollTo}
|
||||
dataSize={liveInfos.length}
|
||||
direction="vertical"
|
||||
renderItem={renderItem}
|
||||
|
||||
Reference in New Issue
Block a user