[251008] feat v2 탭 컨테이너 추가 및 UI 조정

v2 탭 컨테이너를 도입하고, 아이템 크기와 간격을 조정해 UI를 개선했습니다.

🕐 커밋 시간: 2025. 10. 08. 21:38:17

📊 변경 통계:
  • 총 파일: 11개
  • 추가: +56줄
  • 삭제: -22줄

📁 추가된 파일:
  + com.twin.app.shoptime/src/components/TItemCard/TItemCard.v2.module.less
  + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.v2.module.less
  + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/YouMayLikeContents.v2.module.less
  + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx
  + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.module.less

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/components/TItemCard/TItemCard.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/LiveChannelContents.v2.module.less
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/YouMayLikeContents.jsx

🔧 주요 변경 내용:
  • UI 컴포넌트 아키텍처 개선
  • 소규모 기능 개선
  • 모듈 구조 개선
This commit is contained in:
2025-10-08 21:38:22 +09:00
parent a8289c905e
commit 7f66fd9735
11 changed files with 581 additions and 22 deletions

View File

@@ -0,0 +1,156 @@
import React, { useCallback, useEffect } from "react";
import classNames from "classnames";
import Spotlight from "@enact/spotlight";
import Spottable from "@enact/spotlight/Spottable";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { LOG_MENU } from "../../../../utils/Config";
import css from "./TabContainer.v2.module.less";
import LiveChannelContents from "../TabContents/LiveChannelContents";
import ShopNowContents from "../TabContents/ShopNowContents";
import YouMayLikeContents from "../TabContents/YouMayLikeContents";
import ShopNowButton from "./ShopNowButton";
import icon_arrow_dwon from "../../../../../assets/images/player/icon_tabcontainer_arrow_down.png";
import icon_shop_now from "../../../../../assets/images/player/icon_tabcontainer_shopnow.png";
const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused" },
"div"
);
const SpottableDiv = Spottable("div");
export default function TabContainerV2({
panelInfo,
playListInfo,
shopNowInfo,
selectedIndex,
setSelectedIndex,
liveChannelInfos,
videoVerticalVisible,
handleItemFocus,
prevChannelIndex,
currentTime,
spotlightId,
tabIndex = 1, // tabIndex prop으로 제어 (0: ShopNow, 1: LiveChannel, 2: ShopNowButton)
onShopNowButtonClick,
onLiveChannelButtonClick,
}) {
useEffect(() => {
let nowMenu;
if (tabIndex === 0) {
nowMenu = LOG_MENU.FULL_SHOP_NOW;
}
if (tabIndex === 1) {
const isLive = panelInfo?.shptmBanrTpNm === "LIVE";
nowMenu = isLive
? LOG_MENU.FULL_LIVE_CHANNELS
: LOG_MENU.FULL_FEATURED_SHOWS;
}
if (nowMenu) {
handleItemFocus(nowMenu);
}
}, [handleItemFocus, panelInfo?.shptmBanrTpNm, tabIndex]);
const _handleItemFocus = useCallback(
(nowMenu) => {
if (handleItemFocus) {
handleItemFocus(nowMenu);
}
},
[handleItemFocus]
);
const onSpotlightIndicatorUpButton = useCallback(
(e) => {
if (videoVerticalVisible) {
e.stopPropagation();
e.preventDefault();
Spotlight.focus("spotlightId-video-contaienr");
}
},
[videoVerticalVisible]
);
return (
<Container
className={classNames(
css.tabContainer,
videoVerticalVisible && css.vertical,
css[`tabIndex${tabIndex}`]
)}
spotlightId={spotlightId}
>
{tabIndex === 0 && (
<>
<div className={css.shopNowHeader}>
<div className={css.shopNowIconWrapper}>
<img src={icon_shop_now} alt="shop now icon" className={css.shopNowIcon} />
</div>
<div className={css.shopNowHeaderText}>SHOP NOW</div>
</div>
<ShopNowContents
shopNowInfo={shopNowInfo}
playListInfo={playListInfo && playListInfo[selectedIndex]}
videoVerticalVisible={videoVerticalVisible}
panelInfo={panelInfo}
tabIndex={tabIndex}
handleItemFocus={_handleItemFocus}
version={2}
direction="horizontal"
/>
</>
)}
{tabIndex === 1 && (
<>
<SpottableDiv
className={css.liveChannelButton}
onClick={onLiveChannelButtonClick}
spotlightId="below-tab-live-channel-button"
>
<span className={css.buttonText}>LIVE CHANNEL</span>
<div className={css.arrowIcon}>
<img src={icon_arrow_dwon} alt="arrow down" />
</div>
</SpottableDiv>
{panelInfo?.shptmBanrTpNm === "LIVE" && playListInfo && (
<LiveChannelContents
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
videoVerticalVisible={videoVerticalVisible}
currentVideoShowId={playListInfo[selectedIndex]?.showId}
liveInfos={playListInfo}
tabIndex={tabIndex}
handleItemFocus={_handleItemFocus}
panelInfo={panelInfo}
currentTime={currentTime}
version={2}
direction="horizontal"
/>
)}
</>
)}
{tabIndex === 2 && (
<ShopNowButton onClick={onShopNowButtonClick} />
)}
{shopNowInfo && shopNowInfo.length < 3 && tabIndex === 0 && (
<YouMayLikeContents
shopNowInfo={shopNowInfo}
handleItemFocus={_handleItemFocus}
playListInfo={playListInfo && playListInfo[selectedIndex]}
version={2}
direction="horizontal"
/>
)}
</Container>
);
}