import React, { useCallback, useEffect, useMemo, useRef, useState, } from 'react'; import classNames from 'classnames'; import { useDispatch, useSelector, } from 'react-redux'; import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator'; import Spottable from '@enact/spotlight/Spottable'; import btnPlay from '../../../../assets/images/btn/btn-play-thumb-nor.png'; import defaultLogoImg from '../../../../assets/images/ic-tab-partners-default@3x.png'; import emptyHorImage from '../../../../assets/images/img-home-banner-empty-hor.png'; import emptyVerImage from '../../../../assets/images/img-home-banner-empty-ver.png'; import defaultImageItem from '../../../../assets/images/img-thumb-empty-product@3x.png'; import liveShow from '../../../../assets/images/tag-liveshow.png'; //import { sendBroadCast } from "../../../actions/commonActions"; import { pushPanel } from '../../../actions/panelActions'; import { finishVideoPreview, startVideoPlayer, } from '../../../actions/playActions'; import CustomImage from '../../../components/CustomImage/CustomImage'; import useLogService from '../../../hooks/useLogService'; import usePriceInfo from '../../../hooks/usePriceInfo'; import { LOG_MENU, LOG_TP_NO, panel_names, } from '../../../utils/Config'; import { $L, formatGMTString, } from '../../../utils/helperMethods'; import css from './RandomUnit.module.less'; const SpottableComponent = Spottable("div"); const Container = SpotlightContainerDecorator( { enterTo: "last-focused" }, "div" ); export default function RandomUnit({ bannerData, spotlightId, isHorizontal, handleItemFocus, randomNumber, }) { const bannerDetailInfos = bannerData.bannerDetailInfos; const { sendLogTopContents } = useLogService(); const dispatch = useDispatch(); const curationId = useSelector((state) => state.home?.bannerData?.curationId); const curtNm = useSelector((state) => state.home?.bannerData?.curtNm); const shptmTmplCd = useSelector( (state) => state.home?.bannerData?.shptmTmplCd ); const nowMenu = useSelector((state) => state.common.menu.nowMenu); const homeCategory = useSelector( (state) => state.home.menuData?.data?.homeCategory ); const [randomData, setRandomData] = useState(""); const [priceInfos, setpriceInfos] = useState(""); const [isFocused, setIsFocused] = useState(false); const timerRef = useRef(); const bannerDataRef = useRef(bannerData); const randomDataRef = useRef(bannerDetailInfos[randomNumber]); const [videoError, setVideoError] = useState(false); const [liveIndicies, setLiveIndicies] = useState([]); // 정상적으로 로딩되면 빈객체로 넘어가고 , 에러가 나면 객체안에 타입이 담겨옵니다. const broadcast = useSelector((state) => state.common.broadcast); // 1. 비디오(live) 에러 감지 // 2. 라이브 영상이 2개 이상이면, 그 다음 영상으로 전환 // 3. 라이브 영상이 1개면 그 다음 영상으로 전환을 할 수 없으므로 에러 로고 화면을 보여준다. // 라이브 영상이 1개 라도 순간적인 네트워크 오류나, 일시적인 오류 일수 있으므로, 일정 시간을 주고, 비디오를 다시 호출 한다. useEffect(() => { if (bannerDetailInfos && randomNumber) { const indices = bannerDetailInfos .map((info, index) => (info.shptmBanrTpNm === "LIVE" ? index : null)) .filter((index) => index !== null && index !== randomNumber); setLiveIndicies(indices); } }, [bannerDetailInfos, randomNumber]); // 비디오 에러일시, 클릭 이동 const videoErrorClick = useCallback(() => { return dispatch( pushPanel({ name: panel_names.FEATURED_BRANDS_PANEL, panelInfo: { patnrId: randomData.patnrId }, }) ); }, [randomData, dispatch]); // 포커스 인 const onFocus = useCallback(() => { if (handleItemFocus) { handleItemFocus(); } setIsFocused(true); }, [handleItemFocus]); // 포커스 아웃 const onBlur = useCallback(() => { setIsFocused(false); clearTimeout(timerRef.current); }, [isFocused]); // DSP00501 : Featured Brands // DSP00502 : Trending now // DSP00503 : HOT PICKS // DSP00504 : ON SALE // DSP00505 : CATEGORY // DSP00506 : Product Detail // DSP00507 : VOD // DSP00508 : Show Detail // DSP00509 : Theme const categoryData = useMemo(() => { if (randomData && randomData.shptmLnkTpCd === "DSP00505") { if (homeCategory && homeCategory.length > 0) { const foundCategory = homeCategory.find( (data) => data.lgCatCd === randomData.lgCatCd ); if (foundCategory) { return { lgCatNm: foundCategory.lgCatNm, COUNT: foundCategory.COUNT, }; } return; } } }, [homeCategory, randomData.shptmLnkTpCd]); // 이미지 배너 클릭 const imageBannerClick = () => { let panelName = ""; if (randomData.shptmLnkTpCd === "DSP00501") { return dispatch( pushPanel({ name: panel_names.FEATURED_BRANDS_PANEL, panelInfo: { patnrId: randomData.patnrId }, }) ); } else if (randomData.shptmLnkTpCd === "DSP00502") { panelName = panel_names.TRENDING_NOW_PANEL; } else if (randomData.shptmLnkTpCd === "DSP00503") { return dispatch( pushPanel({ name: panel_names.HOT_PICKS_PANEL, panelInfo: { patnrId: randomData.patnrId, curationId: randomData.lnkCurationId, }, }) ); } else if (randomData.shptmLnkTpCd === "DSP00504") { return dispatch( pushPanel({ name: panel_names.ON_SALE_PANEL, panelInfo: { lgCatCd: randomData.lgCatCd, }, }) ); } else if (randomData.shptmLnkTpCd === "DSP00505") { if (Object.keys(categoryData).length > 0) { return dispatch( pushPanel({ name: panel_names.CATEGORY_PANEL, panelInfo: { lgCatCd: randomData.lgCatCd, lgCatNm: categoryData.lgCatNm, COUNT: categoryData.COUNT, currentSpot: null, dropDownTab: 0, tab: 0, focusedContainerId: null, }, }) ); } } else if (randomData.shptmLnkTpCd === "DSP00506") { return dispatch( pushPanel({ name: panel_names.DETAIL_PANEL, panelInfo: { patnrId: randomData.patnrId, prdtId: randomData.prdtId, curationId: randomData.lnkCurationId, }, }) ); } else if (randomData.shptmLnkTpCd === "DSP00507") { return dispatch( startVideoPlayer({ patnrId: randomData.patnrId, showId: randomData.showId, shptmBanrTpNm: "VOD", lgCatCd: randomData.lgCatCd, modal: false, }) ); } else if (randomData.shptmLnkTpCd === "DSP00508") { return dispatch( pushPanel({ name: panel_names.DETAIL_PANEL, panelInfo: { patnrId: randomData.patnrId, curationId: randomData.lnkCurationId, prdtId: randomData.prdtId, type: "theme", }, }) ); } else if (randomData.shptmLnkTpCd === "DSP00509") { return dispatch( pushPanel({ name: panel_names.THEME_CURATION_PANEL, panelInfo: { curationId: randomData.lnkCurationId, }, }) ); } else { panelName = panel_names.HOME_PANEL; } dispatch( pushPanel({ name: panelName, panelInfo: { patnrId: randomData.patnrId, prdtId: randomData.prdtId, }, }) ); }; // 투데이즈딜 클릭 const todayDealClick = useCallback(() => { dispatch( pushPanel({ name: panel_names.DETAIL_PANEL, panelInfo: { patnrId: randomData.patnrId, prdtId: randomData.prdtId, }, }) ); }, [dispatch, randomData?.patnrId, randomData?.prdtId]); // 비디오 클릭 const videoClick = useCallback(() => { dispatch( startVideoPlayer({ showUrl: randomData.showUrl, patnrId: randomData.patnrId, showId: randomData.showId, shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : "MEDIA", lgCatCd: randomData.lgCatCd, chanId: randomData.brdcChnlId, modal: false, modalContainerId: spotlightId, modalClassName: css.videoModal, }) ); }, [randomData, spotlightId]); // 투데이즈 딜 가격 정보 const { originalPrice, discountedPrice, discountRate, offerInfo } = usePriceInfo(priceInfos) || {}; // 로그 useEffect(() => { if ( bannerDataRef.current && randomDataRef.current && nowMenu && nowMenu === LOG_MENU.HOME_TOP ) { const params = { banrNo: `${randomDataRef.current?.banrDpOrd}`, banrTpNm: randomDataRef.current?.vtctpYn ? randomDataRef.current.vtctpYn === "Y" ? "Vertical" : "Horizontal" : "", contId: curationId ?? "", contNm: curtNm ?? "", contTpNm: randomDataRef.current?.shptmBanrTpNm ?? "", dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "", expsOrd: bannerDataRef.current?.banrLctnNo ?? "", inDt: formatGMTString(new Date()), linkTpCd: "", logTpNo: LOG_TP_NO.TOP_CONTENTS, patncNm: randomDataRef.current?.patncNm ?? "", patnrId: randomDataRef.current?.patnrId ?? "", tmplCd: shptmTmplCd, }; return () => sendLogTopContents(params); } }, [curationId, curtNm, nowMenu, sendLogTopContents, shptmTmplCd]); useEffect(() => { if (bannerData) { setRandomData(bannerDetailInfos[randomNumber]); } }, [bannerData]); useEffect(() => { if (randomData && randomData.priceInfo !== null) { return setpriceInfos(randomData.priceInfo); } }, [randomData]); useEffect(() => { if (isFocused) { // 비디오 정상 if (broadcast && Object.keys(broadcast).length === 0) { setVideoError(false); timerRef.current = setTimeout( () => dispatch( startVideoPlayer({ showUrl: randomData.showUrl, patnrId: randomData.patnrId, showId: randomData.showId, shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : "MEDIA", lgCatCd: randomData.lgCatCd, chanId: randomData.brdcChnlId, modal: true, modalContainerId: spotlightId, modalClassName: css.videoModal, }) ), 1000 ); // 비디오 오류 } else if (broadcast && Object.keys(broadcast).length !== 0) { dispatch(finishVideoPreview()); if (liveIndicies.length > 0) { const nextIndex = liveIndicies[0]; setLiveIndicies((prev) => prev.slice(1)); setRandomData(bannerDetailInfos[nextIndex]); setTimeout(() => { setVideoError(false); }, 0); } else { setVideoError(true); } } } else { dispatch(finishVideoPreview()); } return () => { clearTimeout(timerRef.current); }; }, [isFocused, dispatch, broadcast, videoError]); return ( <> {randomData?.shptmBanrTpNm == "Image Banner" ? (
) : randomData?.shptmBanrTpNm == "LIVE" || randomData?.shptmBanrTpNm == "VOD" ? ( {randomData.shptmBanrTpNm == "LIVE" && videoError === false && (

)} {/* 비디오 에러 발생 */} {videoError === true && (
{randomData.patncLogoPath && ( )}

Click the screen to see more products!

)} {/* 배너 메인 이미지 */} {videoError === false && (
{randomData.tmnlImgPath ? ( ) : ( )}
)} {/* 플레이 버튼 [>] */} {videoError === false && (
{randomData.tmnlImgPath == null ? "" : }
)} {/* 배너 하단 로고 */} {videoError === false && (

{randomData.showId && ( )}

)}
) : randomData?.shptmBanrTpNm == "Today's Deals" ? (
{$L("TODAY's DEALS")}
{randomData.prdtNm}
{parseFloat(originalPrice?.replace("$", "")) === 0 ? ( {randomData.offerInfo} ) : discountRate ? ( discountedPrice ) : ( originalPrice )}
{discountRate && ( {originalPrice} )}
) : null}
); }