[251115] fix: DetailPanel FullScreen Focus Move
🕐 커밋 시간: 2025. 11. 15. 22:03:44 📊 변경 통계: • 총 파일: 17개 • 추가: +573줄 • 삭제: -87줄 📁 추가된 파일: + com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/MediaOverlayContents.jsx 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/panelActions.js ~ com.twin.app.shoptime/src/components/MediaPlayer/MediaControls.js ~ com.twin.app.shoptime/src/components/VideoPlayer/MediaPlayer.module.less ~ com.twin.app.shoptime/src/components/VideoPlayer/MediaPlayer.v2.jsx ~ com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.js ~ com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.module.less ~ com.twin.app.shoptime/src/utils/SpotlightIds.js ~ com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx ~ com.twin.app.shoptime/src/views/HomePanel/EventPopUpBanner/EventPopUpBanner.jsx ~ com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx ~ com.twin.app.shoptime/src/views/HomePanel/PickedForYou/PickedForYou.jsx ~ com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx ~ com.twin.app.shoptime/src/views/MainView/MainView.jsx ~ com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx ~ com.twin.app.shoptime/src/views/SearchPanel/SearchResultsNew/ItemCard.jsx 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/actions/panelActions.js (javascript): ✅ Added: updatePanel() 📄 com.twin.app.shoptime/src/components/MediaPlayer/MediaControls.js (javascript): ✅ Added: onSpotlightRight(), onSpotlightUp(), MediaControlsDecoratorHOC(), handleCancel() ❌ Deleted: onSpotlightRight(), onSpotlightUp(), MediaControlsDecoratorHOC(), handleCancel() 📄 com.twin.app.shoptime/src/components/VideoPlayer/MediaPlayer.v2.jsx (javascript): 🔄 Modified: SpotlightContainerDecorator() 📄 com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.v3.module.less (unknown): ✅ Added: position() ❌ Deleted: position() 📄 com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RandomUnit.jsx (javascript): 🔄 Modified: SpotlightContainerDecorator() 📄 com.twin.app.shoptime/src/views/HomePanel/SubCategory/SubCategory.jsx (javascript): 🔄 Modified: getExpsOrdByLgCatCd() 📄 com.twin.app.shoptime/src/views/MediaPanel/MediaPanel.v3.jsx (javascript): 🔄 Modified: normalizeModalStyle() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/PlayerOverlayContents.jsx (javascript): 🔄 Modified: SpotlightContainerDecorator(), PlayerOverlayContents() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerOverlay/MediaOverlayContents.jsx (javascript): ✅ Added: MediaOverlayContents() 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • UI 컴포넌트 아키텍처 개선 • 공통 유틸리티 함수 최적화
This commit is contained in:
@@ -1,28 +1,13 @@
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import {
|
||||
SpotlightContainerDecorator,
|
||||
} from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import { SpotlightContainerDecorator } from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import {
|
||||
pushPanel,
|
||||
updatePanel,
|
||||
} from '../../../actions/panelActions';
|
||||
import {
|
||||
navigateToDetailFromHome,
|
||||
} from '../../../actions/panelNavigationActions';
|
||||
import { pushPanel, updatePanel, navigateFromBestSeller } from '../../../actions/panelActions';
|
||||
import { navigateToDetailFromHome } from '../../../actions/panelNavigationActions';
|
||||
import SectionTitle from '../../../components/SectionTitle/SectionTitle';
|
||||
import Tag from '../../../components/TItemCard/Tag';
|
||||
import TItemCard from '../../../components/TItemCard/TItemCard';
|
||||
@@ -30,23 +15,13 @@ import TItemCardNew from '../../../components/TItemCard/TItemCard.new';
|
||||
import TScroller from '../../../components/TScroller/TScroller';
|
||||
import useScrollReset from '../../../hooks/useScrollReset';
|
||||
import useScrollTo from '../../../hooks/useScrollTo';
|
||||
import {
|
||||
LOG_CONTEXT_NAME,
|
||||
LOG_MESSAGE_ID,
|
||||
panel_names,
|
||||
} from '../../../utils/Config';
|
||||
import {
|
||||
$L,
|
||||
scaleW,
|
||||
} from '../../../utils/helperMethods';
|
||||
import { LOG_CONTEXT_NAME, LOG_MESSAGE_ID, panel_names } from '../../../utils/Config';
|
||||
import { $L, scaleW } from '../../../utils/helperMethods';
|
||||
import { SpotlightIds } from '../../../utils/SpotlightIds';
|
||||
import css from './BestSeller.module.less';
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
const SpottableComponent = Spottable('div');
|
||||
const Container = SpotlightContainerDecorator({ enterTo: 'last-focused' }, 'div');
|
||||
|
||||
const BestSeller = ({
|
||||
order,
|
||||
@@ -58,25 +33,15 @@ const BestSeller = ({
|
||||
shelfTitle,
|
||||
}) => {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
const { handleScrollReset, handleStopScrolling } = useScrollReset(
|
||||
scrollLeft,
|
||||
true
|
||||
);
|
||||
const { handleScrollReset, handleStopScrolling } = useScrollReset(scrollLeft, true);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { cursorVisible } = useSelector((state) => state.common.appStatus);
|
||||
|
||||
const bestSellerDatas = useSelector(
|
||||
(state) => state.product.bestSellerData?.bestSeller
|
||||
);
|
||||
|
||||
const bestSellerNewDatas = useSelector(
|
||||
(state) =>
|
||||
state.foryou?.recommendInfo?.recommendProduct
|
||||
);
|
||||
|
||||
const bestSellerDatas = useSelector((state) => state.product.bestSellerData?.bestSeller);
|
||||
|
||||
const bestSellerNewDatas = useSelector((state) => state.foryou?.recommendInfo?.recommendProduct);
|
||||
|
||||
const [drawChk, setDrawChk] = useState(false);
|
||||
const [firstChk, setFirstChk] = useState(0);
|
||||
@@ -84,59 +49,57 @@ const BestSeller = ({
|
||||
const [bestInfos, setBestInfos] = useState(null);
|
||||
const [bestItemNewData, setBestItemNewData] = useState([]);
|
||||
|
||||
useEffect(()=>{
|
||||
useEffect(() => {
|
||||
setBestInfos(
|
||||
bestSellerNewDatas?.filter(
|
||||
(item) => item.recommendTpCd === "BESTSELLER"
|
||||
) || [] // 기본값으로 빈 배열 설정
|
||||
)
|
||||
},[bestSellerNewDatas])
|
||||
bestSellerNewDatas?.filter((item) => item.recommendTpCd === 'BESTSELLER') || [] // 기본값으로 빈 배열 설정
|
||||
);
|
||||
}, [bestSellerNewDatas]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!bestInfos || bestInfos.length === 0) {
|
||||
const baseData = bestSellerDatas?.map((item) => ({
|
||||
...item,
|
||||
foryou: false,
|
||||
})) || [];
|
||||
const baseData =
|
||||
bestSellerDatas?.map((item) => ({
|
||||
...item,
|
||||
foryou: false,
|
||||
})) || [];
|
||||
setBestItemNewData(baseData);
|
||||
return;
|
||||
}
|
||||
|
||||
const recommendedData = bestInfos[0].productInfos?.map((item) => ({
|
||||
...item,
|
||||
foryou: true,
|
||||
})) || [];
|
||||
|
||||
const recommendedPrdtIds = new Set(recommendedData.map(item => item.prdtId));
|
||||
|
||||
const baseData = bestSellerDatas?.map((item) => ({
|
||||
...item,
|
||||
foryou: recommendedPrdtIds.has(item.prdtId),
|
||||
})) || [];
|
||||
|
||||
|
||||
const recommendedData =
|
||||
bestInfos[0].productInfos?.map((item) => ({
|
||||
...item,
|
||||
foryou: true,
|
||||
})) || [];
|
||||
|
||||
const recommendedPrdtIds = new Set(recommendedData.map((item) => item.prdtId));
|
||||
|
||||
const baseData =
|
||||
bestSellerDatas?.map((item) => ({
|
||||
...item,
|
||||
foryou: recommendedPrdtIds.has(item.prdtId),
|
||||
})) || [];
|
||||
|
||||
setBestItemNewData(baseData);
|
||||
}, [bestSellerDatas, bestInfos]);
|
||||
|
||||
const orderStyle = useMemo(() => ({ order: order }), [order]);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
setDrawChk(true);
|
||||
}, [bestSellerNewDatas]);
|
||||
|
||||
const handleCardClick = useCallback(
|
||||
(patnrId, prdtId) => () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: {
|
||||
patnrId: patnrId,
|
||||
prdtId: prdtId,
|
||||
nowShelf: spotlightId,
|
||||
},
|
||||
navigateFromBestSeller({
|
||||
patnrId,
|
||||
prdtId,
|
||||
spotlightId,
|
||||
})
|
||||
);
|
||||
},
|
||||
[dispatch]
|
||||
[dispatch, spotlightId]
|
||||
);
|
||||
|
||||
const handleMoreCardClick = useCallback(() => {
|
||||
@@ -144,7 +107,7 @@ const BestSeller = ({
|
||||
pushPanel({
|
||||
name: panel_names.TRENDING_NOW_PANEL,
|
||||
panelInfo: {
|
||||
pageName: "BS",
|
||||
pageName: 'BS',
|
||||
focusedContainerId: SpotlightIds.TRENDING_NOW_BEST_SELLER,
|
||||
},
|
||||
})
|
||||
@@ -171,21 +134,18 @@ const BestSeller = ({
|
||||
if (firstChk === 0 && itemIndex === 0) {
|
||||
const c = Spotlight.getCurrent();
|
||||
if (c) {
|
||||
let cAriaLabel = c.getAttribute("aria-label");
|
||||
cAriaLabel = "Best Seller, Heading 1," + cAriaLabel;
|
||||
c.setAttribute("aria-label", cAriaLabel);
|
||||
let cAriaLabel = c.getAttribute('aria-label');
|
||||
cAriaLabel = 'Best Seller, Heading 1,' + cAriaLabel;
|
||||
c.setAttribute('aria-label', cAriaLabel);
|
||||
}
|
||||
setFirstChk(1);
|
||||
} else if (firstChk === 1 && itemIndex === 0) {
|
||||
const c = Spotlight.getCurrent();
|
||||
if (c) {
|
||||
let cAriaLabel = c.getAttribute("aria-label");
|
||||
let cAriaLabel = c.getAttribute('aria-label');
|
||||
if (cAriaLabel) {
|
||||
const newcAriaLabel = cAriaLabel.replace(
|
||||
"Best Seller, Heading 1,",
|
||||
""
|
||||
);
|
||||
c.setAttribute("aria-label", newcAriaLabel);
|
||||
const newcAriaLabel = cAriaLabel.replace('Best Seller, Heading 1,', '');
|
||||
c.setAttribute('aria-label', newcAriaLabel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -219,7 +179,6 @@ const BestSeller = ({
|
||||
handleShelfFocus();
|
||||
}
|
||||
}, [handleShelfFocus]);
|
||||
|
||||
|
||||
return (
|
||||
<Container
|
||||
@@ -230,7 +189,7 @@ const BestSeller = ({
|
||||
onFocus={_handleShelfFocus}
|
||||
>
|
||||
<SectionTitle
|
||||
title={$L("BEST SELLER")}
|
||||
title={$L('BEST SELLER')}
|
||||
data-title-index="homeBestSellerTitle"
|
||||
label="BEST SELLER"
|
||||
/>
|
||||
@@ -262,15 +221,15 @@ const BestSeller = ({
|
||||
) => {
|
||||
const rankText =
|
||||
rankOrd === 1
|
||||
? rankOrd + "st"
|
||||
? rankOrd + 'st'
|
||||
: rankOrd === 2
|
||||
? rankOrd + "nd"
|
||||
? rankOrd + 'nd'
|
||||
: rankOrd === 3
|
||||
? rankOrd + "rd"
|
||||
: rankOrd + "th";
|
||||
? rankOrd + 'rd'
|
||||
: rankOrd + 'th';
|
||||
return (
|
||||
<TItemCardNew
|
||||
key={"subItem" + itemIndex}
|
||||
key={'subItem' + itemIndex}
|
||||
contextName={LOG_CONTEXT_NAME.HOME}
|
||||
messageId={LOG_MESSAGE_ID.SHELF_CLICK}
|
||||
order={itemIndex + 1}
|
||||
@@ -291,13 +250,13 @@ const BestSeller = ({
|
||||
onBlur={handleBlur(itemIndex)}
|
||||
onClick={handleCardClick(patnrId, prdtId)}
|
||||
offerInfo={offerInfo}
|
||||
spotlightId={"bestsellerItem" + itemIndex}
|
||||
spotlightId={'bestsellerItem' + itemIndex}
|
||||
firstLabel={rankText}
|
||||
label={itemIndex * 1 + 1 + " of " + bestItemNewData.length}
|
||||
label={itemIndex * 1 + 1 + ' of ' + bestItemNewData.length}
|
||||
lastLabel=" go to detail, button"
|
||||
euEnrgLblInfos={euEnrgLblInfos}
|
||||
>
|
||||
{foryou === true && <Tag text={"For You"} />}
|
||||
{foryou === true && <Tag text={'For You'} />}
|
||||
</TItemCardNew>
|
||||
);
|
||||
}
|
||||
@@ -308,7 +267,7 @@ const BestSeller = ({
|
||||
<SpottableComponent
|
||||
className={css.displayBox}
|
||||
onClick={handleMoreCardClick}
|
||||
spotlightId={"bestseller-item-more-btn"}
|
||||
spotlightId={'bestseller-item-more-btn'}
|
||||
aria-label="See more button"
|
||||
></SpottableComponent>
|
||||
</div>
|
||||
@@ -318,4 +277,4 @@ const BestSeller = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default BestSeller;
|
||||
export default BestSeller;
|
||||
|
||||
Reference in New Issue
Block a user