[No Jira Issue] IF-LGSP-LOG-005 (GNB 이력) Magic Mouse 대응 (TrendingNowPanel 2차)

Changed files:
1. deepLinkHandler.js
2. TrendingNowPanel.jsx
3. PopularShowIndicator.jsx
4. PopularShowIndicator.module.less
5. PopularProductList.jsx
6. PopularVideoCard.jsx

Detail Note:
1. Component optimization
2. Removal of duplicate functions and effects
3. Deletion of unnecessary props and imports
This commit is contained in:
younghoon100.park
2024-11-14 16:14:54 +09:00
parent 234eb819e9
commit 2d2d01c53c
6 changed files with 161 additions and 219 deletions

View File

@@ -1,6 +1,7 @@
import { updateHomeInfo } from "../actions/homeActions";
import { pushPanel } from "../actions/panelActions";
import { LOG_MENU, panel_names } from "../utils/Config";
import { SpotlightIds } from "../utils/SpotlightIds";
//V2_진입경로코드_진입경로명_MT_노출순번
export const handleDeepLink = (contentTarget) => (dispatch, getState) => {
@@ -177,6 +178,7 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => {
panelName = panel_names.TRENDING_NOW_PANEL;
panelInfo = {
pageName: "BS",
focusedContainerId: SpotlightIds.TRENDING_NOW_BEST_SELLER,
};
break;
@@ -186,6 +188,7 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => {
panelName = panel_names.TRENDING_NOW_PANEL;
panelInfo = {
pageName: "PS",
focusedContainerId: SpotlightIds.TRENDING_NOW_POPULAR_SHOW,
};
break;

View File

@@ -27,12 +27,8 @@ const PopularShowIndicator = ({
showNm,
disclaimer,
expsOrd,
orderPhnNo,
productInfos,
patnrId,
selectedPatnrId,
vtctpYn,
showUrl,
catCd,
showId,
patncNm,
@@ -41,58 +37,40 @@ const PopularShowIndicator = ({
const isVertical = Boolean(vtctpYn === "Y");
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.TRENDING_NOW_POPULAR_SHOWS);
}
if (handleItemFocus) handleItemFocus(LOG_MENU.TRENDING_NOW_POPULAR_SHOWS);
}, [handleItemFocus]);
const _handleItemClick = useCallback(() => {
if (handleItemClick) {
handleItemClick();
}
if (handleItemClick) handleItemClick();
}, [handleItemClick]);
return (
<div className={css.popularContainer}>
<div className={css.popularContents}>
<Container>
<Container className={css.popularContainer}>
<PopularVideoCard
thumbnailImgPath={thumbnailUrl960}
showNm={showNm}
disclaimer={disclaimer}
expsOrd={expsOrd}
orderPhnNo={orderPhnNo}
thumbnailType={isVertical ? "vertical" : "horizontal"}
isVertical={isVertical}
popularShowInfos={topInfos[selectedIndex]}
showUrl={showUrl}
spotlightId={SpotlightIds.TRENDING_NOW_POPULAR_VIDEO}
onSpotlightDown={onSpotlightDown}
showId={showId}
patnrId={patnrId}
lgCatCd={catCd}
handleItemClick={_handleItemClick}
handleItemFocus={_handleItemFocus}
patncNm={patncNm}
isOnTop={isOnTop}
/>
</Container>
<Container className={css.popularProductListContainer}>
<PopularProductList
brandProductInfo={productInfos}
topInfosData={topInfos[selectedIndex]}
patnrId={patnrId}
lgCatCd={catCd}
selectedPatnrId={selectedPatnrId}
onSpotlightDown={onSpotlightDown}
patncNm={patncNm}
patnrId={patnrId}
showId={showId}
showNm={showNm}
spotlightId={SpotlightIds.TRENDING_NOW_POPULAR_VIDEO}
thumbnailType={isVertical ? "vertical" : "horizontal"}
thumbnailImgPath={thumbnailUrl960}
/>
<PopularProductList
handleItemClick={_handleItemClick}
handleItemFocus={_handleItemFocus}
onSpotlightRight={onSpotlightRight}
onSpotlightDown={onSpotlightDown}
selectedIndex={selectedIndex}
handleItemFocus={_handleItemFocus}
handleItemClick={_handleItemClick}
topInfo={topInfos[selectedIndex]}
/>
</Container>
</div>
</div>
);
};

View File

@@ -2,9 +2,12 @@
@import "../../../style/utils.module.less";
.popularContainer {
.size(@w:1638px,@h:564px);
position: relative;
display: flex;
justify-content: space-between;
.size(@w:1638px,@h:564px);
margin: 42px 0 0 90px;
&::after {
.position(@position: absolute, @right: 18px, @bottom: -46px);
z-index: 12;
@@ -13,42 +16,4 @@
background-image: url("../../../../assets/images/img-topdeals-list-masking.png");
content: "";
}
.popularContents {
display: flex;
justify-content: space-between;
}
.player {
.position(@position: absolute, @top: 22px, @left: 0);
z-index: 20;
height: 564px;
display: none;
overflow: hidden;
border-radius: 12px;
&.vertical {
width: 326px;
}
&.horizontal {
width: 1002px;
}
&::before {
// Video desc
// .position(@position: absolute, @top: 33px, @left: 18px);
// z-index: 20;
// .size(@w: 108px, @h: 48px);
// border-radius: 12px;
// background-image: url("../../../../../assets/images/tag/tag-liveshow.png");
// background-position: center center;
// background-repeat: no-repeat;
// content: "";
}
&::after {
.focused(@borderRadius: 12px);
}
.focusDropShadow();
}
}

View File

@@ -1,8 +1,7 @@
import React, { memo, useCallback, useEffect, useRef } from "react";
import React, { memo, useCallback, useEffect } from "react";
import { useDispatch } from "react-redux";
import { pushPanel } from "../../../../actions/panelActions";
import { startVideoPlayer } from "../../../../actions/playActions";
import TItemCard, {
removeDotAndColon,
@@ -10,64 +9,38 @@ import TItemCard, {
} from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from "../../../../hooks/useScrollTo";
import { panel_names } from "../../../../utils/Config";
import { scaleH } from "../../../../utils/helperMethods";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import css from "./PopularProductList.module.less";
export default function PopularProductList({
patnrId,
selectedPatnrId,
const PopularProductList = ({
handleItemClick,
handleItemFocus,
onSpotlightRight,
topInfosData,
brandProductInfo,
onFocus,
onSpotlightDown,
selectedIndex,
handleItemFocus,
handleItemClick,
lgCatCd,
}) {
topInfo,
}) => {
const { getScrollTo, scrollTop } = useScrollTo();
const dispatch = useDispatch();
const timerRef = useRef();
const { catCd, patnrId, productInfos, showId } = topInfo;
useEffect(() => {
timerRef.current = setTimeout(() => scrollTop({ animate: false }));
return () => clearTimeout(timerRef.current);
let timer = setTimeout(() => scrollTop({ animate: false }));
return () => clearTimeout(timer);
}, [selectedIndex]);
const _onSpotlightDown = useCallback(
(ev) => {
if (onSpotlightDown) {
ev.stopPropagation();
ev.preventDefault();
onSpotlightDown(ev);
}
if (onSpotlightDown) onSpotlightDown(ev);
},
[onSpotlightDown]
);
const handleFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus();
}
}, [handleItemFocus]);
const renderItem = useCallback(
({ index, ...rest }) => {
const {
offerInfo,
prdtId,
imgUrl,
prdtNm,
priceInfo,
soldoutFlag,
offsetHour,
} = brandProductInfo[index];
const { showId, patnrId } = topInfosData;
const handleClick = useCallback(
(index, offsetHour, prdtId) => () => {
let y =
index < 2
? 0
@@ -75,7 +48,6 @@ export default function PopularProductList({
? scaleH(208)
: scaleH(index * 248 - 248 - 40);
const handleClick = () => {
dispatch(
startVideoPlayer({
targetId: "spotlightId-" + removeDotAndColon(prdtId),
@@ -83,7 +55,7 @@ export default function PopularProductList({
showId,
patnrId,
prdtId,
lgCatCd,
lgCatCd: catCd,
shptmBanrTpNm: "VOD",
index,
modal: false,
@@ -91,16 +63,32 @@ export default function PopularProductList({
})
);
if (handleItemClick) {
handleItemClick();
}
};
if (handleItemClick) handleItemClick();
},
[catCd, patnrId, showId, handleItemClick]
);
const handleFocus = useCallback(() => {
if (handleItemFocus) handleItemFocus();
}, [handleItemFocus]);
const renderItem = useCallback(
({ index, ...rest }) => {
const {
imgUrl,
offerInfo,
offsetHour,
prdtId,
prdtNm,
priceInfo,
soldoutFlag,
} = productInfos[index];
return (
<TItemCard
imageAlt={prdtNm}
imageSource={imgUrl}
onClick={handleClick}
onClick={handleClick(index, offsetHour, prdtId)}
onFocus={handleFocus}
offerInfo={offerInfo}
priceInfo={priceInfo}
@@ -109,24 +97,26 @@ export default function PopularProductList({
className={css.itemCard}
type={TYPES.horizontal}
onSpotlightRight={onSpotlightRight}
spotlightId={"popular-spotlightId-" + removeDotAndColon(prdtId)}
spotlightId={
"spotlightId-" + "popularShow-" + removeDotAndColon(prdtId)
}
onSpotlightDown={_onSpotlightDown}
label={index * 1 + 1 + " of " + brandProductInfo.length}
label={index * 1 + 1 + " of " + productInfos.length}
lastLabel=" go to detail, button"
{...rest}
/>
);
},
[brandProductInfo, dispatch, patnrId, handleFocus, handleItemClick]
[productInfos, handleClick, handleFocus, _onSpotlightDown]
);
return (
<div className={css.container}>
{brandProductInfo && (
{productInfos && (
<TVirtualGridList
cbScrollTo={getScrollTo}
className={css.tVirtualGridList}
dataSize={brandProductInfo.length}
dataSize={productInfos.length}
itemHeight={236}
itemWidth={600}
spacing={12}
@@ -137,4 +127,6 @@ export default function PopularProductList({
)}
</div>
);
}
};
export default memo(PopularProductList);

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import React, { memo, useCallback, useEffect, useRef, useState } from "react";
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { Job } from "@enact/core/util";
import Spotlight from "@enact/spotlight";
@@ -10,7 +10,7 @@ import { Marquee } from "@enact/ui/Marquee";
import ic_crown from "../../../../../assets/images/icons/ic-crown-badge@3x.png";
import ic_warning from "../../../../../assets/images/icons/ic-warning@3x.png";
import ic_call from "../../../../../assets/images/icons/ic-wh-call@3x.png";
// import ic_call from "../../../../../assets/images/icons/ic-wh-call@3x.png";
import {
finishVideoPreview,
startVideoPlayer,
@@ -20,7 +20,7 @@ import css from "./PopularVideoCard.module.less";
const SpottableComponent = Spottable("div");
const PHONE_STRING = "Phone";
// const PHONE_STRING = "Phone";
const WARNING_STRING = "warning";
const TYPE = {
@@ -28,46 +28,39 @@ const TYPE = {
vertical: "vertical",
};
export default function PopularVideoCard({
showNm,
expsOrd,
orderPhnNo,
thumbnailImgPath,
const PopularVideoCard = ({
disclaimer,
isVertical,
showUrl,
expsOrd,
handleItemClick,
handleItemFocus,
isOnTop,
lgCatCd,
onSpotlightDown,
patncNm,
patnrId,
showId,
showNm,
spotlightId,
thumbnailType = TYPE.horizontal,
onSpotlightDown,
onSpotlightRight,
onSpotlightLeft,
showId,
patnrId,
lgCatCd,
handleItemFocus,
patncNm,
handleItemClick,
isOnTop,
}) {
thumbnailImgPath,
}) => {
const dispatch = useDispatch();
const [isFocused, setIsFocused] = useState(false);
const videoFocusTimeoutJob = useRef(new Job((func) => func(), 1000));
const isFullScreenModeActivedRef = useRef(false);
const cursorVisible = useSelector(
(state) => state.common.appStatus.cursorVisible
);
const [isFocused, setIsFocused] = useState(false);
const isFullScreenModeActiveRef = useRef(false);
const videoFocusTimeoutJob = useRef(new Job((func) => func(), 1000));
useEffect(() => {
if (isFullScreenModeActivedRef.current && isOnTop) {
if (isFullScreenModeActiveRef.current && isOnTop) {
setTimeout(() => {
if (cursorVisible || Spotlight.getPointerMode()) {
if (Spotlight.getPointerMode()) {
dispatch(finishVideoPreview());
isFullScreenModeActivedRef.current = false;
isFullScreenModeActiveRef.current = false;
}
});
}
}, [cursorVisible, isOnTop]);
}, [isOnTop]);
useEffect(() => {
const videoFocusTimeoutJobValue = videoFocusTimeoutJob.current;
@@ -87,7 +80,7 @@ export default function PopularVideoCard({
})
);
isFullScreenModeActivedRef.current = true;
isFullScreenModeActiveRef.current = true;
});
} else {
videoFocusTimeoutJobValue.stop();
@@ -97,9 +90,8 @@ export default function PopularVideoCard({
const onFocus = useCallback(() => {
setIsFocused(true);
if (handleItemFocus) {
handleItemFocus();
}
if (handleItemFocus) handleItemFocus();
}, [handleItemFocus]);
const onBlur = useCallback(() => {
@@ -122,18 +114,12 @@ export default function PopularVideoCard({
})
);
if (handleItemClick) {
handleItemClick();
}
if (handleItemClick) handleItemClick();
}, [dispatch, showId, spotlightId, handleItemClick]);
const _onSpotlightDown = useCallback(
(ev) => {
if (onSpotlightDown) {
ev.stopPropagation();
ev.preventDefault();
onSpotlightDown(ev);
}
if (onSpotlightDown) onSpotlightDown(ev);
},
[onSpotlightDown]
);
@@ -175,4 +161,6 @@ export default function PopularVideoCard({
</div>
</SpottableComponent>
);
}
};
export default memo(PopularVideoCard);

View File

@@ -15,10 +15,11 @@ import { getBestSeller } from "../../actions/productActions";
import SectionTitle from "../../components/SectionTitle/SectionTitle";
import TBody from "../../components/TBody/TBody";
import TButton, { TYPES } from "../../components/TButton/TButton";
import TItemCard from "../../components/TItemCard/TItemCard";
import TItemCard, {
removeDotAndColon,
} from "../../components/TItemCard/TItemCard";
import TPanel from "../../components/TPanel/TPanel";
import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator";
import usePrevious from "../../hooks/usePrevious";
import useWhyDidYouUpdate from "../../hooks/useWhyDidYouUpdate";
import { LOG_MENU, panel_names } from "../../utils/Config";
import { $L } from "../../utils/helperMethods";
@@ -91,15 +92,25 @@ const TrendingNowPanel = ({ panelInfo, spotlightId, isOnTop, ...rest }) => {
}, [panelInfo?.selectedIndex]);
useEffect(() => {
if (isOnTop && panelInfo?.focusedContainerId) {
const menu =
panelInfo?.focusedContainerId === SpotlightIds.TRENDING_NOW_POPULAR_SHOW
? LOG_MENU.TRENDING_NOW_POPULAR_SHOWS
: LOG_MENU.TRENDING_NOW_BEST_SELLER;
if (isOnTop) {
let menu;
dispatch(sendLogGNB(menu));
// case: entering through a deep link or the Home, and returning from the player or details
if (panelInfo?.focusedContainerId) {
menu =
panelInfo.focusedContainerId !==
SpotlightIds.TRENDING_NOW_POPULAR_SHOW
? LOG_MENU.TRENDING_NOW_BEST_SELLER
: LOG_MENU.TRENDING_NOW_POPULAR_SHOWS;
}
}, [isOnTop && panelInfo?.focusedContainerId]);
// case: entering through the GNB
else {
menu = LOG_MENU.TRENDING_NOW_POPULAR_SHOWS;
}
if (menu) dispatch(sendLogGNB(menu));
}
}, [isOnTop]);
const onFocusedContainerId = useCallback((containerId) => {
focusedContainerIdRef.current = containerId;
@@ -288,21 +299,26 @@ const TrendingNowPanel = ({ panelInfo, spotlightId, isOnTop, ...rest }) => {
<div className={css.itemList}>
{bestSeller.map((item, index) => (
<TItemCard
key={item.prdtId}
data-wheel-point={index >= 5}
firstLabel={getFirstLabel(item.rankOrd)}
imageAlt={item.prdtId}
imageSource={item.imgUrl}
priceInfo={item.priceInfo}
productName={item.prdtNm}
key={item.prdtId}
isBestSeller
rank={item.rankOrd}
onFocus={handleBestSellerFocus}
onClick={handleBestSellerClick(item)}
offerInfo={item.offerInfo}
productId={item.prdtId}
firstLabel={getFirstLabel(item.rankOrd)}
label={index * 1 + 1 + " of " + bestSeller.length}
lastLabel=" go to detail, button"
data-wheel-point={index >= 5}
offerInfo={item.offerInfo}
onFocus={handleBestSellerFocus}
onClick={handleBestSellerClick(item)}
priceInfo={item.priceInfo}
productName={item.prdtNm}
productId={item.prdtId}
rank={item.rankOrd}
spotlightId={
"spotlightId-" +
"bestSeller-" +
removeDotAndColon(item.prdtId)
}
/>
))}
</div>