video player panel overlay
This commit is contained in:
@@ -1,8 +1,16 @@
|
||||
import { types } from "./actionTypes";
|
||||
|
||||
export const pushPanel = (panel) => ({
|
||||
/*
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
modal: true //only for video player
|
||||
etc...
|
||||
},
|
||||
*/
|
||||
export const pushPanel = (panel, duplicatable=false) => ({
|
||||
type: types.PUSH_PANEL,
|
||||
payload: panel,
|
||||
duplicatable: duplicatable
|
||||
});
|
||||
|
||||
export const popPanel = (panelName) => ({
|
||||
|
||||
@@ -1,7 +1,55 @@
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import { URLS } from '../api/apiConfig';
|
||||
import { TAxios } from '../api/TAxios';
|
||||
import { panel_names } from '../utils/Config';
|
||||
import { types } from './actionTypes';
|
||||
import { popPanel, pushPanel, updatePanel } from './panelActions';
|
||||
|
||||
|
||||
//yhcho
|
||||
/*
|
||||
dispatch(startVideoPreview({
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
shptmBanrTpNm: randomData.shptmBanrTpNm,
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
modal: true,
|
||||
modalContainerRef: videoModalContainerRef.current, //to calc width, height, left, top
|
||||
modalClassName:css.videoModal
|
||||
}));
|
||||
|
||||
modalClassName: modal more class info and checking it's launched from preview mode
|
||||
*/
|
||||
let startVideoTimer = null;
|
||||
//start modal mode
|
||||
//start Full -> modal mode
|
||||
export const startVideoPlayer = ({ modal, modalContainerId, modalClassName, ...rest }) => (dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
const topPanel = panels[panels.length -1];
|
||||
let panelWorkingAction = pushPanel;
|
||||
if(topPanel && topPanel.name === panel_names.PLAYER_PANEL){
|
||||
panelWorkingAction = updatePanel;
|
||||
}
|
||||
dispatch(panelWorkingAction({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
modal,
|
||||
modalContainerId,
|
||||
modalClassName,
|
||||
...rest
|
||||
}
|
||||
}, true));
|
||||
if(modal && modalContainerId){
|
||||
Spotlight.focus(modalContainerId);
|
||||
}
|
||||
};
|
||||
export const finishVideoPreview = () => (dispatch, getState) => {
|
||||
const panels = getState().panels.panels;
|
||||
const topPanel = panels[panels.length -1];
|
||||
if(topPanel && topPanel.name === panel_names.PLAYER_PANEL && topPanel.panelInfo.modal){
|
||||
dispatch(popPanel());
|
||||
}
|
||||
};
|
||||
// 채팅 로그 가져오기 IF-LGSP-371
|
||||
export const getChatLog =
|
||||
({ patnrId, showId }) =>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.size(@w: 100%, @h: 100vh);
|
||||
box-sizing: border-box;
|
||||
color: black;
|
||||
|
||||
position: absolute; //yhcho
|
||||
> section {
|
||||
font-family: @baseFont;
|
||||
color: @COLOR_GRAY03;
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, { useCallback, useRef, useMemo } from "react";
|
||||
var handledMediaEventsMap =
|
||||
['onReady', 'onStart', 'onPlay', 'onProgress', 'onDuration', 'onPause', 'onBuffer', 'onBufferEnd', 'onSeek', 'onEnded', 'onError'];
|
||||
|
||||
export default function TReactPlayer({mediaEventsMap=handledMediaEventsMap, videoRef, ...rest}) {
|
||||
export default function TReactPlayer({mediaEventsMap=handledMediaEventsMap, videoRef, url, ...rest}) {
|
||||
const playerRef = useRef(null);
|
||||
|
||||
const handleEvent = useCallback((type)=> (ev)=> {
|
||||
@@ -55,6 +55,7 @@ export default function TReactPlayer({mediaEventsMap=handledMediaEventsMap, vide
|
||||
return (
|
||||
<ReactPlayer
|
||||
ref={playerRef}
|
||||
url={url}
|
||||
progressInterval={1000}
|
||||
{...handledMediaEvents}
|
||||
{...rest}
|
||||
|
||||
@@ -732,6 +732,7 @@ const VideoPlayerBase = class extends React.Component {
|
||||
introTime: PropTypes.number,
|
||||
onClickSkipIntro: PropTypes.func,
|
||||
onIntroDisabled: PropTypes.func,
|
||||
modalClassName: PropTypes.any,
|
||||
src: PropTypes.string, //for ReactPlayer
|
||||
};
|
||||
|
||||
@@ -1388,6 +1389,7 @@ const VideoPlayerBase = class extends React.Component {
|
||||
handleEvent = () => {
|
||||
const el = this.video;
|
||||
if(!el){
|
||||
console.log('yhcho VideoPlayer no el ');
|
||||
return;
|
||||
}
|
||||
const updatedState = {
|
||||
@@ -1446,7 +1448,7 @@ const VideoPlayerBase = class extends React.Component {
|
||||
currentTime: this.state.currentTime,
|
||||
duration: this.state.duration,
|
||||
paused: this.state.paused,
|
||||
playbackRate: this.video.playbackRate,
|
||||
playbackRate: this.video?.playbackRate,
|
||||
proportionLoaded: this.state.proportionLoaded,
|
||||
proportionPlayed: this.state.proportionPlayed,
|
||||
};
|
||||
@@ -2040,6 +2042,7 @@ const VideoPlayerBase = class extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
modalClassName,
|
||||
disabled,
|
||||
infoComponents,
|
||||
backButton,
|
||||
@@ -2141,7 +2144,7 @@ const VideoPlayerBase = class extends React.Component {
|
||||
return (
|
||||
<RootContainer
|
||||
className={
|
||||
css.videoPlayer + " enact-fit" + (className ? " " + className : "")
|
||||
classNames(css.videoPlayer + " enact-fit" + (className ? " " + className : ""), modalClassName)
|
||||
}
|
||||
onClick={this.activityDetected}
|
||||
ref={this.setPlayerRef}
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
background-size: cover;
|
||||
border-radius: 20.8125rem;
|
||||
overflow: hidden;
|
||||
margin: 490px auto;
|
||||
// margin: 490px auto;
|
||||
left: calc(50% - 50px);
|
||||
top: calc(50% - 50px);
|
||||
animation: none 1.25s linear infinite;
|
||||
animation-name: spin;
|
||||
// animation-play-state: paused;
|
||||
|
||||
@@ -25,7 +25,7 @@ export const panelsReducer = (state = initialState, action) => {
|
||||
|
||||
if (forceTopIndex >= 0) {
|
||||
forceTopPanelsInfo[forceTopIndex] = panel;
|
||||
} else if (panel.name !== action.payload.name) {
|
||||
} else if (panel.name !== action.payload.name || action.duplicatable) {
|
||||
newState.push(panel);
|
||||
}
|
||||
});
|
||||
@@ -67,10 +67,19 @@ export const panelsReducer = (state = initialState, action) => {
|
||||
}
|
||||
|
||||
case types.UPDATE_PANEL:
|
||||
{
|
||||
let lastIndex = -1;
|
||||
// 배열의 끝에서부터 시작하여 조건에 맞는 마지막 인덱스 찾기
|
||||
for (let i = state.panels.length - 1; i >= 0; i--) {
|
||||
if (state.panels[i].name === action.payload.name) {
|
||||
lastIndex = i;
|
||||
break; // 조건에 맞는 첫 번째 요소를 찾으면 루프 종료
|
||||
}
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
panels: state.panels.map((panel) =>
|
||||
panel.name === action.payload.name
|
||||
panels: state.panels.map((panel, index) =>
|
||||
index === lastIndex
|
||||
? {
|
||||
...panel,
|
||||
panelInfo: { ...panel.panelInfo, ...action.payload.panelInfo },
|
||||
@@ -78,7 +87,7 @@ export const panelsReducer = (state = initialState, action) => {
|
||||
: panel
|
||||
),
|
||||
};
|
||||
|
||||
}
|
||||
case types.UPDATE_MODAL_STATUS:
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -13,14 +13,16 @@ import { clearProductDetail } from "../../actions/productActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import THeader from "../../components/THeader/THeader";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import { panel_names } from "../../utils/Config";
|
||||
import css from "./DetailPanel.module.less";
|
||||
import GroupProduct from "./GroupProduct/GroupProduct";
|
||||
import SingleProduct from "./SingleProduct/SingleProduct";
|
||||
import ThemeProduct from "./ThemeProduct/ThemeProduct";
|
||||
import UnableProduct from "./UnableProduct/UnableProduct";
|
||||
import YouMayLike from "./YouMayLike/YouMayLike";
|
||||
import { finishVideoPreview } from "../../actions/playActions";
|
||||
|
||||
export default function DetailPanel() {
|
||||
export default function ItemDetail({panelInfo}) {
|
||||
const [selectedPatnrId, setSelectedPatnrId] = useState("");
|
||||
const [selectedPrdtId, setSelectedPrtdId] = useState("");
|
||||
const [selectedCurationId, setSelectedCurationId] = useState("");
|
||||
@@ -94,6 +96,8 @@ export default function DetailPanel() {
|
||||
}, [dispatch, selectedPatnrId, selectedPrdtId, panels]);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
// dispatch(resetPanels([{ name: panel_names.DETAIL_PANEL, panelInfo: {} }]));
|
||||
dispatch(finishVideoPreview());
|
||||
dispatch(popPanel());
|
||||
}, [dispatch]);
|
||||
|
||||
@@ -184,6 +188,7 @@ export default function DetailPanel() {
|
||||
selectedPrdtId={selectedPrdtId}
|
||||
selectedIndex={selectedIndex}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
launchedFromPlayer={panelInfo.launchedFromPlayer}
|
||||
/>
|
||||
)}
|
||||
{/* 그룹상품 영역 */}
|
||||
@@ -194,6 +199,7 @@ export default function DetailPanel() {
|
||||
selectedPrdtId={selectedPrdtId}
|
||||
selectedIndex={selectedIndex}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
launchedFromPlayer={panelInfo.launchedFromPlayer}
|
||||
/>
|
||||
)}
|
||||
{/* 구매불가상품 영역 */}
|
||||
@@ -203,6 +209,7 @@ export default function DetailPanel() {
|
||||
selectedPrdtId={selectedPrdtId}
|
||||
selectedIndex={selectedIndex}
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
launchedFromPlayer={panelInfo.launchedFromPlayer}
|
||||
/>
|
||||
)}
|
||||
{/* 테마그룹상품 영역*/}
|
||||
@@ -213,6 +220,7 @@ export default function DetailPanel() {
|
||||
selectedCurationId={selectedCurationId}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
themeType={themeType}
|
||||
launchedFromPlayer={panelInfo.launchedFromPlayer}
|
||||
/>
|
||||
)}
|
||||
</TBody>
|
||||
|
||||
@@ -21,6 +21,7 @@ export default function UnableProduct({
|
||||
selectedPrdtId,
|
||||
selectedIndex,
|
||||
setSelectedIndex,
|
||||
launchedFromPlayer
|
||||
}) {
|
||||
const productData = useSelector((state) => state.main.productData);
|
||||
|
||||
@@ -46,6 +47,7 @@ export default function UnableProduct({
|
||||
productInfo={productData}
|
||||
soldoutFlag={soldout}
|
||||
promotionCode={promotionCode}
|
||||
launchedFromPlayer={launchedFromPlayer}
|
||||
/>
|
||||
<IndicatorOptions
|
||||
productInfo={productData}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
@@ -15,6 +15,8 @@ import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGr
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { panel_names } from "../../../../utils/Config";
|
||||
import css from "./Indicator.module.less";
|
||||
import { finishVideoPreview, startVideoPlayer } from "../../../../actions/playActions";
|
||||
import { scaleW } from "../../../../utils/helperMethods";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused", preserveld: true },
|
||||
@@ -22,47 +24,52 @@ const Container = SpotlightContainerDecorator(
|
||||
);
|
||||
const SpottableComponent = Spottable("div");
|
||||
const SpottableImage = Spottable(Image);
|
||||
const IMAGE_WIDTH = 152;
|
||||
export default function Indicator({
|
||||
const IMAGE_WIDTH = scaleW(152);
|
||||
function Indicator({
|
||||
selectedIndex,
|
||||
setSelectedIndex,
|
||||
productInfo,
|
||||
soldoutFlag,
|
||||
launchedFromPlayer,
|
||||
promotionCode,
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
const [selectedImage, setSelectedImage] = useState(null);
|
||||
const { cursorVisible } = useSelector((state) => state.common.appStatus);
|
||||
const { getScrollTo, scrollTop } = useScrollTo();
|
||||
|
||||
const [detailVideoPlaying, setDetailVideoPlaying] = useState(!launchedFromPlayer && productInfo.prdtMediaUrl);
|
||||
let imagePosition = IMAGE_WIDTH * selectedIndex - IMAGE_WIDTH;
|
||||
let images = [];
|
||||
|
||||
console.log("#promotionCode", promotionCode);
|
||||
|
||||
useEffect(() => {
|
||||
if (productInfo?.prdtMediaUrl !== null && selectedIndex > 0) {
|
||||
setSelectedImage(images[selectedIndex]);
|
||||
} else {
|
||||
setSelectedImage(productInfo.imgUrls600[selectedIndex]);
|
||||
console.log('yhcho productInfo detailVideoPlaying', productInfo, launchedFromPlayer, detailVideoPlaying);
|
||||
if(detailVideoPlaying && productInfo.prdtMediaUrl){ //auto play
|
||||
dispatch(startVideoPlayer({
|
||||
showUrl: productInfo.prdtMediaUrl,
|
||||
showNm: productInfo.prdtNm,
|
||||
patnrNm: productInfo.patncNm,
|
||||
patncLogoPath: productInfo.patncLogoPath,
|
||||
orderPhnNo: productInfo.orderPhnNo,
|
||||
shptmBanrTpNm: "MEDIA",
|
||||
modal: true,
|
||||
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
|
||||
modalClassName: selectedIndex === 0 ? css.videoModal:css.videoModalHide
|
||||
}));
|
||||
}
|
||||
}, [selectedIndex, productInfo]);
|
||||
}, [selectedIndex, productInfo, detailVideoPlaying, launchedFromPlayer]);
|
||||
|
||||
const handleUpClick = useCallback(() => {
|
||||
if (selectedIndex === 0) {
|
||||
return;
|
||||
}
|
||||
setSelectedIndex((prev) => prev - 1);
|
||||
if (productInfo.imgUrls600.length - 1 !== selectedIndex) {
|
||||
if (listImages.length - 1 !== selectedIndex) {
|
||||
scrollTop({ y: imagePosition - IMAGE_WIDTH, animate: true });
|
||||
}
|
||||
}, [selectedIndex]);
|
||||
}, [selectedIndex, listImages]);
|
||||
|
||||
const handleDownClick = useCallback(() => {
|
||||
if (productInfo.imgUrls600.length - 1 === selectedIndex) {
|
||||
if (listImages.length.length - 1 === selectedIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedIndex((prev) => prev + 1);
|
||||
if (selectedIndex > 1) {
|
||||
scrollTop({
|
||||
@@ -70,23 +77,30 @@ export default function Indicator({
|
||||
animate: true,
|
||||
});
|
||||
}
|
||||
}, [selectedIndex, selectedImage]);
|
||||
}, [selectedIndex, listImages]);
|
||||
|
||||
const canPlayVideo = useMemo(()=>{
|
||||
return productInfo.prdtMediaUrl && selectedIndex === 0;
|
||||
},[productInfo, selectedIndex]);
|
||||
|
||||
const handleVideoOnClick = useCallback(() => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
if(canPlayVideo){
|
||||
dispatch(startVideoPlayer({
|
||||
showUrl: productInfo.prdtMediaUrl,
|
||||
showNm: productInfo.prdtNm,
|
||||
patnrNm: productInfo.patncNm,
|
||||
patncLogoPath: productInfo.patncLogoPath,
|
||||
orderPhnNo: productInfo.orderPhnNo,
|
||||
shptmBanrTpNm: "MEDIA",
|
||||
},
|
||||
})
|
||||
);
|
||||
}, [dispatch]);
|
||||
modal: !detailVideoPlaying,
|
||||
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
|
||||
modalClassName:css.videoModal
|
||||
}));
|
||||
if(!detailVideoPlaying){
|
||||
setDetailVideoPlaying(true);
|
||||
}
|
||||
}
|
||||
}, [dispatch, productInfo, detailVideoPlaying, canPlayVideo]);
|
||||
|
||||
const onSpotlightRight = useCallback(() => {
|
||||
const timer = setTimeout(() => {
|
||||
@@ -104,9 +118,9 @@ export default function Indicator({
|
||||
const onSpotlightLeft = useCallback(() => {
|
||||
Spotlight.focus("spotlightId_backBtn");
|
||||
}, []);
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
images = [...productInfo.imgUrls600];
|
||||
|
||||
const listImages = useMemo(()=>{
|
||||
const images = [...productInfo.imgUrls600];
|
||||
if (productInfo?.prdtMediaUrl !== null) {
|
||||
images.splice(
|
||||
0,
|
||||
@@ -116,6 +130,15 @@ export default function Indicator({
|
||||
: defaultImage
|
||||
);
|
||||
}
|
||||
return images;
|
||||
},[productInfo]);
|
||||
|
||||
const selectedImage = useMemo(()=>{
|
||||
return listImages[selectedIndex];
|
||||
},[listImages, selectedIndex]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
|
||||
const handleItemClick = () => {
|
||||
setSelectedIndex(index);
|
||||
@@ -124,7 +147,7 @@ export default function Indicator({
|
||||
return (
|
||||
<>
|
||||
<SpottableImage
|
||||
src={images[index]}
|
||||
src={listImages[index]}
|
||||
alt=""
|
||||
className={classNames(
|
||||
css.image,
|
||||
@@ -143,63 +166,34 @@ export default function Indicator({
|
||||
</>
|
||||
);
|
||||
},
|
||||
[productInfo, selectedIndex, selectedImage]
|
||||
[listImages, selectedIndex]
|
||||
);
|
||||
|
||||
const renderThumbnail = useCallback(() => {
|
||||
return (
|
||||
<div className={css.thumbnailContainer}>
|
||||
{productInfo && productInfo.prdtMediaUrl !== null ? (
|
||||
selectedIndex === 0 ? (
|
||||
<>
|
||||
<SpottableComponent
|
||||
className={css.player}
|
||||
spotlightId="indicator_videoContainer"
|
||||
spotlightDisabled={!canPlayVideo}
|
||||
disabled={!canPlayVideo}
|
||||
className={classNames(css.thumbnail, soldoutFlag && css.soldout)}
|
||||
onSpotlightRight={onSpotlightRight}
|
||||
onSpotlightLeft={onSpotlightLeft}
|
||||
onClick={handleVideoOnClick}
|
||||
onSpotlightUp={onSpotlightUp}
|
||||
onSpotlightLeft={onSpotlightLeft}
|
||||
spotlightId="spotlight_videoThumbnail"
|
||||
>
|
||||
<TVideoPlayer
|
||||
showUrl={productInfo.prdtMediaUrl}
|
||||
width={560}
|
||||
height={560}
|
||||
videoIsPlaying
|
||||
/>
|
||||
</SpottableComponent>
|
||||
{productInfo && productInfo[selectedIndex]?.disclaimer && (
|
||||
<div className={css.disclaimerContainer}>
|
||||
<span className={css.icon} />
|
||||
<div className={css.disclaimer}>
|
||||
{productInfo?.disclaimer}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<>
|
||||
<Image
|
||||
className={css.image}
|
||||
src={detailVideoPlaying && canPlayVideo ? "" : selectedImage}
|
||||
alt=""
|
||||
></Image>
|
||||
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
|
||||
{!detailVideoPlaying && canPlayVideo && <h3 className={css.soldoutLabel}>Play Button (todo)</h3>}
|
||||
</>
|
||||
) : (
|
||||
<SpottableImage
|
||||
src={selectedImage}
|
||||
alt=""
|
||||
className={classNames(css.thumbnail, soldoutFlag && css.soldout)}
|
||||
onSpotlightRight={onSpotlightRight}
|
||||
onSpotlightLeft={onSpotlightLeft}
|
||||
>
|
||||
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
|
||||
</SpottableImage>
|
||||
)
|
||||
) : (
|
||||
<SpottableImage
|
||||
src={selectedImage}
|
||||
alt=""
|
||||
className={classNames(css.thumbnail, soldoutFlag && css.soldout)}
|
||||
onSpotlightRight={onSpotlightRight}
|
||||
onSpotlightLeft={onSpotlightLeft}
|
||||
>
|
||||
{soldoutFlag && <h3 className={css.soldoutLabel}>SOLD OUT</h3>}
|
||||
</SpottableImage>
|
||||
)}
|
||||
</SpottableComponent>
|
||||
</div>
|
||||
);
|
||||
}, [productInfo, selectedIndex, selectedImage, soldoutFlag]);
|
||||
}, [productInfo, selectedIndex, selectedImage, soldoutFlag, detailVideoPlaying]);
|
||||
|
||||
return (
|
||||
<Container className={css.indicatorContainer}>
|
||||
@@ -218,10 +212,10 @@ export default function Indicator({
|
||||
<TVirtualGridList
|
||||
cbScrollTo={getScrollTo}
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={productInfo.imgUrls600.length}
|
||||
itemWidth={144}
|
||||
itemHeight={144}
|
||||
spacing={8}
|
||||
dataSize={listImages.length}
|
||||
itemWidth={scaleW(144)}
|
||||
itemHeight={scaleW(144)}
|
||||
spacing={scaleW(8)}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
@@ -231,10 +225,27 @@ export default function Indicator({
|
||||
spotlightDisabled={!cursorVisible}
|
||||
className={classNames(
|
||||
css.downButton,
|
||||
productInfo.imgUrls600.length - 1 === selectedIndex && css.disable
|
||||
(listImages.length-1) === selectedIndex && css.disable
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
const propsAreEqual = (prev, next) => {
|
||||
const keys = Object.keys(prev);
|
||||
const nextKeys = Object.keys(next);
|
||||
if(keys.length !== nextKeys.length){
|
||||
return false;
|
||||
}
|
||||
for(let i=0; i<keys.length; i++){
|
||||
if(prev[keys[i]] !== next[keys[i]]){
|
||||
if (JSON.stringify(prev[keys[i]]) === JSON.stringify(next[keys[i]])) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export default React.memo(Indicator, propsAreEqual);
|
||||
@@ -76,7 +76,11 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.image{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
> h3 {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
@@ -231,3 +235,9 @@
|
||||
|
||||
//isOptions
|
||||
}
|
||||
.videoModal::after {
|
||||
// .focused(@boxShadow:22px, @borderRadius: 0px);
|
||||
}
|
||||
.videoModalHide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
@@ -14,11 +13,11 @@ import emptyVerImage from "../../../../assets/images/img-home-banner-empty-ver.p
|
||||
import liveShow from "../../../../assets/images/tag-liveshow.png";
|
||||
import { pushPanel } from "../../../actions/panelActions";
|
||||
import CustomImage from "../../../components/CustomImage/CustomImage";
|
||||
import TVideoPlayer from "../../../components/TVideoPlayer/TVideoPlayer";
|
||||
import usePriceInfo from "../../../hooks/usePriceInfo";
|
||||
import useScrollReset from "../../../hooks/useScrollReset";
|
||||
import { panel_names } from "../../../utils/Config";
|
||||
import css from "./RandomUnit.module.less";
|
||||
import { finishVideoPreview, startVideoPlayer } from "../../../actions/playActions";
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
|
||||
@@ -35,13 +34,11 @@ export default function RandomUnit({
|
||||
}) {
|
||||
const bannerDetailInfos = bannerData.bannerDetailInfos;
|
||||
|
||||
const [videoIsPlaying, setVideoIsPlaying] = useState(false);
|
||||
const [randomData, setRandomData] = useState("");
|
||||
const [priceInfos, setpriceInfos] = useState("");
|
||||
const [videoIndex, setVideoIndex] = useState([]);
|
||||
const [videoError, setVideoError] = useState(false);
|
||||
const [randomNumber, setRandomNumber] = useState("");
|
||||
|
||||
const { handleScrollReset, handleStopScrolling } =
|
||||
useScrollReset(scrollTopBody);
|
||||
|
||||
@@ -86,14 +83,28 @@ export default function RandomUnit({
|
||||
};
|
||||
|
||||
// 포커스 인
|
||||
const onFocus = () => {
|
||||
setVideoIsPlaying(true);
|
||||
const onFocus = (ev) => {
|
||||
handleScrollReset();
|
||||
if(randomData.shptmBanrTpNm == "LIVE" ||
|
||||
randomData.shptmBanrTpNm == "VOD"){
|
||||
dispatch(startVideoPlayer({
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
shptmBanrTpNm: randomData.shptmBanrTpNm,
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
modal: true,
|
||||
modalContainerId: spotlightId, //to calc width, height, left, top
|
||||
modalClassName:css.videoModal
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
// 포커스 아웃
|
||||
const onBlur = () => {
|
||||
setVideoIsPlaying(false);
|
||||
const onBlur = (ev) => {
|
||||
if(randomData.shptmBanrTpNm == "LIVE" ||
|
||||
randomData.shptmBanrTpNm == "VOD"){
|
||||
dispatch(finishVideoPreview());
|
||||
}
|
||||
handleStopScrolling();
|
||||
};
|
||||
|
||||
@@ -119,17 +130,13 @@ export default function RandomUnit({
|
||||
} else if (randomData.shptmLnkTpNm === "Product Detail") {
|
||||
panelName = panel_names.DETAIL_PANEL;
|
||||
} else if (randomData.shptmLnkTpNm === "VOD") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
return dispatch(startVideoPlayer({
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
shptmBanrTpNm: "VOD",
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
},
|
||||
})
|
||||
);
|
||||
modal: false
|
||||
}));
|
||||
} else if (randomData.shptmLnkTpNm === "Show Detail") {
|
||||
panelName = panel_names.HOME_PANEL;
|
||||
} else if (randomData.shptmLnkTpNm === "Theme Page") {
|
||||
@@ -166,19 +173,17 @@ export default function RandomUnit({
|
||||
};
|
||||
|
||||
// 비디오 클릭
|
||||
const videoClick = () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.PLAYER_PANEL,
|
||||
panelInfo: {
|
||||
const videoClick = useCallback(() => {
|
||||
dispatch(startVideoPlayer({
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
shptmBanrTpNm: randomData.shptmBanrTpNm,
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
modal: false,
|
||||
modalContainerId: spotlightId, //to calc width, height, left, top
|
||||
modalClassName:css.videoModal
|
||||
}));
|
||||
},[randomData, spotlightId]);
|
||||
|
||||
// 투데이즈 딜 가격 정보
|
||||
const { originalPrice, discountedPrice, discountRate, offerInfo } =
|
||||
@@ -260,26 +265,7 @@ export default function RandomUnit({
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{/* 비디오 오류, 비디오 포커스 상태, 라이브 일 경우 */}
|
||||
{videoError === true &&
|
||||
videoIsPlaying === true &&
|
||||
randomData.shptmBanrTpNm === "LIVE" ? (
|
||||
<div className={css.errorContents}>
|
||||
<div>
|
||||
<CustomImage
|
||||
delay={0}
|
||||
className={css.errorlogo}
|
||||
src={randomData.patncLogoPath}
|
||||
animationSpeed="fast"
|
||||
/>
|
||||
<p className={css.errorText}>
|
||||
Click the screen to see more products!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{videoIsPlaying === false ? (
|
||||
{/* 비디오 오류, --> Player 내부로 이동 */}
|
||||
<div
|
||||
className={classNames(
|
||||
css.itemBox,
|
||||
@@ -305,19 +291,6 @@ export default function RandomUnit({
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<TVideoPlayer
|
||||
showUrl={randomData.showUrl}
|
||||
className={""}
|
||||
videoIsPlaying={videoIsPlaying}
|
||||
width={randomData.vtctpYn === "Y" ? 486 : 744}
|
||||
height={randomData.vtctpYn === "Y" ? 858 : 420}
|
||||
videoErrorCheck={videoErrorCheck}
|
||||
videoType={randomData.shptmBanrTpNm}
|
||||
/>
|
||||
)}
|
||||
|
||||
{videoError === false ? (
|
||||
<p className={css.brandIcon}>
|
||||
<CustomImage
|
||||
delay={0}
|
||||
@@ -325,7 +298,7 @@ export default function RandomUnit({
|
||||
animationSpeed="fast"
|
||||
/>
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
</SpottableComponent>
|
||||
) : randomData.shptmBanrTpNm == "Today's Deals" ? (
|
||||
<SpottableComponent
|
||||
|
||||
@@ -185,3 +185,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.videoModal::after {
|
||||
.focused(@boxShadow:22px, @borderRadius: 12px);
|
||||
}
|
||||
@@ -69,8 +69,8 @@ export default function MainView() {
|
||||
const [tabActivated, setTabActivated] = useState(false);
|
||||
|
||||
const isOnTop = useMemo(() => {
|
||||
return !mainIndex && panels.length <= 0;
|
||||
}, [mainIndex, panels.length]);
|
||||
return !mainIndex && (panels.length <= 0 || (panels.length===1 && panels[0].panelInfo.modal));
|
||||
}, [mainIndex, panels]);
|
||||
|
||||
const onPreImageLoadComplete = useCallback(() => {
|
||||
console.log("MainView onPreImageLoadComplete");
|
||||
@@ -79,9 +79,36 @@ export default function MainView() {
|
||||
|
||||
const renderTopPanel = useCallback(() => {
|
||||
if (panels && panels.length > 0) {
|
||||
let renderringPanels = [];
|
||||
if(panels[panels.length-1]?.name === Config.panel_names.PLAYER_PANEL ||
|
||||
panels[panels.length-2]?.name === Config.panel_names.PLAYER_PANEL
|
||||
){
|
||||
renderringPanels = panels.slice(-2);
|
||||
}else{
|
||||
renderringPanels = panels.slice(-1);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{isOnTop &&
|
||||
<HomePanel isOnTop={isOnTop} />
|
||||
}
|
||||
{renderringPanels.map((panel, index) => {
|
||||
const Component = panelMap[panel.name];
|
||||
//render last two panels if there's videoplayer
|
||||
return <Component
|
||||
key={panel.name+(panels.indexOf(panel))}//to maintain react virtual dom
|
||||
panelInfo={panel.panelInfo}
|
||||
spotlightId={panel.name}
|
||||
isTabActivated={tabActivated}
|
||||
isOnTop={index===(renderringPanels.length-1)}
|
||||
/>
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
/*
|
||||
const panel = panels[panels.length - 1];
|
||||
const Component = panelMap[panel.name];
|
||||
|
||||
return (
|
||||
<Component
|
||||
panelInfo={panel.panelInfo}
|
||||
@@ -89,10 +116,12 @@ export default function MainView() {
|
||||
isTabActivated={tabActivated}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
*/
|
||||
} else if(isOnTop){
|
||||
return <HomePanel isOnTop={isOnTop} />;
|
||||
}
|
||||
}, [panels]);
|
||||
return null;
|
||||
}, [panels, tabActivated, isOnTop]);
|
||||
|
||||
const onTabActivated = useCallback((activated) => {
|
||||
setTabActivated(activated);
|
||||
@@ -100,7 +129,12 @@ export default function MainView() {
|
||||
|
||||
const topPanelName = useMemo(() => {
|
||||
if (panels && panels.length > 0) {
|
||||
return panels[panels.length - 1].name;
|
||||
let targetName = panels[panels.length - 1].name;
|
||||
if(panels[panels.length - 1].name === Config.panel_names.PLAYER_PANEL
|
||||
&& panels[panels.length - 1].panelInfo.modal){
|
||||
targetName = panels[panels.length - 2]?.name;
|
||||
}
|
||||
return targetName;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -108,9 +142,14 @@ export default function MainView() {
|
||||
|
||||
useEffect(() => {
|
||||
if (panels && panels.length > 0) {
|
||||
const panel = panels[panels.length - 1];
|
||||
|
||||
Spotlight.focus(panel.name);
|
||||
let panel = panels[panels.length - 1];
|
||||
if(panels[panels.length - 1].name === Config.panel_names.PLAYER_PANEL
|
||||
&& panels[panels.length - 1].panelInfo.modal){
|
||||
panel = panels[panels.length - 2];
|
||||
}
|
||||
if(panel?.name){
|
||||
Spotlight.focus(panel?.name);
|
||||
}
|
||||
}
|
||||
}, [panels]);
|
||||
|
||||
@@ -155,11 +194,9 @@ export default function MainView() {
|
||||
showLoadingPanel.type === "launching" ? css.transparent : null
|
||||
)}
|
||||
>
|
||||
{isOnTop ? (
|
||||
<HomePanel isOnTop={isOnTop} />
|
||||
) : (
|
||||
{
|
||||
<div className={classNames(css.mainlayout)}>{renderTopPanel()}</div>
|
||||
)}
|
||||
}
|
||||
<TabLayout
|
||||
topPanelName={topPanelName}
|
||||
onTabActivated={onTabActivated}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ export default function PlayerOverlayHeader({
|
||||
onClick,
|
||||
setSelectedIndex,
|
||||
}) {
|
||||
const onClickBack = () => {
|
||||
const onClickBack = (ev) => {
|
||||
if (onClick) {
|
||||
onClick();
|
||||
onClick(ev);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
} from "../../actions/mainActions";
|
||||
import * as PanelActions from "../../actions/panelActions";
|
||||
import { updatePanel } from "../../actions/panelActions";
|
||||
import { getChatLog, getSubTitle } from "../../actions/playActions";
|
||||
import { getChatLog, getSubTitle, startVideoPlayer } from "../../actions/playActions";
|
||||
import { MediaControls } from "../../components/MediaPlayer";
|
||||
import TButton from "../../components/TButton/TButton";
|
||||
import TButtonTab, { LIST_TYPE } from "../../components/TButtonTab/TButtonTab";
|
||||
@@ -53,12 +53,12 @@ const unableToPlay = new Job((callback) => {
|
||||
// callback();
|
||||
}, 5000);
|
||||
|
||||
const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
const PlayerPanel = ({ hideChildren, isTabActivated, panelInfo, isOnTop, ...props }) => {
|
||||
const dispatch = useDispatch();
|
||||
const videoPlayer = useRef(null);
|
||||
const [playListInfo, setPlayListInfo] = useState("");
|
||||
const [shopNowInfo, setShopNowInfo] = useState();
|
||||
const [panelInfo, setPaneInfo] = useState([]);
|
||||
const [modalStyle, setModalStyle] = useState({});
|
||||
const [tab, setTab] = useState(0);
|
||||
const [sideOpen, setSideOpen] = useState(true);
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
@@ -81,22 +81,27 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
|
||||
];
|
||||
|
||||
// 패널 정보 받기
|
||||
const getPanelInfo = useCallback(() => {
|
||||
if (panels) {
|
||||
for (let i = 0; i < panels.length; i++) {
|
||||
if (panels[i].name === "playerpanel") {
|
||||
setPaneInfo(panels[i].panelInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [panels]);
|
||||
|
||||
const onClickBack = useCallback(
|
||||
(ev) => {
|
||||
console.log('yhcho onClickBack', panelInfo);
|
||||
//modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감.
|
||||
if(panelInfo.modalContainerId && !panelInfo.modal){
|
||||
dispatch(startVideoPlayer({
|
||||
...panelInfo,
|
||||
modal: true,
|
||||
}));
|
||||
videoPlayer.current?.hideControls();
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
return;
|
||||
}
|
||||
if(!panelInfo.modal){
|
||||
dispatch(PanelActions.popPanel());
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
}
|
||||
},
|
||||
[dispatch]
|
||||
[dispatch, panelInfo]
|
||||
);
|
||||
|
||||
const handleItemClick = useCallback(
|
||||
@@ -127,11 +132,6 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
];
|
||||
setPlayListInfo(updatedPlayListInfo);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getPanelInfo();
|
||||
}, [panels, panelInfo, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (panelInfo) {
|
||||
dispatch(
|
||||
@@ -160,7 +160,7 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [dispatch, panelInfo, selectedIndex, panels]);
|
||||
}, [dispatch, panelInfo, selectedIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (panelInfo?.shptmBanrTpNm === "LIVE") {
|
||||
@@ -172,7 +172,7 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [panelInfo, playListInfo]);
|
||||
}, [panelInfo?.shptmBanrTpNm, playListInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -246,43 +246,75 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
}, [isActive]);
|
||||
|
||||
useEffect(() => {
|
||||
if(!panelInfo.modal){
|
||||
if (panelInfo && shopNowInfo) {
|
||||
Spotlight.focus("playVideoShopNowBox");
|
||||
Spotlight.focus(`spotlightId-video-${panelInfo.index}`);
|
||||
return;
|
||||
}
|
||||
Spotlight.focus("hotpicks-close-arrow");
|
||||
}
|
||||
}, [panelInfo, shopNowInfo, playListInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if(panelInfo.modal && panelInfo.modalContainerId){
|
||||
const node = document.querySelector(`[data-spotlight-id="${panelInfo.modalContainerId}"]`);
|
||||
if(node){
|
||||
const {width, height, top, left} = node.getBoundingClientRect();
|
||||
const modalStyle = {width: width+'px', height: height+'px', top: top+'px', left: left+'px', position: 'fixed'};
|
||||
setModalStyle(modalStyle);
|
||||
dispatch(updatePanel({name: panel_names.PLAYER_PANEL, panelInfo: {modalStyle: modalStyle}}));
|
||||
}else{
|
||||
setModalStyle(panelInfo.modalStyle);
|
||||
console.error('PlayerPanel modalContainerId node not found', panelInfo.modalContainerId);
|
||||
}
|
||||
}else if(isOnTop && !panelInfo.modal && videoPlayer.current?.getMediaState()?.paused){
|
||||
videoPlayer.current.play();
|
||||
}
|
||||
}, [panelInfo, isOnTop]);
|
||||
|
||||
const cannotPlay = useMemo(()=>{
|
||||
const topPanel = panels[panels.length-1];
|
||||
return !isOnTop && topPanel?.name === panel_names.PLAYER_PANEL;
|
||||
},[panels, isOnTop]);
|
||||
|
||||
delete props.panelInfo;
|
||||
|
||||
|
||||
const getPlayer = useCallback((ref) => {
|
||||
videoPlayer.current = ref;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<TPanel isTabActivated={false} {...props} className={css.videoContainer}>
|
||||
<TPanel isTabActivated={false} {...props} className={classNames(css.videoContainer, panelInfo.modal && css.modal, !isOnTop && css.background)} handleCancel={onClickBack}>
|
||||
<VideoPlayer
|
||||
// setApiProvider={getPlayer}
|
||||
setApiProvider={getPlayer}
|
||||
disabled={panelInfo.modal}
|
||||
onEnded={onClickBack} // 플레이어가 끝날때 호출
|
||||
noAutoPlay={false} // 오토플레이
|
||||
noAutoPlay={cannotPlay} // 오토플레이
|
||||
autoCloseTimeout={100000000000000} // 컨트롤 버튼 숨기는 시간
|
||||
playListInfo={playListInfo && playListInfo[selectedIndex]} // 비디오 데이터
|
||||
onBackButton={onClickBack} // 뒤로가기 버튼
|
||||
panelInfo={panelInfo} // 패널정보 (라이브,VOD)
|
||||
setSelectedIndex={setSelectedIndex} // 선택한 인덱스 Set
|
||||
selectedIndex={selectedIndex} // 선택한 인덱스
|
||||
spotlightDisabled={sideOpen}
|
||||
spotlightDisabled={sideOpen || panelInfo.modal}
|
||||
src={playListInfo && playListInfo[selectedIndex]?.showUrl}
|
||||
style={panelInfo.modal ? modalStyle : {}}
|
||||
modalClassName={panelInfo.modal && panelInfo.modalClassName}
|
||||
>
|
||||
<source
|
||||
src={playListInfo && playListInfo[selectedIndex]?.showUrl}
|
||||
type="application/mpegurl"
|
||||
/>
|
||||
<track
|
||||
{/* <track
|
||||
kind="subtitles"
|
||||
src={vodSubtitleData && vodSubtitleData}
|
||||
srclang="en"
|
||||
label="English"
|
||||
type="text/vtt"
|
||||
default
|
||||
/>
|
||||
/> */}
|
||||
{/* 테스트 */}
|
||||
{/* <source
|
||||
src={
|
||||
@@ -299,7 +331,7 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
/> */}
|
||||
</VideoPlayer>
|
||||
{/* 리액트 플레이어 테스트용 */}
|
||||
{typeof window === "object" && window.PalmSystem ? (
|
||||
{/* {typeof window === "object" && window.PalmSystem ? (
|
||||
""
|
||||
) : (
|
||||
<>
|
||||
@@ -314,7 +346,7 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
<SpottableBtn className={css.videoReduce} onClick={onClickBack} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
)} */}
|
||||
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
|
||||
<VideoOverlayWithPhoneNumber
|
||||
className={css.videoOverlayWithPhoneNumber}
|
||||
@@ -362,7 +394,6 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
<LiveChannelContents
|
||||
setSelectedIndex={setSelectedIndex}
|
||||
liveInfos={playListInfo}
|
||||
setPaneInfo={setPaneInfo}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -375,4 +406,20 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayerPanel;
|
||||
const propsAreEqual = (prev, next) => {
|
||||
const keys = Object.keys(prev);
|
||||
const nextKeys = Object.keys(next);
|
||||
if(keys.length !== nextKeys.length){
|
||||
return false;
|
||||
}
|
||||
for(let i=0; i<keys.length; i++){
|
||||
if(prev[keys[i]] !== next[keys[i]]){
|
||||
if (JSON.stringify(prev[keys[i]]) === JSON.stringify(next[keys[i]])) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export default React.memo(PlayerPanel, propsAreEqual);
|
||||
@@ -1,9 +1,10 @@
|
||||
@import "../../style/CommonStyle.module.less";
|
||||
@import "../../style/utils.module.less";
|
||||
|
||||
@videoBackgroundColor: black;
|
||||
.videoContainer {
|
||||
position: relative;
|
||||
|
||||
background-color: @videoBackgroundColor;
|
||||
.playButton {
|
||||
.size(@w: 60px, @h: 60px);
|
||||
background-image: url("../../../assets/images/btn/btn-video-play-nor@3x.png");
|
||||
@@ -156,4 +157,19 @@
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
&.modal,
|
||||
&.background{
|
||||
width:1px;
|
||||
height: 1px;
|
||||
left: -1px;
|
||||
top: -1px;
|
||||
pointer-events: none;
|
||||
background-color: @videoBackgroundColor;
|
||||
.videoOverlayWithPhoneNumber,
|
||||
.tabContainer,
|
||||
.arrow,
|
||||
.toOpenBtn{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ export default function ShopNowContents({ shopNowInfo }) {
|
||||
panelInfo: {
|
||||
patnrId,
|
||||
prdtId,
|
||||
launchedFromPlayer: true
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user