Files
shoptime/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.new.jsx

119 lines
4.2 KiB
JavaScript

// src/views/HomePanel/HomeBanner/RandomUnit.new.jsx (새 파일)
import React, { useCallback } from "react";
import { useDispatch } from "react-redux";
import classNames from "classnames";
import Spottable from "@enact/spotlight/Spottable";
// 새로운 '플레이 제어 매니저' 액션들을 임포트합니다.
import {
requestPlayControl,
releasePlayControl,
goToFullScreen,
} from "../../../actions/playActions";
import CustomImage from "../../../components/CustomImage/CustomImage";
import liveShow from "../../../../assets/images/tag-liveshow.png";
import emptyHorImage from "../../../../assets/images/img-home-banner-empty-hor.png";
import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png";
import css from "./RandomUnit.module.less"; // 스타일은 기존 RandomUnit과 공유
const SpottableComponent = Spottable("div");
/**
* 이 컴포넌트는 새로운 '플레이 제어 매니저' 아키텍처를 사용하여
* '포커스를 받을 때만' 미리보기 비디오를 재생하는 '배너 1'의 역할을 합니다.
*/
export default function RandomUnitNew({
bannerData,
spotlightId,
isHorizontal,
handleShelfFocus,
handleItemFocus,
randomNumber,
}) {
const dispatch = useDispatch();
const randomData = bannerData.bannerDetailInfos[randomNumber];
/**
* 이 컴포넌트에 포커스가 들어왔을 때 호출됩니다.
* 'banner1_preview'라는 고유 ID로 비디오 재생 제어권을 '요청'합니다.
*/
const handleFocus = useCallback(() => {
if (randomData && randomData.showUrl) {
const videoInfo = {
showUrl: randomData.showUrl,
patnrId: randomData.patnrId,
showId: randomData.showId,
shptmBanrTpNm: randomData.shptmBanrTpNm,
modalContainerId: spotlightId,
};
dispatch(requestPlayControl("banner1_preview", videoInfo));
}
if (handleItemFocus) {
handleItemFocus();
}
}, [dispatch, randomData, spotlightId, handleItemFocus]);
/**
* 이 컴포넌트에서 포커스가 나갔을 때 호출됩니다.
* 'banner1_preview'가 가지고 있던 비디오 재생 제어권을 '해제'합니다.
*/
const handleBlur = useCallback(() => {
dispatch(releasePlayControl("banner1_preview"));
}, [dispatch]);
/**
* 사용자가 이 배너를 클릭했을 때 호출됩니다.
* 'goToFullScreen' 액션을 호출하여 공유 PlayerPanel을 전체화면으로 전환합니다.
*/
const handleGoToFullScreen = useCallback(() => {
dispatch(goToFullScreen());
}, [dispatch]);
// 상위 컴포넌트로 포커스 이벤트를 전달하는 콜백
const onContainerFocus = useCallback(() => {
if (handleShelfFocus) {
handleShelfFocus();
}
}, [handleShelfFocus]);
// 비디오 재생이 가능한 타입인지 확인 (LIVE 또는 VOD)
const isVideoContent =
randomData?.shptmBanrTpNm === "LIVE" || randomData?.shptmBanrTpNm === "VOD";
return (
<div onFocus={onContainerFocus}>
<SpottableComponent
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
spotlightId={spotlightId}
onClick={isVideoContent ? handleGoToFullScreen : undefined} // 비디오 컨텐츠일 때만 클릭 이벤트 연결
onFocus={isVideoContent ? handleFocus : handleItemFocus} // 비디오 컨텐츠일 때만 포커스 이벤트 연결
onBlur={isVideoContent ? handleBlur : undefined} // 비디오 컨텐츠일 때만 블러 이벤트 연결
aria-label={randomData?.showNm || randomData?.prdtNm}
>
<div
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
>
<CustomImage
delay={0}
src={randomData?.tmnlImgPath}
fallbackSrc={isHorizontal ? emptyHorImage : undefined}
animationSpeed="fast"
/>
{isVideoContent && randomData?.tmnlImgPath && (
<div className={css.btnPlay}>
<img src={btnPlay} alt="Play" />
</div>
)}
{randomData?.shptmBanrTpNm === "LIVE" && (
<p className={css.liveIcon}>
<CustomImage delay={0} src={liveShow} animationSpeed="fast" />
</p>
)}
</div>
</SpottableComponent>
</div>
);
}