[251026] feat: HomeBaner Video-1
🕐 커밋 시간: 2025. 10. 26. 20:17:22 📊 변경 통계: • 총 파일: 3개 • 추가: +139줄 • 삭제: -70줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/playActions.js ~ com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx ~ com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 중간 규모 기능 개선 • 코드 정리 및 최적화
This commit is contained in:
@@ -59,6 +59,56 @@ export const startVideoPlayer =
|
||||
}
|
||||
};
|
||||
|
||||
export const startVideoPlayerNew =
|
||||
({ modal, modalContainerId, modalClassName, spotlightDisable, useNewPlayer, bannerId, ...rest }) =>
|
||||
(dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
const topPanel = panels[panels.length - 1];
|
||||
let panelWorkingAction = pushPanel;
|
||||
|
||||
// const panelName = useNewPlayer ? panel_names.PLAYER_PANEL_NEW : panel_names.PLAYER_PANEL;
|
||||
const panelName = panel_names.PLAYER_PANEL;
|
||||
|
||||
if (topPanel && topPanel.name === panelName) {
|
||||
panelWorkingAction = updatePanel;
|
||||
}
|
||||
|
||||
// playerState 업데이트: 기존 playerState와 새 데이터 병합
|
||||
const currentPlayerState = topPanel?.panelInfo?.playerState || {};
|
||||
|
||||
// 같은 배너에서 이미 비디오가 재생 중이면 return (중복 재생 방지)
|
||||
if (currentPlayerState.currentBannerId === bannerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newPlayerState = {
|
||||
...currentPlayerState,
|
||||
currentBannerId: bannerId,
|
||||
};
|
||||
|
||||
dispatch(
|
||||
panelWorkingAction(
|
||||
{
|
||||
name: panelName,
|
||||
panelInfo: {
|
||||
modal,
|
||||
modalContainerId,
|
||||
modalClassName,
|
||||
playerState: newPlayerState,
|
||||
...rest,
|
||||
},
|
||||
},
|
||||
true
|
||||
)
|
||||
);
|
||||
if (modal && modalContainerId && !spotlightDisable) {
|
||||
Spotlight.setPointerMode(false);
|
||||
startVideoFocusTimer = setTimeout(() => {
|
||||
Spotlight.focus(modalContainerId);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
export const finishVideoPreview = () => (dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
const topPanel = panels[panels.length - 1];
|
||||
|
||||
@@ -59,7 +59,7 @@ import css from './HomeBanner.module.less';
|
||||
import PersistentVideoUnit from './PersistentVideoUnit';
|
||||
import JustForSwitchBanner from './RandomBannerType/JustForYouBanner';
|
||||
import Random from './RandomUnit';
|
||||
import RandomUnitNew from './RandomUnit';
|
||||
// import RandomUnitNew from './RandomUnit';
|
||||
import Rolling from './RollingUnit';
|
||||
import SimpleVideoContainer from './SimpleVideoContainer';
|
||||
|
||||
@@ -407,8 +407,18 @@ export default function HomeBanner({
|
||||
]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
(index, isHorizontal, videoPlayerable = false) => {
|
||||
(index, isHorizontal) => {
|
||||
const data = bannerDataList?.[index] ?? {};
|
||||
|
||||
// videoPlayable을 동적으로 계산
|
||||
// Random이나 Rolling 배너에서 LIVE 또는 VOD 타입의 비디오가 있는지 확인
|
||||
const videoPlayerable =
|
||||
(data.shptmDspyTpNm === "Random" || data.shptmDspyTpNm === "Rolling") &&
|
||||
data.bannerDetailInfos?.some(item =>
|
||||
item.shptmBanrTpNm === "LIVE" ||
|
||||
item.shptmBanrTpNm === "VOD"
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={!isHorizontal ? css.imgBox : undefined}>
|
||||
{data.shptmDspyTpNm === "Rolling" ? (
|
||||
@@ -456,56 +466,56 @@ export default function HomeBanner({
|
||||
);
|
||||
|
||||
// 1번째 배너(포커스 재생) 및 기타 배너를 위한 렌더링 함수
|
||||
const renderItemNew = useCallback(
|
||||
(index, isHorizontal) => {
|
||||
const data = bannerDataList?.[index] ?? {};
|
||||
// const renderItemNew = useCallback(
|
||||
// (index, isHorizontal) => {
|
||||
// const data = bannerDataList?.[index] ?? {};
|
||||
|
||||
// DSP00201 레이아웃의 두 번째 배너는 새로운 RandomUnitNew를 사용
|
||||
if (selectTemplate === "DSP00201" && index === 1) {
|
||||
return (
|
||||
<div className={!isHorizontal ? css.imgBox : undefined}>
|
||||
<RandomUnitNew
|
||||
bannerData={data}
|
||||
isHorizontal={isHorizontal}
|
||||
key={"banner" + index}
|
||||
spotlightId={"banner" + index}
|
||||
handleShelfFocus={_handleShelfFocus}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
randomNumber={data.randomIndex}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// // DSP00201 레이아웃의 두 번째 배너는 새로운 RandomUnitNew를 사용
|
||||
// if (selectTemplate === "DSP00201" && index === 1) {
|
||||
// return (
|
||||
// <div className={!isHorizontal ? css.imgBox : undefined}>
|
||||
// <RandomUnitNew
|
||||
// bannerData={data}
|
||||
// isHorizontal={isHorizontal}
|
||||
// key={"banner" + index}
|
||||
// spotlightId={"banner" + index}
|
||||
// handleShelfFocus={_handleShelfFocus}
|
||||
// handleItemFocus={_handleItemFocus}
|
||||
// randomNumber={data.randomIndex}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
// 다른 타입의 유닛 렌더링 (예: RollingUnit)
|
||||
if (data.shptmDspyTpNm === "Rolling") {
|
||||
return (
|
||||
<div className={!isHorizontal ? css.imgBox : undefined}>
|
||||
<RollingUnit
|
||||
bannerData={data}
|
||||
isHorizontal={isHorizontal}
|
||||
key={"banner" + index}
|
||||
spotlightId={"banner" + index}
|
||||
handleShelfFocus={_handleShelfFocus}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// 기본 이미지만 있는 배너 등 다른 케이스 처리
|
||||
return (
|
||||
<div
|
||||
className={!isHorizontal ? css.imgBox : undefined}
|
||||
key={"banner" + index}
|
||||
>
|
||||
<SpottableComponent spotlightId={"banner" + index}>
|
||||
{/* ... 정적 이미지 렌더링 로직 ... */}
|
||||
</SpottableComponent>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
[_handleItemFocus, _handleShelfFocus, bannerDataList, selectTemplate]
|
||||
);
|
||||
// // 다른 타입의 유닛 렌더링 (예: RollingUnit)
|
||||
// if (data.shptmDspyTpNm === "Rolling") {
|
||||
// return (
|
||||
// <div className={!isHorizontal ? css.imgBox : undefined}>
|
||||
// <RollingUnit
|
||||
// bannerData={data}
|
||||
// isHorizontal={isHorizontal}
|
||||
// key={"banner" + index}
|
||||
// spotlightId={"banner" + index}
|
||||
// handleShelfFocus={_handleShelfFocus}
|
||||
// handleItemFocus={_handleItemFocus}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
// // 기본 이미지만 있는 배너 등 다른 케이스 처리
|
||||
// return (
|
||||
// <div
|
||||
// className={!isHorizontal ? css.imgBox : undefined}
|
||||
// key={"banner" + index}
|
||||
// >
|
||||
// <SpottableComponent spotlightId={"banner" + index}>
|
||||
// {/* ... 정적 이미지 렌더링 로직 ... */}
|
||||
// </SpottableComponent>
|
||||
// </div>
|
||||
// );
|
||||
// },
|
||||
// [_handleItemFocus, _handleShelfFocus, bannerDataList, selectTemplate]
|
||||
// );
|
||||
|
||||
// 0번째 배너(영구 재생)를 위한 렌더링 함수
|
||||
const renderItemPersistentVideo = useCallback(
|
||||
@@ -544,34 +554,34 @@ export default function HomeBanner({
|
||||
return (
|
||||
<>
|
||||
<ContainerBasic className={css.smallBox}>
|
||||
{renderItem(0, true, true)}
|
||||
{renderItem(1, true, true)}
|
||||
{renderItem(0, true)}
|
||||
{renderItem(1, true)}
|
||||
</ContainerBasic>
|
||||
{renderItem(2, false, false)}
|
||||
{renderItem(3, false, false)}
|
||||
{renderItem(2, false)}
|
||||
{renderItem(3, false)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
case "DSP00202": {
|
||||
return (
|
||||
<>
|
||||
{renderItem(0, false, false)}
|
||||
{renderItem(0, false)}
|
||||
<ContainerBasic className={css.smallBox}>
|
||||
{renderItem(1, true, true)}
|
||||
{renderItem(2, true, true)}
|
||||
{renderItem(1, true)}
|
||||
{renderItem(2, true)}
|
||||
</ContainerBasic>
|
||||
{renderItem(3, false, false)}
|
||||
{renderItem(3, false)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
case "DSP00203": {
|
||||
return (
|
||||
<>
|
||||
{renderItem(0, false, false)}
|
||||
{renderItem(1, false, false)}
|
||||
{renderItem(0, false)}
|
||||
{renderItem(1, false)}
|
||||
<ContainerBasic className={css.smallBox}>
|
||||
{renderItem(2, true, true)}
|
||||
{renderItem(3, true, true)}
|
||||
{renderItem(2, true)}
|
||||
{renderItem(3, true)}
|
||||
</ContainerBasic>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ import { changeAppStatus } from '../../../actions/commonActions';
|
||||
import { updateHomeInfo } from '../../../actions/homeActions';
|
||||
import { sendLogTopContents, sendLogTotalRecommend } from '../../../actions/logActions';
|
||||
import { pushPanel } from '../../../actions/panelActions';
|
||||
import { finishVideoPreview, startVideoPlayer } from '../../../actions/playActions';
|
||||
import { finishVideoPreview, startVideoPlayer, startVideoPlayerNew } from '../../../actions/playActions';
|
||||
import CustomImage from '../../../components/CustomImage/CustomImage';
|
||||
import usePriceInfo from '../../../hooks/usePriceInfo';
|
||||
import {
|
||||
@@ -57,6 +57,13 @@ export default function RandomUnit({
|
||||
const homeCategory = useSelector((state) => state.home.menuData?.data?.homeCategory);
|
||||
const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd);
|
||||
|
||||
// 현재 재생 중인 비디오 배너 ID 가져오기
|
||||
const currentVideoBannerId = useSelector((state) => {
|
||||
const panels = state.panels?.panels || [];
|
||||
const playerPanel = panels.find((p) => p.name === panel_names.PLAYER_PANEL);
|
||||
return playerPanel?.panelInfo?.playerState?.currentBannerId;
|
||||
});
|
||||
|
||||
// 정상적으로 로딩되면 빈객체로 넘어가고 , 에러가 나면 객체안에 타입이 담겨옵니다.
|
||||
const broadcast = useSelector((state) => state.common.broadcast);
|
||||
const { curationId, curationTitle } = useSelector((state) => state.home);
|
||||
@@ -198,15 +205,15 @@ export default function RandomUnit({
|
||||
const onFocus = useCallback(() => {
|
||||
setIsFocused(true);
|
||||
|
||||
// video가 플레이 가능한 경우 기존 비디오 즉시 종료료
|
||||
if (videoPlayerable) {
|
||||
// video가 플레이 가능한 경우: 다른 배너에서 비디오 재생 중이면 종료
|
||||
if (videoPlayerable && currentVideoBannerId && currentVideoBannerId !== spotlightId) {
|
||||
dispatch(finishVideoPreview());
|
||||
}
|
||||
|
||||
if (handleItemFocus) {
|
||||
handleItemFocus();
|
||||
}
|
||||
}, [handleItemFocus]);
|
||||
}, [handleItemFocus, videoPlayerable, spotlightId, currentVideoBannerId]);
|
||||
|
||||
const shelfFocus = useCallback(() => {
|
||||
if (handleShelfFocus) {
|
||||
@@ -417,7 +424,8 @@ export default function RandomUnit({
|
||||
}
|
||||
|
||||
dispatch(
|
||||
startVideoPlayer({
|
||||
startVideoPlayerNew({
|
||||
bannerId: spotlightId,
|
||||
showUrl: randomData.showUrl,
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
@@ -491,7 +499,8 @@ export default function RandomUnit({
|
||||
timerRef.current = setTimeout(
|
||||
() =>
|
||||
dispatch(
|
||||
startVideoPlayer({
|
||||
startVideoPlayerNew({
|
||||
bannerId: spotlightId,
|
||||
showUrl: randomData.showUrl,
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
|
||||
Reference in New Issue
Block a user