PlayerPanel VOD 테스트 및 css 작업 / 컨트롤러 커스텀 / VOD안들어가지는 패널 onClick 수정

This commit is contained in:
고동영
2024-04-05 17:06:25 +09:00
parent 38b3fd807e
commit 75f71418dc
10 changed files with 276 additions and 196 deletions

View File

@@ -107,17 +107,20 @@
.focus({
.bar {
background-color: @sand-mediaslider-bar-bg-color;
background-color: #fff;
}
.fill {
background-color: @sand-mediaslider-fill-bg-color;
background-color: #c70850;
}
.disabled({
.bar {
opacity: @sand-mediaslider-disabled-bar-opacity;
}
.Knob {
background-color: #fff;
}
});
});

View File

@@ -10,6 +10,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import DurationFmt from 'ilib/lib/DurationFmt';
import PropTypes from 'prop-types';
import shallowEqual from 'recompose/shallowEqual';
@@ -105,7 +106,7 @@ const calcNumberValueOfPlaybackRate = (rate) => {
? parseInt(pbArray[0]) / parseInt(pbArray[1])
: parseInt(rate);
};
const SpottableBtn = Spottable("button");
const SpottableDiv = Touchable(Spottable("div"));
const RootContainer = SpotlightContainerDecorator(
{
@@ -2060,6 +2061,9 @@ const VideoPlayerBase = class extends React.Component {
cameraSettingsButton,
onBackButton,
panelInfo,
selectedIndex,
setSelectedIndex,
...mediaProps
} = this.props;
@@ -2157,7 +2161,14 @@ const VideoPlayerBase = class extends React.Component {
playListInfo={playListInfo}
onClick={onBackButton}
panelInfo={panelInfo}
setSelectedIndex={setSelectedIndex}
/>
<div>
<SpottableBtn
className={css.videoReduce}
onClick={onBackButton}
/>
</div>
</div>
)}
</Overlay>

View File

@@ -79,6 +79,22 @@
transform: translateY(~"calc(var(--liftDistance) * -1)");
transition: transform 0.3s linear;
}
.videoReduce {
width: 60px;
height: 60px;
background-image: url("../../../assets/images/btn/btn-video-min-nor@3x.png");
background-size: cover;
position: absolute;
right: 60px;
bottom: 150px;
z-index: 3;
&:focus {
background-color: #c70850;
opacity: 0.5;
}
}
}
.fullscreen {
.miniFeedback {
@@ -94,7 +110,7 @@
}
.bottom {
position: absolute;
z-index: 100; // Value assigned as part of the VideoPlayer API so layers may be inserted in-between
z-index: 3; // Value assigned as part of the VideoPlayer API so layers may be inserted in-between
bottom: -18px;
left: 0;
right: 0;

View File

@@ -1,16 +1,17 @@
.subtitleWrap{
position: absolute;
bottom: 50px;
width: 100%;
white-space: pre-wrap;
z-index: 1;
.subtitle {
color: rgb(255, 255, 255);
text-shadow: -2.5px 0px 2px rgb(0, 0, 0), 0px 2.5px 2px rgb(0, 0, 0), 2.5px 0px 2px rgb(0, 0, 0), 0px -2.5px 2px rgb(0, 0, 0);
font-family: "LG SmartFont";
font-size: 58px;
line-height: 1.4;
background-color: transparent;
text-align: center;
}
}
.subtitleWrap {
position: absolute;
bottom: 50px;
width: 100%;
white-space: pre-wrap;
z-index: 1;
.subtitle {
color: rgb(255, 255, 255);
text-shadow: -2.5px 0px 2px rgb(0, 0, 0), 0px 2.5px 2px rgb(0, 0, 0),
2.5px 0px 2px rgb(0, 0, 0), 0px -2.5px 2px rgb(0, 0, 0);
font-family: "LG SmartFont";
font-size: 58px;
line-height: 1.4;
background-color: transparent;
text-align: center;
}
}

View File

@@ -1,22 +1,32 @@
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 { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import {
SpotlightContainerDecorator,
} from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import { pushPanel } from "../../../actions/panelActions";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { pushPanel } from '../../../actions/panelActions';
import SectionTitle from '../../../components/SectionTitle/SectionTitle';
import TItemCard, {
IMAGETYPES,
TYPES,
} from "../../../components/TItemCard/TItemCard";
import TScroller from "../../../components/TScroller/TScroller";
import useScrollReset from "../../../hooks/useScrollReset";
import useScrollTo from "../../../hooks/useScrollTo";
import { panel_names } from "../../../utils/Config";
import { $L } from "../../../utils/helperMethods";
import css from "../PopularShow/PopularShow.module.less";
} from '../../../components/TItemCard/TItemCard';
import TScroller from '../../../components/TScroller/TScroller';
import useScrollReset from '../../../hooks/useScrollReset';
import useScrollTo from '../../../hooks/useScrollTo';
import { panel_names } from '../../../utils/Config';
import { $L } from '../../../utils/helperMethods';
import css from '../PopularShow/PopularShow.module.less';
const SpottableComponent = Spottable("div");
const Container = SpotlightContainerDecorator(
@@ -44,13 +54,11 @@ const PopularShow = ({ homeChk = true, order, ...rest }) => {
{
name: panel_names.PLAYER_PANEL,
panelInfo: {
playInfo: {
patnrId: item.patnrId,
showId: item.showId,
lgCatCd: item.lgCatCd,
type: "VOD",
showUrl: item.showUrl,
},
patnrId: item.patnrId,
showId: item.showId,
lgCatCd: item.lgCatCd,
shptmBanrTpNm: "VOD",
showUrl: item.showUrl,
},
},
[dispatch]

View File

@@ -13,13 +13,27 @@ export default function PlayerOverlayHeader({
playListInfo,
selectedIndex,
onClick,
setSelectedIndex,
}) {
console.log("#playListInfo", playListInfo);
const onClickBack = () => {
if (onClick) {
onClick();
}
};
const handleUpClick = () => {
if (selectedIndex !== 0) {
setSelectedIndex((prev) => prev + 1);
}
};
const handleDownClick = () => {
if (playListInfo.length - 1 === selectedIndex) {
return;
}
setSelectedIndex((prev) => prev + 1);
};
return (
<>
<div className={classNames(css.overIcon, css.backLiveicon)}>
@@ -55,6 +69,13 @@ export default function PlayerOverlayHeader({
)}
</h3>
</div>
<div className={classNames(css.overIcon, css.topIcon)}>
<SpottableBtn onClick={handleUpClick} />
</div>
<div className={classNames(css.overIcon, css.downIcon)}>
<SpottableBtn onClick={handleDownClick} />
</div>
</>
);
}

View File

@@ -101,3 +101,38 @@
font-size: 20px;
}
}
.overIcon {
position: absolute;
z-index: 3;
&.topIcon {
top: 12px;
left: 936px;
> button {
width: 48px;
height: 48px;
background-size: contain;
background-image: url("../../../../assets/images/btn/btn-wh-arrow-top-nor.svg");
&:focus {
background-image: url("../../../../assets/images/btn/btn-wh-arrow-top-foc.svg");
}
}
}
&.downIcon {
bottom: -973px;
left: 936px;
> button {
width: 48px;
height: 48px;
background-size: contain;
background-image: url("../../../../assets/images/btn/btn-wh-arrow-down-nor.svg");
&:focus {
background-image: url("../../../../assets/images/btn/btn-wh-arrow-down-foc.svg");
}
}
}
}

View File

@@ -39,6 +39,8 @@ 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 { $L } from '../../utils/helperMethods';
import PlayerOverlayChat from './PlayerOverlay/PlayerOverlayChat';
import PlayerOverlayHeader from './PlayerOverlay/PlayerOverlayHeader';
@@ -82,12 +84,14 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
const showNowInfos = useSelector((state) => state.main.showNowInfo);
const showNowProduct = useSelector((state) => state.main.showNowProduct);
const liveShowInfos = useSelector((state) => state.main.liveShowInfos);
const subtitle = useSelector((state) => state.play.subTitle);
const tabList = [
$L("SHOP NOW"),
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
];
console.log("#playListInfo", playListInfo);
console.log("#subTitleShowVod", subtitle);
// 패널 정보 받기
const getPanelInfo = useCallback(() => {
if (panels) {
@@ -101,18 +105,11 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
const onClickBack = useCallback(
(ev) => {
console.log("#####################");
dispatch(PanelActions.popPanel());
},
[dispatch]
);
const SpotToSlider = useCallback((ev) => {
if (Spotlight.focus("PLAYER_SLIDER")) {
ev.stopPropagation();
}
}, []);
const handleItemClick = useCallback(
({ index }) => {
if (index === tab) return;
@@ -130,20 +127,6 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
console.log("#getPlayer ", ref);
}, []);
// const onPlay = useCallback(() => {
// setIsPlay((prev) => !prev);
// videoPlayer.current.play();
// }, [isPlay]);
// const playButton = useCallback(() => {
// console.log("#isPlay", isPlay);
// return (
// <SpottableBtn
// className={classNames(isPlay ? css.pauseButton : css.playButton)}
// onClick={onPlay}
// ></SpottableBtn>
// );
// }, [onPlay, isPlay]);
const isActive = useMemo(() => {
return playListInfo;
}, [playListInfo]);
@@ -153,19 +136,6 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
onClickBack();
}, [dispatch, onClickBack]);
const handleUpClick = () => {
if (selectedIndex !== 0) {
setSelectedIndex((prev) => prev + 1);
}
};
const handleDownClick = () => {
if (playListInfo.length - 1 === selectedIndex) {
return;
}
setSelectedIndex((prev) => prev + 1);
};
const addPanelInfoToPlayList = (featuredShowsInfos) => {
const updatedPlayListInfo = [
{ ...showDetailInfo[0] },
@@ -187,29 +157,33 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
curationId: panelInfo.curationId,
})
);
dispatch(getMainLiveShow());
dispatch(
getMainLiveShowNowProduct({
patnrId: panelInfo.patnrId,
showId: panelInfo.showId,
})
);
}
dispatch(
getChatLog({ patnrId: panelInfo.patnrId, showId: panelInfo.showId })
);
if (panelInfo && panelInfo.lgCatCd) {
dispatch(
getHomeFullVideoInfo({
lgCatCd: panelInfo.lgCatCd,
})
);
dispatch(
getChatLog({ patnrId: panelInfo.patnrId, showId: panelInfo.showId })
);
dispatch(getMainLiveShow());
}
}, [dispatch, panelInfo, selectedIndex]);
useEffect(() => {
if (playListInfo && playListInfo.length > 0) {
if (
playListInfo &&
playListInfo.length > 0 &&
playListInfo[0].showSubtitlUrl
) {
dispatch(
getSubTitle({ showSubtitleUrl: playListInfo[0].showSubtitlUrl })
);
@@ -251,29 +225,22 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
setPlayListInfo(liveChannelInfos ? liveChannelInfos : liveShowInfos);
setShopNowInfo(showNowProduct);
}
}, [
panelInfo,
showDetailInfo,
liveChannelInfos,
showNowProduct,
selectedIndex,
dispatch,
]);
}, [panelInfo, showDetailInfo, liveChannelInfos, showNowProduct, dispatch]);
// 일정시간마다 API를 재호출해야하는 기능 테스트기간 동안 주석
// useEffect(() => {
// if (panelInfo?.shptmBanrTpNm === "LIVE") {
// const interval = setInterval(() => {
// dispatch(
// getMainLiveShowNowProduct({
// patnrId: panelInfo.patnrId,
// showId: panelInfo.showId,
// })
// );
// }, 10000); // 10초마다 호출
// return () => clearInterval(interval);
// }
// }, [panelInfo, showNowProduct, dispatch]);
useEffect(() => {
if (panelInfo?.shptmBanrTpNm === "LIVE") {
const interval = setInterval(() => {
dispatch(
getMainLiveShowNowProduct({
patnrId: panelInfo.patnrId,
showId: panelInfo.showId,
})
);
}, 10000); // 10초마다 호출
return () => clearInterval(interval);
}
}, [panelInfo, showNowProduct, dispatch]);
useEffect(() => {
if (panelInfo?.shptmBanrTpNm === "LIVE") {
@@ -299,7 +266,7 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
return (
<TPanel isTabActivated={false} {...props} className={css.videoContainer}>
{typeof window === "object" && typeof window.PalmSystem === "object" ? (
{typeof window === "object" && window.PalmSystem ? (
<VideoPlayer
setApiProvider={getPlayer}
onEnded={onClickBack} // 플레이어가 끝날때 호출
@@ -308,28 +275,27 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
playListInfo={playListInfo && playListInfo[selectedIndex]} // 비디오 데이터
onBackButton={onClickBack} // 뒤로가기 버튼
panelInfo={panelInfo} // 패널정보 (라이브,VOD)
setSelectedIndex={setSelectedIndex} // 선택한 인덱스 Set
selectedIndex={selectedIndex} // 선택한 인덱스
spotlightDisabled={sideOpen}
>
<source
src={playListInfo && playListInfo[selectedIndex]?.showUrl}
type="application/x-mpegURL"
type="application/mpegurl"
/>
{/* 테스트 */}
{/* <source
src={
" https://d130labfjte6iy.cloudfront.net/vod/1e62b39b-4301-4fe5-a16e-bebebef4e1c6/3e72500af7fc4d9d800e7a9533a29a36.mp4"
}
type="video/mp4"
/> */}
src={
" https://d130labfjte6iy.cloudfront.net/vod/1e62b39b-4301-4fe5-a16e-bebebef4e1c6/3e72500af7fc4d9d800e7a9533a29a36.mp4"
}
type="video/mp4"
/> */}
</VideoPlayer>
) : (
<ReactPlayer
className={""}
url={
playListInfo
? playListInfo[selectedIndex]?.showUrl
: panelInfo?.showUrl
} // 플레이어 url
url={playListInfo && playListInfo[selectedIndex]?.showUrl} // 플레이어 url
playing={true} // 자동 재생 on = true off = false
muted={false} // 자동 재생 on = true off = false
width={"1920"} // 플레이어 크기 (가로)
@@ -337,37 +303,33 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
controls={true} // 플레이어 컨트롤 노출 여부
onEnded={onClickBack} // 플레이어가 끝날때 호출
/>
)}
)}{" "}
*/
{/* 리액트 플레이어 테스트용 */}
{typeof window === "object" && typeof window.PalmSystem === "object" ? (
{typeof window === "object" && window.PalmSystem ? (
""
) : (
<PlayerOverlayHeader
selectedIndex={selectedIndex}
panelInfo={panelInfo}
playListInfo={playListInfo && playListInfo[selectedIndex]}
onClick={onClickBack}
/>
<>
<PlayerOverlayHeader
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
panelInfo={panelInfo}
playListInfo={playListInfo && playListInfo[selectedIndex]}
onClick={onClickBack}
/>
<div>
<SpottableBtn className={css.videoReduce} onClick={onClickBack} />
</div>
</>
)}
<div>
<SpottableBtn className={css.videoReduce} onClick={onClickBack} />
</div>
{/* 인디게이터 버튼 */}
<div className={classNames(css.overIcon, css.topIcon)}>
<SpottableBtn onClick={handleUpClick} />
</div>
<div className={classNames(css.overIcon, css.downIcon)}>
<SpottableBtn onClick={handleDownClick} />
</div>
{/* CalltoOrder */}
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
<VideoOverlayWithPhoneNumber
className={css.videoOverlayWithPhoneNumber}
show
/>
)}
<VideoPlayerSubtitle subtitle={subtitle && subtitle.text} />
{playListInfo && chatData && <PlayerOverlayChat />}
{/* <PlayerOverlayQRCode /> */}
<div
className={classNames(
@@ -399,12 +361,14 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
setSelectedIndex={setSelectedIndex}
/>
)}
{panelInfo?.shptmBanrTpNm === "LIVE" && tab === 1 && (
<LiveChannelContents
setSelectedIndex={setSelectedIndex}
liveInfos={playListInfo}
/>
)}
{panelInfo?.shptmBanrTpNm === "LIVE" &&
tab === 1 &&
(liveChannelInfos || liveShowInfos) && (
<LiveChannelContents
setSelectedIndex={setSelectedIndex}
liveInfos={playListInfo}
/>
)}
{shopNowInfo !== "undefined" &&
youmaylikeInfos &&

View File

@@ -64,13 +64,53 @@
}
&.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: 276px;
position: fixed;
left: 0;
content: "";
z-index: 4;
}
&:before {
bottom: 0;
background: linear-gradient(
0deg,
rgba(0, 0, 0, 1) 0%,
transparent 100%
);
}
&:after {
top: 0;
background: linear-gradient(
180deg,
rgba(0, 0, 0, 1) 0%,
transparent 100%
);
}
}
&: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;
}
}
}
@@ -81,7 +121,7 @@
right: 0;
top: 0;
padding: 48px 30px 0 30px;
z-index: 3;
z-index: 999;
.tTab {
border-radius: 12px;
overflow: hidden;
@@ -102,44 +142,18 @@
left: 60px;
}
.videoReduce {
.size(@w:60px, @h:60px);
background-image: url("../../../assets/images/btn/btn-video-min-nor@3x.png");
background-size: cover;
.size(@w:78px, @h:78px);
background: url("../../../assets/images/btn/btn-video-min-nor@3x.png")
no-repeat center center/60px 60px;
position: absolute;
right: 60px;
bottom: 150px;
z-index: 100;
}
z-index: 3;
.overIcon {
position: absolute;
z-index: 2;
&.topIcon {
top: 12px;
left: 936px;
> button {
.size(@w: 48px, @h: 48px);
background-size: contain;
background-image: url("../../../assets/images/btn/btn-wh-arrow-top-nor.svg");
&:focus {
background-image: url("../../../assets/images/btn/btn-wh-arrow-top-foc.svg");
}
}
}
&.downIcon {
bottom: 12px;
left: 936px;
> button {
.size(@w: 48px, @h: 48px);
background-size: contain;
background-image: url("../../../assets/images/btn/btn-wh-arrow-down-nor.svg");
&:focus {
background-image: url("../../../assets/images/btn/btn-wh-arrow-down-foc.svg");
}
}
&:focus {
.size(@w:78px, @h:78px);
background-color: rgba(199, 8, 80, 0.5);
border-radius: 50%;
}
}
}

View File

@@ -1,18 +1,27 @@
import React, { useCallback, useEffect, useState } from "react";
import React, {
useCallback,
useEffect,
useState,
} from 'react';
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import classNames from 'classnames';
import {
useDispatch,
useSelector,
} from 'react-redux';
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import { pushPanel } from "../../../actions/panelActions";
import TButton from "../../../components/TButton/TButton";
import useScrollReset from "../../../hooks/useScrollReset";
import { panel_names } from "../../../utils/Config";
import css from "./PopularShowIndicator.module.less";
import PopularProductList from "./PopularShowVerticalContents/PopularProductList";
import PopularVideoCard from "./PopularVideoCard/PopularVideoCard";
import { pushPanel } from '../../../actions/panelActions';
import TButton from '../../../components/TButton/TButton';
import useScrollReset from '../../../hooks/useScrollReset';
import { panel_names } from '../../../utils/Config';
import css from './PopularShowIndicator.module.less';
import PopularProductList
from './PopularShowVerticalContents/PopularProductList';
import PopularVideoCard from './PopularVideoCard/PopularVideoCard';
const Container = SpotlightContainerDecorator(
{
@@ -76,13 +85,11 @@ export default function PopularShowIndicator({ scrollTop, onSpotlightDown }) {
pushPanel({
name: panel_names.PLAYER_PANEL,
panelInfo: {
playInfo: {
patnrId,
showId,
lgCatCd: catCd,
type: "VOD",
showUrl,
},
patnrId,
showId,
lgCatCd: catCd,
shptmBanrTpNm: "VOD",
showUrl,
},
})
);