Files
shoptime/com.twin.app.shoptime/src/views/DetailPanel/YouMayLike/YouMayLike.jsx

242 lines
6.8 KiB
JavaScript

import React, {
memo,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import { Job } from "@enact/core/util";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";
import { clearThemeDetail } from "../../../actions/homeActions";
import { getMainYouMayLike } from "../../../actions/mainActions";
import { popPanel, pushPanel } from "../../../actions/panelActions";
import { finishVideoPreview } from "../../../actions/playActions";
import TItemCard from "../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from "../../../hooks/useScrollTo";
import { panel_names } from "../../../utils/Config";
import { $L } from "../../../utils/helperMethods";
import { SpotlightIds } from "../../../utils/SpotlightIds";
import css from "./YouMayLike.module.less";
import { sendLogTotalRecommend } from "../../../actions/logActions";
import * as Config from "../../../utils/Config";
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element" },
"div"
);
const SpottableComponent = Spottable("div");
export default memo(function YouMayLike({
isUnable,
panelInfo,
productInfo,
setSelectedIndex,
setIsYouMayLikeOpened,
}) {
const [focused, setFocused] = useState(false);
const [expanded, setExpanded] = useState(false);
const dispatch = useDispatch();
const youmaylikeData = useSelector((state) => state.main.youmaylikeData);
const { getScrollTo, scrollLeft } = useScrollTo();
const panels = useSelector((state) => state.panels.panels);
const cursorVisible = useSelector(
(state) => state.common.appStatus.cursorVisible
);
const themeProductInfos = useSelector(
(state) => state.home.themeCurationDetailInfoData
);
const cursorOpen = useRef(new Job((func) => func(), 1000));
const launchedFromPlayer = useMemo(() => {
const detailPanelIndex = panels.findIndex(
({ name }) => name === "detailpanel"
);
const playerPanelIndex = panels.findIndex(
({ name }) => name === "playerpanel"
);
return detailPanelIndex - 1 === playerPanelIndex;
}, [panels]);
useEffect(() => {
if (expanded) {
setIsYouMayLikeOpened(true);
return () => setIsYouMayLikeOpened(false);
}
}, [expanded, setIsYouMayLikeOpened]);
useEffect(() => {
scrollLeft();
}, [panelInfo]);
const cursorVisibleOnFocus = useCallback(() => {
if (cursorVisible) {
cursorOpen.current.start(() => {
setExpanded(true);
});
} else if (productInfo) {
setExpanded(true);
}
}, [productInfo, cursorVisible]);
const cursorVisibleOnBlur = useCallback(() => {
if (cursorVisible) {
cursorOpen.current.stop();
}
}, [cursorVisible]);
const onFocus = useCallback(() => {
if (productInfo) {
setFocused(true);
}
}, [productInfo]);
const onBlur = useCallback(() => {
setFocused(false);
}, []);
const onClickExtraArea = useCallback(() => {
setExpanded(false);
setFocused(false);
}, []);
const onKeyDown = useCallback((event) => {
if (event.key === "ArrowUp") {
setExpanded(false);
event.stopPropagation();
event.preventDefault();
Spotlight.focus("spotlight-IndicatorContainer");
}
}, []);
const onButtonClick = useCallback(() => {
setExpanded((prev) => !prev);
}, []);
const renderItem = useCallback(
({ index, ...rest }) => {
const {
imgUrl,
patnrId,
prdtId,
prdtNm,
priceInfo,
offerInfo,
patncNm,
brndNm,
lgCatCd,
lgCatNm,
} = youmaylikeData[index];
const handleItemClick = () => {
setExpanded(false);
setSelectedIndex(0);
dispatch(finishVideoPreview());
dispatch(popPanel(panel_names.DETAIL_PANEL));
setContainerLastFocusedElement(null, ["indicator-GridListContainer"]);
if (themeProductInfos && themeProductInfos.length > 0) {
dispatch(clearThemeDetail());
}
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: {
patnrId,
prdtId,
launchedFromPlayer: launchedFromPlayer,
},
})
);
cursorOpen.current.stop();
};
return (
<TItemCard
{...rest}
key={prdtId}
contextName={Config.LOG_CONTEXT_NAME.YOUMAYLIKE}
messageId={Config.LOG_MESSAGE_ID.CONTENTCLICK}
productId={prdtId}
productTitle={prdtNm}
nowProductId={productInfo?.prdtId}
nowProductTitle={productInfo?.prdtNm}
nowCategory={productInfo?.catNm}
catNm={lgCatNm}
patnerName={patncNm}
brandName={brndNm}
imageAlt={prdtId}
imageSource={imgUrl}
priceInfo={priceInfo}
offerInfo={offerInfo}
productName={prdtNm}
onClick={handleItemClick}
label={index * 1 + 1 + " of " + youmaylikeData.length}
lastLabel=" go to detail, button"
/>
);
},
[youmaylikeData, launchedFromPlayer]
);
return (
<>
<Container
className={classNames(
css.container,
isUnable && css.unable,
expanded && css.expanded,
focused && css.focused
)}
spotlightRestrict="self-only"
onFocus={cursorVisibleOnFocus}
onBlur={cursorVisibleOnBlur}
>
<SpottableComponent
className={classNames(css.button, focused && css.focused)}
onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
onClick={onButtonClick}
aria-label={
(expanded === false ? "Open " : "Close ") + "YOU MAY LIKE, button"
}
>
{$L("You may also like")}
<span className={classNames(css.arrow, expanded && css.expanded)} />
</SpottableComponent>
<Container className={css.itemWrap}>
{youmaylikeData && youmaylikeData.length > 0 && (
<TVirtualGridList
cbScrollTo={getScrollTo}
dataSize={youmaylikeData.length}
direction="horizontal"
autoScroll
renderItem={renderItem}
itemWidth={324}
itemHeight={438}
spacing={15}
className={css.itemList}
/>
)}
</Container>
{expanded && (
<Container className={css.extraArea} onClick={onClickExtraArea} />
)}
</Container>
</>
);
});