[251006] feat: views - PlayerPanel.jsx, LiveShowContainer.jsx, LiveSho...
🕐 커밋 시간: 2025. 10. 06. 17:12:55 📊 변경 통계: • 총 파일: 7개 • 추가: +33줄 • 삭제: -15줄 📁 추가된 파일: + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/LiveShowContainer.jsx + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/LiveShowContainer.module.less + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowButton.jsx + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowButton.module.less + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowContainer.jsx + com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowContainer.module.less 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/LiveShowContainer.module.less (unknown): ✅ Added: position(), gradient(), focused() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowButton.module.less (unknown): ✅ Added: position(), gradient(), focused() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowContainer.module.less (unknown): ✅ Added: position(), gradient()
This commit is contained in:
@@ -55,7 +55,9 @@ import PlayerOverlayQRCode from './PlayerOverlay/PlayerOverlayQRCode';
|
||||
import css from './PlayerPanel.module.less';
|
||||
import PlayerTabButton from './PlayerTabContents/TabButton/PlayerTabButton';
|
||||
import TabContainer from './PlayerTabContents/TabContainer';
|
||||
import BelowTabContainer from './PlayerTabContents/v2/BelowTabContainer';
|
||||
import LiveShowContainer from './PlayerTabContents/v2/LiveShowContainer';
|
||||
import ShopNowContainer from './PlayerTabContents/v2/ShopNowContainer';
|
||||
import ShopNowButton from './PlayerTabContents/v2/ShopNowButton';
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: 'default-element', preserveld: true },
|
||||
@@ -200,6 +202,7 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
isDetailMediaReady: false,
|
||||
});
|
||||
const [isVODPaused, setIsVODPaused] = USE_STATE('isVODPaused', false);
|
||||
const [belowTabMode, setBelowTabMode] = USE_STATE('belowTabMode', 'liveShow');
|
||||
|
||||
const panels = USE_SELECTOR('panels', (state) => state.panels.panels);
|
||||
const chatData = USE_SELECTOR('chatData', (state) => state.play.chatData);
|
||||
@@ -2057,20 +2060,35 @@ const PlayerPanel = ({ isTabActivated, panelInfo, isOnTop, spotlightId, ...props
|
||||
/>
|
||||
)}
|
||||
|
||||
{showBelowContents && (
|
||||
<BelowTabContainer
|
||||
panelInfo={panelInfo}
|
||||
liveInfos={playListInfo}
|
||||
currentTime={currentTime}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
videoVerticalVisible={videoVerticalVisible}
|
||||
currentVideoShowId={playListInfo && playListInfo[selectedIndex]?.showId}
|
||||
handleItemFocus={handleItemFocus}
|
||||
tabTitle={[
|
||||
$L('SHOP NOW'),
|
||||
panelInfo?.shptmBanrTpNm === 'LIVE' ? $L('LIVE CHANNEL') : $L('FEATURED SHOWS'),
|
||||
]}
|
||||
/>
|
||||
{!panelInfo?.modal && (
|
||||
<>
|
||||
{belowTabMode === 'liveShow' && (
|
||||
<LiveShowContainer
|
||||
panelInfo={panelInfo}
|
||||
liveInfos={playListInfo}
|
||||
currentTime={currentTime}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
videoVerticalVisible={videoVerticalVisible}
|
||||
currentVideoShowId={playListInfo && playListInfo[selectedIndex]?.showId}
|
||||
handleItemFocus={handleItemFocus}
|
||||
onLiveChannelButtonClick={() => setBelowTabMode('shopNowButton')}
|
||||
/>
|
||||
)}
|
||||
{belowTabMode === 'shopNowButton' && (
|
||||
<ShopNowButton onClick={() => setBelowTabMode('shopNow')} />
|
||||
)}
|
||||
{belowTabMode === 'shopNow' && (
|
||||
<ShopNowContainer
|
||||
panelInfo={panelInfo}
|
||||
liveInfos={playListInfo}
|
||||
currentTime={currentTime}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
videoVerticalVisible={videoVerticalVisible}
|
||||
currentVideoShowId={playListInfo && playListInfo[selectedIndex]?.showId}
|
||||
handleItemFocus={handleItemFocus}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from './LiveShowContainer.module.less';
|
||||
import icon_arrow_dwon from '../../../../../assets/images/player/icon_tabcontainer_arrow_down.png';
|
||||
import LiveChannelContents from './LiveChannelContents';
|
||||
|
||||
const SpottableDiv = Spottable('div');
|
||||
|
||||
export default function LiveShowContainer({
|
||||
liveInfos,
|
||||
currentTime,
|
||||
setSelectedIndex,
|
||||
videoVerticalVisible,
|
||||
currentVideoShowId,
|
||||
handleItemFocus,
|
||||
tabTitle,
|
||||
panelInfo,
|
||||
onLiveChannelButtonClick,
|
||||
}) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<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>
|
||||
|
||||
<LiveChannelContents
|
||||
liveInfos={liveInfos}
|
||||
currentTime={currentTime}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
videoVerticalVisible={videoVerticalVisible}
|
||||
currentVideoShowId={currentVideoShowId}
|
||||
handleItemFocus={handleItemFocus}
|
||||
tabTitle={tabTitle}
|
||||
panelInfo={panelInfo}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.size(@w: 100%, @h: 365px);
|
||||
.position(@position: fixed, @bottom: 0, @left: 0);
|
||||
padding: 60px;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.95) 0%,
|
||||
rgba(0, 0, 0, 0.85) 40%,
|
||||
rgba(0, 0, 0, 0.6) 70%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
border-top: 1px solid rgba(234, 234, 234, 0.3);
|
||||
overflow: hidden;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column);
|
||||
z-index: 5;
|
||||
|
||||
> * + * {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
.position(@position: absolute, @top: 0, @left: 0);
|
||||
.size(@w: 100%, @h: 100%);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(30, 30, 30, 0.4) 0%,
|
||||
rgba(50, 50, 50, 0.25) 30%,
|
||||
transparent 50%,
|
||||
rgba(50, 50, 50, 0.25) 70%,
|
||||
rgba(30, 30, 30, 0.4) 100%
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.liveChannelButton {
|
||||
.size(@w: 300px, @h: 70px);
|
||||
padding: 20px 30px;
|
||||
border-radius: 100px;
|
||||
border: 1px solid rgba(234, 234, 234, 0.5);
|
||||
overflow: hidden;
|
||||
.flex(@display: flex, @justifyCenter: space-between, @alignCenter: center);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(5px);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.buttonText {
|
||||
color: @COLOR_WHITE;
|
||||
font-size: 24px;
|
||||
font-family: @baseFont;
|
||||
font-weight: 600;
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
.arrowIcon {
|
||||
.size(@w: 26.25px, @h: 15.63px);
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-color: rgba(234, 234, 234, 0.7);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(199, 8, 80, 0.2);
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 100px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.channelList {
|
||||
width: 100%;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start);
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
> * + * {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.channelCard {
|
||||
.size(@w: 470px, @h: 155px);
|
||||
padding: 18px;
|
||||
background: rgba(44, 44, 44, 0.85);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
flex-shrink: 0;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
> * + * {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
flex: 1 1 0;
|
||||
.size(@w: 212px, @h: 119px);
|
||||
overflow: hidden;
|
||||
.flex(@display: flex, @justifyCenter: center, @alignCenter: center);
|
||||
|
||||
> img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
flex: 1 1 0;
|
||||
height: 110px;
|
||||
.flex(@display: flex, @justifyCenter: space-between, @alignCenter: flex-start, @direction: column);
|
||||
|
||||
.channelHeader {
|
||||
width: 100%;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: center);
|
||||
|
||||
> * + * {
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.logoWrapper {
|
||||
.size(@w: 40px, @h: 40px);
|
||||
border-radius: 100px;
|
||||
.position(@position: relative);
|
||||
overflow: hidden;
|
||||
.flex(@display: flex, @justifyCenter: center, @alignCenter: center);
|
||||
|
||||
.logo {
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.channelName {
|
||||
color: #EAEAEA;
|
||||
font-size: 24px;
|
||||
font-family: @baseFont;
|
||||
font-weight: 700;
|
||||
line-height: 31px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.programName {
|
||||
width: 100%;
|
||||
color: #EAEAEA;
|
||||
font-size: 24px;
|
||||
font-family: @baseFont;
|
||||
font-weight: 400;
|
||||
line-height: 31px;
|
||||
.elip(@clamp: 1);
|
||||
}
|
||||
|
||||
.progressBarWrapper {
|
||||
width: 100%;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start);
|
||||
|
||||
> * + * {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.progressBar {
|
||||
flex: 1 1 0;
|
||||
height: 5px;
|
||||
.position(@position: relative);
|
||||
overflow: hidden;
|
||||
|
||||
.progressTrack {
|
||||
.size(@w: 100%, @h: 5px);
|
||||
.position(@position: absolute, @top: 0, @left: 0);
|
||||
background: #D4D4D4;
|
||||
}
|
||||
|
||||
.progressFill {
|
||||
height: 5px;
|
||||
.position(@position: absolute, @top: 0, @left: 0);
|
||||
background: #7D848C;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(44, 44, 44, 0.95);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(44, 44, 44, 1);
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
|
||||
import css from './ShopNowButton.module.less';
|
||||
|
||||
const SpottableDiv = Spottable('div');
|
||||
|
||||
export default function ShopNowButton({ onClick }) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<SpottableDiv className={css.shopNowButton} onClick={onClick} spotlightId="shop-now-button">
|
||||
<span className={css.buttonText}>SHOP NOW</span>
|
||||
</SpottableDiv>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.position(@position: fixed, @bottom: 247px, @right: 60px);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.shopNowButton {
|
||||
width: 188px;
|
||||
height: 85px;
|
||||
padding: 10px 30px;
|
||||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.30) 0%, rgba(0, 0, 0, 0.30) 100%);
|
||||
border: 1px solid rgba(234, 234, 234, 0.5);
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-color: rgba(234, 234, 234, 0.7);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba(199, 8, 80, 0.2);
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.buttonText {
|
||||
color: #FCFCFC;
|
||||
font-size: 22px;
|
||||
font-family: 'LG Smart UI';
|
||||
font-weight: 700;
|
||||
line-height: 15px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import css from './ShopNowContainer.module.less';
|
||||
|
||||
export default function ShopNowContainer() {
|
||||
return <div className={css.container}>{/* 나중에 콘텐츠 추가 예정 */}</div>;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.size(@w: 100%, @h: 365px);
|
||||
.position(@position: fixed, @bottom: 0, @left: 0);
|
||||
padding: 60px;
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(0, 0, 0, 0.95) 0%,
|
||||
rgba(0, 0, 0, 0.85) 40%,
|
||||
rgba(0, 0, 0, 0.6) 70%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
border-top: 1px solid rgba(234, 234, 234, 0.3);
|
||||
overflow: hidden;
|
||||
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column);
|
||||
z-index: 5;
|
||||
|
||||
> * + * {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
.position(@position: absolute, @top: 0, @left: 0);
|
||||
.size(@w: 100%, @h: 100%);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(30, 30, 30, 0.4) 0%,
|
||||
rgba(50, 50, 50, 0.25) 30%,
|
||||
transparent 50%,
|
||||
rgba(50, 50, 50, 0.25) 70%,
|
||||
rgba(30, 30, 30, 0.4) 100%
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user