[251209] feat: NBCU-ShopByShow-4
🕐 커밋 시간: 2025. 12. 09. 16:19:54 📊 변경 통계: • 총 파일: 5개 • 추가: +62줄 • 삭제: -139줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/hooks/useScrollTo.js ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.jsx ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.module.less 🗑️ 삭제된 파일: - com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx - com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 소규모 기능 개선 • 코드 정리 및 최적화 Performance: 코드 최적화로 성능 개선 기대
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useRef } from "react";
|
import React, { useCallback, useEffect, useRef } from "react";
|
||||||
|
|
||||||
export default function useScrollTo() {
|
export default function useScrollTo({ skipAutoScrollTop = false } = {}) {
|
||||||
const scrollTo = useRef();
|
const scrollTo = useRef();
|
||||||
|
|
||||||
const scrollTop = useCallback(
|
const scrollTop = useCallback(
|
||||||
@@ -23,8 +23,10 @@ export default function useScrollTo() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!skipAutoScrollTop) {
|
||||||
scrollTop();
|
scrollTop();
|
||||||
}, []);
|
}
|
||||||
|
}, [skipAutoScrollTop]);
|
||||||
|
|
||||||
return { getScrollTo, scrollLeft, scrollTop, scrollToRef: scrollTo };
|
return { getScrollTo, scrollLeft, scrollTop, scrollToRef: scrollTo };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import React, { memo, useCallback, useState } from "react";
|
import React, { memo, useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import { getBrandShopByShow } from "../../../actions/brandActions";
|
||||||
|
|
||||||
|
import { Job } from "@enact/core/util";
|
||||||
import Spotlight from "@enact/spotlight";
|
import Spotlight from "@enact/spotlight";
|
||||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||||
|
|
||||||
|
import useScrollTo from "../../../hooks/useScrollTo";
|
||||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||||
import { $L } from "../../../utils/helperMethods";
|
import { $L } from "../../../utils/helperMethods";
|
||||||
import css from "./ShopByShow.module.less";
|
import css from "./ShopByShow.module.less";
|
||||||
import ShopByShowList from "./ShopByShowList/ShopByShowList";
|
import ShopByShowNav from "./ShopByShowList/ShopByShowNav/ShopByShowNav";
|
||||||
|
import ShopByShowContents from "./ShopByShowList/ShopByShowContents/ShopByShowContents";
|
||||||
|
|
||||||
const STRING_CONF = {
|
const STRING_CONF = {
|
||||||
SHOP_BY_SHOW: "SHOP BY SHOW",
|
SHOP_BY_SHOW: "SHOP BY SHOW",
|
||||||
@@ -28,6 +35,33 @@ const ShopByShow = ({
|
|||||||
shelfTitle,
|
shelfTitle,
|
||||||
}) => {
|
}) => {
|
||||||
const [firstChk, setFirstChk] = useState(0);
|
const [firstChk, setFirstChk] = useState(0);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { getScrollTo, scrollLeft } = useScrollTo({ skipAutoScrollTop: true });
|
||||||
|
const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);
|
||||||
|
const scrollLeftJob = useRef(new Job((func) => func(), 0));
|
||||||
|
|
||||||
|
const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || [];
|
||||||
|
|
||||||
|
const handleContsIdChange = useCallback((contsId) => {
|
||||||
|
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId }));
|
||||||
|
}, [selectedPatnrId, dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollLeftJobValue = scrollLeftJob.current;
|
||||||
|
const { x } = panelInfo;
|
||||||
|
|
||||||
|
scrollLeftJobValue.start(() => scrollLeft({ x }));
|
||||||
|
|
||||||
|
return () => scrollLeftJobValue.stop();
|
||||||
|
}, [panelInfo, scrollLeft]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
scrollLeft();
|
||||||
|
}, [scrollLeft, selectedPatnrId]);
|
||||||
|
|
||||||
const _handleItemFocus = useCallback(() => {
|
const _handleItemFocus = useCallback(() => {
|
||||||
if (handleItemFocus) handleItemFocus(spotlightId, shelfOrder);
|
if (handleItemFocus) handleItemFocus(spotlightId, shelfOrder);
|
||||||
@@ -70,15 +104,27 @@ const ShopByShow = ({
|
|||||||
data-title="shop-by-show"
|
data-title="shop-by-show"
|
||||||
label="shop-by-show Heading 1"
|
label="shop-by-show Heading 1"
|
||||||
/>
|
/>
|
||||||
<ShopByShowList
|
<ShopByShowNav
|
||||||
brandShopByShowContsList={brandShopByShowContsList}
|
brandShopByShowContsList={brandShopByShowContsList}
|
||||||
brandShopByShowContsInfo={brandShopByShowContsInfo}
|
brandShopByShowContsInfo={brandShopByShowContsInfo}
|
||||||
handleItemFocus={_handleItemFocus}
|
handleItemFocus={_handleItemFocus}
|
||||||
|
onContsIdChange={handleContsIdChange}
|
||||||
|
/>
|
||||||
|
{brandShopByShowClctInfos.map((collection, collIdx) => (
|
||||||
|
<ShopByShowContents
|
||||||
|
key={`${spotlightId}-${collIdx}`}
|
||||||
|
brandProductInfos={collection.brandProductInfos}
|
||||||
|
contentsIndex={collIdx}
|
||||||
|
handleItemFocus={_handleItemFocus}
|
||||||
|
clctNm={collection.clctNm}
|
||||||
|
clctImgUrl={collection.clctImgUrl}
|
||||||
|
patnrId={selectedPatnrId}
|
||||||
selectedPatnrId={selectedPatnrId}
|
selectedPatnrId={selectedPatnrId}
|
||||||
spotlightId={spotlightId}
|
|
||||||
shelfOrder={shelfOrder}
|
shelfOrder={shelfOrder}
|
||||||
shelfTitle={shelfTitle}
|
shelfTitle={shelfTitle}
|
||||||
|
spotlightId={spotlightId}
|
||||||
/>
|
/>
|
||||||
|
))}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,4 +9,8 @@
|
|||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
padding-left: 60px;
|
padding-left: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> nav {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
import React, {
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
import {
|
|
||||||
useDispatch,
|
|
||||||
useSelector,
|
|
||||||
} from 'react-redux';
|
|
||||||
|
|
||||||
import { Job } from '@enact/core/util';
|
|
||||||
import SpotlightContainerDecorator
|
|
||||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
|
||||||
import {
|
|
||||||
getContainerId,
|
|
||||||
setContainerLastFocusedElement,
|
|
||||||
} from '@enact/spotlight/src/container';
|
|
||||||
|
|
||||||
import { getBrandShopByShow } from '../../../../actions/brandActions';
|
|
||||||
import useScrollTo from '../../../../hooks/useScrollTo';
|
|
||||||
import css from './ShopByShowList.module.less';
|
|
||||||
import ShopByShowNav from './ShopByShowNav/ShopByShowNav';
|
|
||||||
import ShopByShowContents from './ShopByShowContents/ShopByShowContents';
|
|
||||||
|
|
||||||
const Container = SpotlightContainerDecorator(
|
|
||||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
|
||||||
"div"
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function ShopByShowList({
|
|
||||||
brandShopByShowContsList,
|
|
||||||
brandShopByShowContsInfo,
|
|
||||||
handleItemFocus,
|
|
||||||
selectedPatnrId,
|
|
||||||
spotlightId,
|
|
||||||
shelfTitle,
|
|
||||||
shelfOrder,
|
|
||||||
}) {
|
|
||||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);
|
|
||||||
const scrollLeftJob = useRef(new Job((func) => func(), 0));
|
|
||||||
|
|
||||||
const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || [];
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollLeftJobValue = scrollLeftJob.current;
|
|
||||||
const { x } = panelInfo;
|
|
||||||
|
|
||||||
scrollLeftJobValue.start(() => scrollLeft({ x }));
|
|
||||||
|
|
||||||
return () => scrollLeftJobValue.stop();
|
|
||||||
}, [panelInfo, scrollLeft]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const containerId = "shop-by-show-list-id";
|
|
||||||
const container = document.getElementById(containerId);
|
|
||||||
|
|
||||||
if (container) {
|
|
||||||
const childrenId = getContainerId(container?.children[0].children[0]);
|
|
||||||
|
|
||||||
if (childrenId) {
|
|
||||||
setContainerLastFocusedElement(null, [containerId, childrenId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollLeft();
|
|
||||||
}, [scrollLeft, selectedPatnrId]);
|
|
||||||
|
|
||||||
const handleContsIdChange = useCallback((contsId) => {
|
|
||||||
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId }));
|
|
||||||
}, [selectedPatnrId, dispatch]);
|
|
||||||
|
|
||||||
const _handleItemFocus = useCallback(() => {
|
|
||||||
if (handleItemFocus) {
|
|
||||||
handleItemFocus();
|
|
||||||
}
|
|
||||||
}, [handleItemFocus]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Container
|
|
||||||
className={css.container}
|
|
||||||
id={"shop-by-show-list-id"}
|
|
||||||
spotlightId={"shop-by-show-list-id"}
|
|
||||||
>
|
|
||||||
<ShopByShowNav
|
|
||||||
brandShopByShowContsList={brandShopByShowContsList}
|
|
||||||
brandShopByShowContsInfo={brandShopByShowContsInfo}
|
|
||||||
handleItemFocus={_handleItemFocus}
|
|
||||||
onContsIdChange={handleContsIdChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{brandShopByShowClctInfos.map((collection, collIdx) => (
|
|
||||||
<ShopByShowContents
|
|
||||||
key={`${spotlightId}-${collIdx}`}
|
|
||||||
brandProductInfos={collection.brandProductInfos}
|
|
||||||
contentsIndex={collIdx}
|
|
||||||
handleItemFocus={_handleItemFocus}
|
|
||||||
clctNm={collection.clctNm}
|
|
||||||
clctImgUrl={collection.clctImgUrl}
|
|
||||||
patnrId={selectedPatnrId}
|
|
||||||
selectedPatnrId={selectedPatnrId}
|
|
||||||
shelfOrder={shelfOrder}
|
|
||||||
shelfTitle={shelfTitle}
|
|
||||||
spotlightId={spotlightId}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
@import "../../../../style/CommonStyle.module.less";
|
|
||||||
@import "../../../../style/utils.module.less";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
> nav {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user