[PlayerPanel] SideTab 폴더 구조 분해

This commit is contained in:
고동영
2024-04-29 14:35:14 +09:00
parent 15115b44d0
commit 363e3e557c
17 changed files with 280 additions and 155 deletions

View File

@@ -725,7 +725,7 @@ const VideoPlayerBase = class extends React.Component {
static contextType = FloatingLayerContext;
static defaultProps = {
autoCloseTimeout: 5000,
// autoCloseTimeout: 5000,
feedbackHideDelay: 3000,
initialJumpDelay: 400,
jumpBy: 30,

View File

@@ -7,13 +7,10 @@ import React, {
} from "react";
import classNames from "classnames";
import ReactPlayer from "react-player";
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 dummyVtt from "../../../assets/mock/video.vtt";
import * as CommonActions from "../../actions/commonActions";
@@ -30,30 +27,16 @@ import {
getSubTitle,
startVideoPlayer,
} from "../../actions/playActions";
import { MediaControls } from "../../components/MediaPlayer";
import TButton from "../../components/TButton/TButton";
import TButtonTab, { LIST_TYPE } from "../../components/TButtonTab/TButtonTab";
import TPanel from "../../components/TPanel/TPanel";
import VideoOverlayWithPhoneNumber from "../../components/VideoOverlayWithPhoneNumber/VideoOverlayWithPhoneNumber";
import { VideoPlayer } from "../../components/VideoPlayer/VideoPlayer";
import VideoPlayerSubtitle from "../../components/VideoPlayerSubtitle/VideoPlayerSubtitle";
import * as Config from "../../utils/Config";
import { panel_names } from "../../utils/Config";
import { $L } from "../../utils/helperMethods";
import PlayerOverlayChat from "./PlayerOverlay/PlayerOverlayChat";
import PlayerOverlayHeader from "./PlayerOverlay/PlayerOverlayHeader";
import PlayerOverlayQRCode from "./PlayerOverlay/PlayerOverlayQRCode";
import css from "./PlayerPanel.module.less";
import FeaturedShowContents from "./PlayerTabContents/FeaturedShowContents";
import LiveChannelContents from "./PlayerTabContents/LiveChannelContents";
import ShopNowContents from "./PlayerTabContents/ShopNowContents";
import YouMayLikeContents from "./PlayerTabContents/YouMayLikeContents";
const SpottableBtn = Spottable("button");
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element" },
"div"
);
import PlayerTabButton from "./PlayerTabContents/TabButton/PlayerTabButton";
import TabContainer from "./PlayerTabContents/TabContaienr";
const unableToPlay = new Job((callback) => {
callback();
@@ -71,7 +54,6 @@ const PlayerPanel = ({
const [playListInfo, setPlayListInfo] = useState("");
const [shopNowInfo, setShopNowInfo] = useState();
const [modalStyle, setModalStyle] = useState({});
const [tab, setTab] = useState(0);
const [sideOpen, setSideOpen] = useState(true);
const [selectedIndex, setSelectedIndex] = useState(0);
const [isUpdate, setIsUpdate] = useState(false);
@@ -89,12 +71,8 @@ const PlayerPanel = ({
const showNowInfos = useSelector((state) => state.main.showNowInfo);
const showNowProduct = useSelector((state) => state.main.showNowProduct);
const liveShowInfos = useSelector((state) => state.main.liveShowInfos);
//getSubTitle
const vodSubtitleData = useSelector((state) => state.play.subTitleBlobs);
const tabList = [
$L("SHOP NOW"),
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
];
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const onClickBack = useCallback(
(ev) => {
@@ -133,18 +111,6 @@ const PlayerPanel = ({
};
}, [panelInfo?.modal]);
const handleItemClick = useCallback(
({ index }) => {
if (index === tab) return;
setTab(index);
},
[tab]
);
const handleTabOnClick = () => {
setSideOpen((prev) => !prev);
};
const isActive = useMemo(() => {
return playListInfo;
}, [playListInfo]);
@@ -158,26 +124,6 @@ const PlayerPanel = ({
videoPlayer.current = ref;
}, []);
const onSpotlightBackBtn = () => {
const timer = setTimeout(() => {
Spotlight.focus("videoBackbtn");
});
return () => {
clearTimeout(timer);
};
};
const onSpotlightReduceBtn = () => {
const timer = setTimeout(() => {
Spotlight.focus("videoReduceBtn");
});
return () => {
clearTimeout(timer);
};
};
const toastUnableToPlay = useCallback(() => {
dispatch(CommonActions.alertToast($L("An unknown error has occured.")));
onClickBack();
@@ -191,11 +137,22 @@ const PlayerPanel = ({
setPlayListInfo(updatedPlayListInfo);
};
const autoCloseTimeout = useMemo(() => {
const autoCloseVideoOverlay = useMemo(() => {
console.log("#sideOpen", sideOpen);
if (!sideOpen && panelInfo.modal === false) {
return 3000;
}
}, [sideOpen, panelInfo]);
//10초뒤에 사이드 오픈 ( 예외처리 필요 )
useEffect(() => {
const timer = setTimeout(() => {
setSideOpen(false);
}, 10000);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
if (panelInfo) {
//console.log("#panelInfo", panelInfo);
@@ -282,7 +239,6 @@ const PlayerPanel = ({
]);
// 일정시간마다 API를 재호출해야하는 기능 테스트기간 동안 주석
useEffect(() => {
if (panelInfo?.shptmBanrTpNm === "LIVE") {
const interval = setInterval(() => {
@@ -422,7 +378,7 @@ const PlayerPanel = ({
disabled={panelInfo.modal}
onEnded={onClickBack} // 플레이어가 끝날때 호출
noAutoPlay={cannotPlay} // 오토플레이
autoCloseTimeout={autoCloseTimeout} // 컨트롤 버튼 숨기는 시간
autoCloseTimeout={autoCloseVideoOverlay} // 컨트롤 버튼 숨기는 시간
playListInfo={playListInfo && playListInfo} // 비디오 데이터
onBackButton={onClickBack} // 뒤로가기 버튼
panelInfo={panelInfo} // 패널정보 (라이브,VOD)
@@ -445,6 +401,9 @@ const PlayerPanel = ({
)}
</VideoPlayer>
)}
{/* Overlay Area */}
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
<VideoOverlayWithPhoneNumber
className={css.videoOverlayWithPhoneNumber}
@@ -453,54 +412,17 @@ const PlayerPanel = ({
/>
)}
{playListInfo && chatData && <PlayerOverlayChat />}
{/* <PlayerOverlayQRCode /> */}
{panelInfo?.shptmBanrTpNm !== "MEDIA" && (
<div
className={classNames(
css.arrow,
sideOpen ? css.arrowOpen : css.arrowClose
)}
>
<SpottableBtn
spotlightId={"hotpicks-close-arrow"}
onClick={handleTabOnClick}
className={css.button}
onSpotlightUp={onSpotlightBackBtn}
onSpotlightDown={onSpotlightReduceBtn}
/>
</div>
<PlayerTabButton setSideOpen={setSideOpen} sideOpen={sideOpen} />
)}
{/* </Container> */}
{sideOpen && panelInfo?.shptmBanrTpNm !== "MEDIA" && (
<Container className={css.tabContainer}>
<TButtonTab
contents={tabList}
className={css.tTab}
onItemClick={handleItemClick}
selectedIndex={tab}
listType={LIST_TYPE.small}
/>
{tab === 0 && <ShopNowContents shopNowInfo={shopNowInfo} />}
{panelInfo?.shptmBanrTpNm === "VOD" && tab === 1 && (
<FeaturedShowContents
featuredShowsInfos={playListInfo}
setSelectedIndex={setSelectedIndex}
/>
)}
{panelInfo?.shptmBanrTpNm === "LIVE" &&
tab === 1 &&
(liveChannelInfos || liveShowInfos) && (
<LiveChannelContents
setSelectedIndex={setSelectedIndex}
liveInfos={playListInfo}
/>
)}
{shopNowInfo && shopNowInfo.length < 3 && tab === 0 && (
<YouMayLikeContents shopNowInfo={shopNowInfo} />
)}
</Container>
<TabContainer
panelInfo={panelInfo}
shopNowInfo={shopNowInfo}
playListInfo={playListInfo}
setSelectedIndex={setSelectedIndex}
liveChannelInfos={liveChannelInfos || liveShowInfos}
/>
)}
</TPanel>
);

View File

@@ -116,28 +116,6 @@
}
}
}
.tabContainer {
.size(@w:660px, @h:100%);
background: #2c343f;
position: absolute;
right: 0;
top: 0;
padding: 48px 30px 0 30px;
z-index: 999;
.tTab {
border-radius: 12px;
overflow: hidden;
width: auto;
height: auto;
margin-bottom: 24px;
> div {
.size(@w:300px, @h:66px);
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
}
.videoOverlayWithPhoneNumber {
bottom: 210px;
@@ -175,7 +153,7 @@
display: none;
}
}
&.hideSubtitle{
&.hideSubtitle {
video::cue {
visibility: hidden;
}

View File

@@ -0,0 +1,52 @@
import React from "react";
import classNames from "classnames";
import Spotlight from "@enact/spotlight";
import Spottable from "@enact/spotlight/Spottable";
import css from "./PlayerTabButton.module.less";
const SpottableBtn = Spottable("button");
export default function PlayerTabButton({ sideOpen, setSideOpen }) {
const onSpotlightBackBtn = () => {
const timer = setTimeout(() => {
Spotlight.focus("videoBackbtn");
});
return () => {
clearTimeout(timer);
};
};
const onSpotlightReduceBtn = () => {
const timer = setTimeout(() => {
Spotlight.focus("videoReduceBtn");
});
return () => {
clearTimeout(timer);
};
};
const handleTabOnClick = () => {
setSideOpen((prev) => !prev);
};
return (
<div
className={classNames(
css.arrow,
sideOpen ? css.arrowOpen : css.arrowClose
)}
>
<SpottableBtn
spotlightId={"hotpicks-close-arrow"}
onClick={handleTabOnClick}
className={css.button}
onSpotlightUp={onSpotlightBackBtn}
onSpotlightDown={onSpotlightReduceBtn}
/>
</div>
);
}

View File

@@ -0,0 +1,76 @@
@import "../../../../style/utils.module.less";
.arrow {
.size(@w: 48px, @h: 144px);
text-align: center;
position: absolute;
top: 468px;
z-index: 2;
> button {
.size(@w: 48px, @h: 144px);
background-size: 48px 144px;
background-repeat: no-repeat;
font-size: 0;
line-height: 0;
display: inline-block;
cursor: pointer;
}
&.arrowClose {
right: -2px;
> button {
&.button {
background-image: url(../../../../../assets/images/btn/btn-toopen-nor.svg);
&:focus {
background-image: url(../../../../../assets/images/btn/btn-toopen-foc.svg);
}
}
}
}
&.arrowOpen {
right: 658px;
z-index: 4;
> button {
position: relative;
z-index: 5;
&.button {
background-image: url(../../../../../assets/images/btn/btn-toclose-nor.svg);
&:focus {
background-image: url(../../../../../assets/images/btn/btn-toclose-foc.svg);
}
}
&:before,
&:after {
width: 1920px;
height: 50%;
position: fixed;
left: 0;
content: "";
z-index: 4;
}
&:before {
bottom: 0;
background: linear-gradient(0deg, rgba(0, 0, 0, 1) 0%, transparent 50%);
}
&:after {
top: 0;
background: linear-gradient(
180deg,
rgba(0, 0, 0, 1) 0%,
transparent 50%
);
}
}
&:after {
width: 1920px;
height: 1080px;
position: fixed;
left: 0;
content: "";
z-index: 4;
top: 0;
background-color: rgba(0, 0, 0, 0.3);
cursor: auto;
}
}
}

View File

@@ -0,0 +1,71 @@
import React, { useCallback, useState } from "react";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import TButtonTab, {
LIST_TYPE,
} from "../../../components/TButtonTab/TButtonTab";
import { $L } from "../../../utils/helperMethods";
import css from "./TabContainer.module.less";
import FeaturedShowContents from "./TabContents/FeaturedShowContents";
import LiveChannelContents from "./TabContents/LiveChannelContents";
import ShopNowContents from "./TabContents/ShopNowContents";
import YouMayLikeContents from "./TabContents/YouMayLikeContents";
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element" },
"div"
);
export default function TabContainer({
panelInfo,
playListInfo,
shopNowInfo,
setSelectedIndex,
liveChannelInfos,
}) {
const [tab, setTab] = useState(0);
const tabList = [
$L("SHOP NOW"),
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
];
const handleItemClick = useCallback(
({ index }) => {
if (index === tab) return;
setTab(index);
},
[tab]
);
return (
<Container className={css.tabContainer}>
<TButtonTab
contents={tabList}
className={css.tTab}
onItemClick={handleItemClick}
selectedIndex={tab}
listType={LIST_TYPE.small}
/>
{tab === 0 && <ShopNowContents shopNowInfo={shopNowInfo} />}
{panelInfo?.shptmBanrTpNm === "VOD" && tab === 1 && (
<FeaturedShowContents
featuredShowsInfos={playListInfo}
setSelectedIndex={setSelectedIndex}
/>
)}
{panelInfo?.shptmBanrTpNm === "LIVE" && tab === 1 && liveChannelInfos && (
<LiveChannelContents
setSelectedIndex={setSelectedIndex}
liveInfos={playListInfo}
/>
)}
{shopNowInfo && shopNowInfo.length < 3 && tab === 0 && (
<YouMayLikeContents shopNowInfo={shopNowInfo} />
)}
</Container>
);
}

View File

@@ -0,0 +1,25 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.tabContainer {
.size(@w:660px, @h:100%);
background: #2c343f;
position: absolute;
right: 0;
top: 0;
padding: 48px 30px 0 30px;
z-index: 999;
.tTab {
border-radius: 12px;
overflow: hidden;
width: auto;
height: auto;
margin-bottom: 24px;
> div {
.size(@w:300px, @h:66px);
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
}

View File

@@ -2,10 +2,10 @@ import React, { useCallback, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { pushPanel, updatePanel } from "../../../actions/panelActions";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../utils/Config";
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
import { pushPanel, updatePanel } from "../../../../actions/panelActions";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../../utils/Config";
import PlayerItemCard, { TYPES } from "../../PlayerItemCard/PlayerItemCard";
import css from "./LiveChannelContents.module.less";
import PlayerTabLoading from "./PlayerTabLoading";

View File

@@ -1,4 +1,4 @@
@import "../../../style/utils.module.less";
@import "../../../../style/utils.module.less";
.container {
height: 956px;

View File

@@ -2,10 +2,10 @@ import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { pushPanel, updatePanel } from "../../../actions/panelActions";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../utils/Config";
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
import { pushPanel, updatePanel } from "../../../../actions/panelActions";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../../utils/Config";
import PlayerItemCard, { TYPES } from "../../PlayerItemCard/PlayerItemCard";
import css from "./LiveChannelContents.module.less";
import PlayerTabLoading from "./PlayerTabLoading";

View File

@@ -1,4 +1,4 @@
@import "../../../style/utils.module.less";
@import "../../../../style/utils.module.less";
.container {
height: 956px;

View File

@@ -1,7 +1,7 @@
import React from "react";
import loading from "../../../../assets/images/img-contents-loading@3x.png";
import { $L } from "../../../utils/helperMethods";
import loading from "../../../../../assets/images/img-contents-loading@3x.png";
import { $L } from "../../../../utils/helperMethods";
import css from "./PlayerTabLoading.module.less";
export default function PlayerTabLoading() {

View File

@@ -1,4 +1,5 @@
@import "../../../style/utils.module.less";
@import "../../../../style/utils.module.less";
.loadingContainer {
height: 250px;
display: flex;

View File

@@ -4,10 +4,10 @@ import { useDispatch, useSelector } from "react-redux";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { pushPanel, updatePanel } from "../../../actions/panelActions";
import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../utils/Config";
import { pushPanel, updatePanel } from "../../../../actions/panelActions";
import TItemCard, { TYPES } from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../../utils/Config";
import PlayerTabLoading from "./PlayerTabLoading";
import css from "./ShopNowContents.module.less";
@@ -41,7 +41,7 @@ export default function ShopNowContents({ shopNowInfo }) {
panelInfo: {
patnrId,
prdtId,
launchedFromPlayer: true
launchedFromPlayer: true,
},
})
);

View File

@@ -1,4 +1,4 @@
@import "../../../style/utils.module.less";
@import "../../../../style/utils.module.less";
.container {
overflow: hidden;

View File

@@ -2,11 +2,11 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { pushPanel } from "../../../actions/panelActions";
import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../utils/Config";
import { $L } from "../../../utils/helperMethods";
import { pushPanel } from "../../../../actions/panelActions";
import TItemCard, { TYPES } from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../../utils/Config";
import { $L } from "../../../../utils/helperMethods";
import PlayerTabLoading from "./PlayerTabLoading";
import css from "./YouMayLikeContents.module.less";

View File

@@ -1,5 +1,5 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.title {
color: #ffffff;
font-size: 36px;