From e8ba1bbf4ff39f873f33874ddc4d313de74a7676 Mon Sep 17 00:00:00 2001 From: yonghyon Date: Tue, 15 Oct 2024 17:46:53 +0900 Subject: [PATCH] =?UTF-8?q?[SHOPTIME-3707]=20Home=20/=20Top=20/=20?= =?UTF-8?q?=EC=9A=B0=EC=B8=A1=20=EC=83=81=EB=8B=A8=20/=20=ED=8F=AC?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=EA=B0=80=20=EC=9E=88=EB=8A=94=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=97=90=EC=84=9C=20=EB=A1=A4=EB=A7=81=EC=9D=B4=20?= =?UTF-8?q?=EB=90=A8=20=EC=9B=90=EC=9D=B8=20:=20React=20depencency=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20focus=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EB=A5=BC=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=ED=95=98=EC=A7=80=20=EB=AA=BB=ED=95=A8.=20?= =?UTF-8?q?=EB=8C=80=EC=B1=85=20:=20depencency=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20ref=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomePanel/HomeBanner/RollingUnit.jsx | 289 ++++++------------ 1 file changed, 85 insertions(+), 204 deletions(-) diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx index 73c6b578..57b9bbb5 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx @@ -1,54 +1,31 @@ -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import classNames from 'classnames'; -import { - useDispatch, - useSelector, -} from 'react-redux'; +import classNames from "classnames"; +import { useDispatch, useSelector } from "react-redux"; -import SpotlightContainerDecorator - from '@enact/spotlight/SpotlightContainerDecorator'; -import Spottable from '@enact/spotlight/Spottable'; +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 { setBannerIndex } from '../../../actions/homeActions'; -import { sendLogTopContents } from '../../../actions/logActions'; -import { pushPanel } from '../../../actions/panelActions'; -import { startVideoPlayer } from '../../../actions/playActions'; -import CustomImage from '../../../components/CustomImage/CustomImage'; -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 './RollingUnit.module.less'; +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 { setBannerIndex } from "../../../actions/homeActions"; +import { sendLogTopContents } from "../../../actions/logActions"; +import { pushPanel } from "../../../actions/panelActions"; +import { startVideoPlayer } from "../../../actions/playActions"; +import CustomImage from "../../../components/CustomImage/CustomImage"; +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 "./RollingUnit.module.less"; const SpottableComponent = Spottable("div"); -const Container = SpotlightContainerDecorator( - { enterTo: "last-focused" }, - "div" -); +const Container = SpotlightContainerDecorator({ enterTo: "last-focused" }, "div"); const LINK_TYPES = { FEATURED_BRANDS: "DSP00501", @@ -75,12 +52,7 @@ const createPanelInfo = (data, categoryData = {}) => ({ focusedContainerId: null, }); -export default function RollingUnit({ - bannerData, - spotlightId, - isHorizontal, - handleItemFocus, -}) { +export default function RollingUnit({ bannerData, spotlightId, isHorizontal, handleItemFocus }) { const rollingData = bannerData.bannerDetailInfos; const rollingDataLength = bannerData.bannerDetailInfos.length; @@ -88,25 +60,20 @@ export default function RollingUnit({ 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 shptmTmplCd = useSelector((state) => state.home?.bannerData?.shptmTmplCd); const nowMenu = useSelector((state) => state.common.menu.nowMenu); const entryMenu = useSelector((state) => state.common.menu.entryMenu); - const homeCategory = useSelector( - (state) => state.home.menuData?.data?.homeCategory - ); + const homeCategory = useSelector((state) => state.home.menuData?.data?.homeCategory); const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd); const bannerId = `banner-${bannerData.banrLctnNo}`; const savedIndex = useSelector((state) => state.home.bannerIndices[bannerId]); - const [startIndex, setStartIndex] = useState( - savedIndex !== undefined ? savedIndex : 0 - ); - const lastIndex = rollingDataLength - 1; - const [rollingFocus, setRollingFocus] = useState(false); + const [startIndex, setStartIndex] = useState(savedIndex !== undefined ? savedIndex : 0); + const lastIndexRef = useRef(rollingDataLength - 1); + const doRollingRef = useRef(false); + const [unitHasFocus, setUnitHasFocus] = useState(false); const [contentsFocus, setContentsFocus] = useState(false); const [prevFocus, setPrevFocus] = useState(false); const [nextFocus, setNextFocus] = useState(false); @@ -153,11 +120,7 @@ export default function RollingUnit({ return { banrNo: `${currentRollingData?.banrDpOrd}`, - banrTpNm: currentRollingData?.vtctpYn - ? currentRollingData.vtctpYn === "Y" - ? "Vertical" - : "Horizontal" - : "", + banrTpNm: currentRollingData?.vtctpYn ? (currentRollingData.vtctpYn === "Y" ? "Vertical" : "Horizontal") : "", contId, contNm, contTpNm: currentRollingData?.shptmBanrTpNm ?? "", @@ -179,37 +142,27 @@ export default function RollingUnit({ } }, [savedIndex]); - const animate = useCallback( - (time) => { - if (previousTimeRef.current != undefined) { - const deltaTime = time - previousTimeRef.current; + const animate = useCallback((time) => { + if (previousTimeRef.current != undefined) { + const deltaTime = time - previousTimeRef.current; - if (deltaTime >= 10000 && !rollingFocus && rollingDataLength > 1) { - setStartIndex((prevIndex) => - prevIndex === lastIndex ? 0 : prevIndex + 1 - ); - previousTimeRef.current = time; - } - } else { + if (deltaTime >= 10000 && doRollingRef.current) { + setStartIndex((prevIndex) => (prevIndex === lastIndexRef.current ? 0 : prevIndex + 1)); previousTimeRef.current = time; } + } else { + previousTimeRef.current = time; + } - if (typeof window === "object") { - requestRef.current = window.requestAnimationFrame(animate); - } - }, - [rollingFocus, rollingDataLength, lastIndex] - ); - - // 롤링 시작 여부 true = stop, false = start - const rollingStart = useCallback((focus) => { - setRollingFocus(focus); + if (typeof window === "object") { + requestRef.current = window.requestAnimationFrame(animate); + } }, []); // 롤링 이전 버튼 const handlePrev = useCallback(() => { if (startIndex === 0) { - setStartIndex(lastIndex); + setStartIndex(lastIndexRef.current); return; } setStartIndex(startIndex - 1); @@ -217,27 +170,25 @@ export default function RollingUnit({ // 롤링 다음 버튼 const handleNext = useCallback(() => { - if (lastIndex === startIndex) { + if (lastIndexRef.current === startIndex) { setStartIndex(0); return; } setStartIndex(startIndex + 1); - }, [startIndex, lastIndex]); + }, [startIndex]); // 베너 포커스 인 const onFocus = useCallback(() => { if (handleItemFocus) { handleItemFocus(); } - rollingStart(true); - setRollingFocus(true); - }, [handleItemFocus, rollingStart]); + setUnitHasFocus(true); + }, [handleItemFocus]); // 배너 포커스 아웃 - const onBlur = () => { - rollingStart(false); - setRollingFocus(false); - }; + const onBlur = useCallback(() => { + setUnitHasFocus(false); + }, []); // 인디케이터 아래키 누를시 [<] const prevKeyDown = (event) => { @@ -264,17 +215,17 @@ export default function RollingUnit({ setNextFocus(false); setContentsFocus(false); setPrevFocus(false); - rollingStart(true); - }, [handleItemFocus, rollingStart]); + setUnitHasFocus(true); + }, [handleItemFocus]); // 인디케이터 포커스 아웃 - const indicatorBlur = () => { - rollingStart(false); + const indicatorBlur = useCallback(() => { + setUnitHasFocus(false); setTimeout(() => { setNextFocus(false); setContentsFocus(false); }, 300); - }; + }, []); const categoryData = useMemo(() => { if ( @@ -282,9 +233,7 @@ export default function RollingUnit({ rollingData[startIndex].shptmLnkTpCd === LINK_TYPES.CATEGORY ) { if (homeCategory && homeCategory.length > 0) { - const foundCategory = homeCategory.find( - (data) => data.lgCatCd === rollingData[startIndex].lgCatCd - ); + const foundCategory = homeCategory.find((data) => data.lgCatCd === rollingData[startIndex].lgCatCd); if (foundCategory) { return { lgCatNm: foundCategory.lgCatNm, @@ -341,17 +290,11 @@ export default function RollingUnit({ break; case LINK_TYPES.TRENDING_NOW: - handlePushPanel( - panel_names.TRENDING_NOW_PANEL, - createPanelInfo(currentData) - ); + handlePushPanel(panel_names.TRENDING_NOW_PANEL, createPanelInfo(currentData)); break; case LINK_TYPES.HOT_PICKS: - handlePushPanel( - panel_names.HOT_PICKS_PANEL, - createPanelInfo(currentData) - ); + handlePushPanel(panel_names.HOT_PICKS_PANEL, createPanelInfo(currentData)); break; case LINK_TYPES.ON_SALE: @@ -362,10 +305,7 @@ export default function RollingUnit({ case LINK_TYPES.CATEGORY: if (Object.keys(categoryData).length > 0) { - handlePushPanel( - panel_names.CATEGORY_PANEL, - createPanelInfo(currentData, categoryData) - ); + handlePushPanel(panel_names.CATEGORY_PANEL, createPanelInfo(currentData, categoryData)); } break; @@ -397,15 +337,7 @@ export default function RollingUnit({ logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK, }) ); - }, [ - rollingData, - startIndex, - bannerId, - dispatch, - categoryData, - handlePushPanel, - topContentsLogInfo, - ]); + }, [rollingData, startIndex, bannerId, dispatch, categoryData, handlePushPanel, topContentsLogInfo]); const videoClick = useCallback(() => { if (bannerId) { @@ -433,32 +365,26 @@ export default function RollingUnit({ logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK, }) ); - }, [ - rollingData, - startIndex, - bannerId, - dispatch, - handleStartVideoPlayer, - topContentsLogInfo, - ]); + }, [rollingData, startIndex, bannerId, dispatch, handleStartVideoPlayer, topContentsLogInfo]); // 10초 롤링 useEffect(() => { // 데이터가 1개인 경우 및 포커스 있는 경우 롤링 하지 않음 - if (rollingDataLength === 1 || rollingFocus) { - return; - } - - if (typeof window === "object") { - requestRef.current = window.requestAnimationFrame(animate); - } - - return () => { + lastIndexRef.current = rollingDataLength - 1; + previousTimeRef.current = undefined; + if (rollingDataLength <= 1 || unitHasFocus) { + doRollingRef.current = false; if (typeof window === "object") { window.cancelAnimationFrame(requestRef.current); } - }; - }, [rollingDataLength, rollingFocus, animate]); + return; + } + + doRollingRef.current = true; + if (typeof window === "object") { + requestRef.current = window.requestAnimationFrame(animate); + } + }, [rollingDataLength, unitHasFocus]); useEffect(() => { let _nowMenu = nowMenu; @@ -489,12 +415,7 @@ export default function RollingUnit({ }, [nowMenu]); return ( - + {rollingDataLength !== 1 ? ( ) : null} - {rollingData && - rollingData[startIndex].shptmBanrTpNm === "Image Banner" ? ( + {rollingData && rollingData[startIndex].shptmBanrTpNm === "Image Banner" ? (
@@ -538,28 +456,14 @@ export default function RollingUnit({ aria-label={"LIVE " + rollingData[startIndex].showNm} >

- +

-
+
{rollingData[startIndex].tmnlImgPath == null ? ( @@ -576,11 +480,7 @@ export default function RollingUnit({ {rollingData[startIndex].tmnlImgPath == null ? ( "" ) : ( - + )}
@@ -605,20 +505,11 @@ export default function RollingUnit({ spotlightDisabled={contentsFocus} aria-label={rollingData[startIndex].showNm} > -
+
{rollingData[startIndex].tmnlImgPath == null ? ( ) : ( @@ -633,11 +524,7 @@ export default function RollingUnit({ {rollingData[startIndex].tmnlImgPath == null ? ( "" ) : ( - + )}
@@ -669,9 +556,7 @@ export default function RollingUnit({ spotlightId={spotlightId} spotlightDisabled={contentsFocus} aria-label={ - rollingData[startIndex].prdtNm - ? rollingData[startIndex].prdtNm - : rollingData[startIndex].tmnlImgNm + rollingData[startIndex].prdtNm ? rollingData[startIndex].prdtNm : rollingData[startIndex].tmnlImgNm } >
@@ -688,13 +573,9 @@ export default function RollingUnit({ : discountRate ? discountedPrice : originalPrice} - {discountRate && !isHorizontal && ( - {originalPrice} - )} + {discountRate && !isHorizontal && {originalPrice}}
- {isHorizontal && ( - {originalPrice} - )} + {isHorizontal && {originalPrice}}