playerPanel API연동 및 컴포넌트 구조분해

This commit is contained in:
고동영
2024-04-02 17:15:56 +09:00
parent 3522eaf610
commit b4f8400695
20 changed files with 602 additions and 114 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -113,4 +113,8 @@ export const types = {
// order actions
SET_PURCHASE_TERMS_AGREE: "SET_PURCHASE_TERMS_AGREE",
SET_PURCHASE_TERMS_WITHDRAW: "SET_PURCHASE_TERMS_WITHDRAW",
// play controller
GET_CHAT_LOG: "GET_CHAT_LOG",
GET_SUBTITLE: "GET_SUBTITLE",
};

View File

@@ -0,0 +1,62 @@
import { URLS } from '../api/apiConfig';
import { TAxios } from '../api/TAxios';
import { types } from './actionTypes';
// 채팅 로그 가져오기 IF-LGSP-371
export const getChatLog =
({ patnrId, showId }) =>
(dispatch, getState) => {
const onSuccess = (response) => {
console.log("getChatLog onSuccess", response.data);
dispatch({
type: types.GET_CHAT_LOG,
payload: response.data.data,
});
};
const onFail = (error) => {
console.error("getChatLog onFail", error);
};
TAxios(
dispatch,
getState,
"get",
URLS.CHAT_LOG,
{ patnrId, showId },
{},
onSuccess,
onFail
);
};
// VOD 자막 가져오기 IF-LGSP-072
export const getSubTitle =
({ patnrId, showId }) =>
(dispatch, getState) => {
console.log("#patnrId, showId ", patnrId, showId);
const onSuccess = (response) => {
console.log("getSubTitle onSuccess", response.data);
dispatch({
type: types.GET_SUBTITLE,
payload: response.data.data,
});
};
const onFail = (error) => {
console.error("getSubTitle onFail", error);
};
TAxios(
dispatch,
getState,
"get",
URLS.SUBTITLE,
{ patnrId, showId },
{},
onSuccess,
onFail
);
};

View File

@@ -96,6 +96,10 @@ export const URLS = {
// app controller
SEND_SMS: "/lgsp/v1/app/sms.lge",
// play controller
CHAT_LOG: "/lgsp/v1/play/vod/chatLog.lge",
SUBTITLE: "/lgsp/v1/play/vod/subtitle.lge",
// order controller
SET_PURCHASE_TERMS_AGREE: "/lgsp/v1/myinfo/purchaseTerms/agree.lge",
SET_PURCHASE_TERMS_WITHDRAW: "/lgsp/v1/myinfo/purchaseTerms/withdraw.lge",

View File

@@ -299,3 +299,10 @@
}
}
}
.qrPopup {
.default-style();
.info {
.size(@w: 780px , @h: 750px);
}
}

View File

@@ -1,4 +1,4 @@
import { types } from "../actions/actionTypes";
import { types } from '../actions/actionTypes';
const initialState = {
subCategoryData: {},
@@ -72,9 +72,11 @@ export const mainReducer = (state = initialState, action) => {
case types.GET_MAIN_LIVE_SHOW_NOW_PRODUCT: {
const data = action.payload;
return {
...state,
showNowProduct: data.productInfos,
showNowInfo: action.payload,
};
}

View File

@@ -0,0 +1,20 @@
import { types } from '../actions/actionTypes';
const initialState = {};
export const playReducer = (state = initialState, action) => {
switch (action.type) {
case types.GET_CHAT_LOG:
return {
...state,
chatData: action.payload,
};
case types.GET_SUBTITLE:
return {
...state,
subTitle: action.payload,
};
default:
return state;
}
};

View File

@@ -1,24 +1,29 @@
import { applyMiddleware, combineReducers, createStore } from "redux";
import thunk from "redux-thunk";
import {
applyMiddleware,
combineReducers,
createStore,
} from 'redux';
import thunk from 'redux-thunk';
import { appDataReducer } from "../reducers/appDataReducer";
import { billingReducer } from "../reducers/billingReducer";
import { brandReducer } from "../reducers/brandReducer";
import { cardReducer } from "../reducers/cardReducer";
import { checkoutReducer } from "../reducers/checkoutReducer";
import { commonReducer } from "../reducers/commonReducer";
import { couponReducer } from "../reducers/couponReducer";
import { deviceReducer } from "../reducers/deviceReducer";
import { eventReducer } from "../reducers/eventReducer";
import { homeReducer } from "../reducers/homeReducer";
import { localSettingsReducer } from "../reducers/localSettingsReducer";
import { mainReducer } from "../reducers/mainReducer";
import { myPageReducer } from "../reducers/myPageReducer";
import { onSaleReducer } from "../reducers/onSaleReducer";
import { panelsReducer } from "../reducers/panelReducer";
import { productReducer } from "../reducers/productReducer";
import { searchReducer } from "../reducers/searchReducer";
import { shippingReducer } from "../reducers/shippingReducer";
import { appDataReducer } from '../reducers/appDataReducer';
import { billingReducer } from '../reducers/billingReducer';
import { brandReducer } from '../reducers/brandReducer';
import { cardReducer } from '../reducers/cardReducer';
import { checkoutReducer } from '../reducers/checkoutReducer';
import { commonReducer } from '../reducers/commonReducer';
import { couponReducer } from '../reducers/couponReducer';
import { deviceReducer } from '../reducers/deviceReducer';
import { eventReducer } from '../reducers/eventReducer';
import { homeReducer } from '../reducers/homeReducer';
import { localSettingsReducer } from '../reducers/localSettingsReducer';
import { mainReducer } from '../reducers/mainReducer';
import { myPageReducer } from '../reducers/myPageReducer';
import { onSaleReducer } from '../reducers/onSaleReducer';
import { panelsReducer } from '../reducers/panelReducer';
import { playReducer } from '../reducers/playReducer';
import { productReducer } from '../reducers/productReducer';
import { searchReducer } from '../reducers/searchReducer';
import { shippingReducer } from '../reducers/shippingReducer';
const rootReducer = combineReducers({
panels: panelsReducer,
@@ -39,6 +44,7 @@ const rootReducer = combineReducers({
billing: billingReducer,
shipping: shippingReducer,
checkout: checkoutReducer,
play: playReducer,
});
export const store = createStore(rootReducer, applyMiddleware(thunk));

View File

@@ -49,6 +49,7 @@ export const ACTIVE_POPUP = {
favoritePopup: "favoritePopup",
loginPopup: "loginPopup",
alarmOffPopup: "alarmOffPopup",
qrPopup: "qrPopup",
};
export const AUTO_SCROLL_DELAY = 600;

View File

@@ -1,23 +1,29 @@
import React, { useEffect, useState } from "react";
import React, {
useEffect,
useState,
} from 'react';
import { useDispatch, useSelector } from "react-redux";
import {
useDispatch,
useSelector,
} from 'react-redux';
import {
getThemeCurationDetailInfo,
getThemeHotelDetailInfo,
} from "../../actions/homeActions";
import { getMainCategoryDetail } from "../../actions/mainActions";
import { popPanel } from "../../actions/panelActions";
import { getProductGroup } from "../../actions/productActions";
import TBody from "../../components/TBody/TBody";
import THeader from "../../components/THeader/THeader";
import TPanel from "../../components/TPanel/TPanel";
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";
} from '../../actions/homeActions';
import { getMainCategoryDetail } from '../../actions/mainActions';
import { popPanel } from '../../actions/panelActions';
import { getProductGroup } from '../../actions/productActions';
import TBody from '../../components/TBody/TBody';
import THeader from '../../components/THeader/THeader';
import TPanel from '../../components/TPanel/TPanel';
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';
export default function ItemDetail() {
const [selectedPatnrId, setSelectedPatnrId] = useState("");
@@ -27,6 +33,7 @@ export default function ItemDetail() {
const [selectedIndex, setSelectedIndex] = useState(0);
const productData = useSelector((state) => state.main.productData);
const themeData = useSelector((state) => state.home.productData);
const panels = useSelector((state) => state.panels.panels);
const hotelData = useSelector((state) => state.home.hotelData);
const productInfo = useSelector(
@@ -91,6 +98,7 @@ export default function ItemDetail() {
const onClick = () => {
dispatch(popPanel());
};
return (
<TPanel isTabActivated={false}>
<THeader
@@ -98,7 +106,7 @@ export default function ItemDetail() {
title={
(selectedPrdtId && productData?.prdtNm) ||
(themeType === "hotel" && hotelData?.hotelInfo.curationNm) ||
(themeType === "theme" && productInfo[selectedIndex]?.prdtNm)
(themeType === "theme" && themeData?.themeInfo[0]?.curationNm)
}
onBackButton
onClick={onClick}

View File

@@ -0,0 +1,66 @@
import React, { useCallback } from 'react';
import {
useDispatch,
useSelector,
} from 'react-redux';
import Spottable from '@enact/spotlight/Spottable';
import {
setHidePopup,
setShowPopup,
} from '../../../actions/commonActions';
import TButton from '../../../components/TButton/TButton';
import TPopUp from '../../../components/TPopUp/TPopUp';
import TQRCode from '../../../components/TQRCode/TQRCode';
import { ACTIVE_POPUP } from '../../../utils/Config';
import { $L } from '../../../utils/helperMethods';
import css from './PlayerOverlayChat.module.less';
const SpottableBtn = Spottable("button");
export default function PlayerOverlayChat() {
const dispatch = useDispatch();
const { popupVisible, activePopup } = useSelector(
(state) => state.common.popup
);
const handleQRCodeClick = useCallback(() => {
dispatch(setShowPopup(ACTIVE_POPUP.qrPopup));
}, [dispatch]);
const onClose = useCallback(() => {
dispatch(setHidePopup());
}, [dispatch]);
return (
<>
<div className={css.chatContainer}>
<div className={css.chatHeader} />
<div className={css.contents} />
<TButton className={css.messageBtn} onClick={handleQRCodeClick}>
{"TYPE A MESSAGE"}
</TButton>
</div>
{activePopup === ACTIVE_POPUP.qrPopup && (
<TPopUp kind="qrPopup" open={popupVisible} onClose={onClose}>
<div className={css.popupContainer}>
<div className={css.header}>
<h3>{$L("QR CODE")}</h3>
</div>
<div className={css.qrcodeContainer}>
<div className={css.qrcode}>
<TQRCode text="" width="" height="" />
</div>
<h3>{$L("To send a message, please scan the QR code.")}</h3>
<TButton className={css.popupBtn} onClick={onClose}>
{$L("CLOSE")}
</TButton>
</div>
</div>
</TPopUp>
)}
</>
);
}

View File

@@ -0,0 +1,65 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.chatContainer {
.size(@w: 402px , @h: 640px);
.position(@position: absolute, @top: auto, @right: auto, @bottom: 220px, @left: 60px);
padding: 21px 18px 18px 18px;
background-color: #1e1e1e;
border-radius: 10px;
.messageBtn {
.size(@w: 366px , @h: 60px);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: auto;
font-size: 24px;
font-weight: bold;
line-height: 1.33;
&:focus {
background-color: #c70850;
}
}
}
.popupContainer {
.header {
.size(@w: 780px , @h: 102px);
.flex(@display: flex, @justifyCenter: "", @alignCenter: center, @direction: row);
padding-left: 61px;
background-color: #e7ebef;
> h3 {
font-size: 36px;
color: #222222;
font-weight: bold;
}
}
.qrcodeContainer {
padding: 30px 210px 30px 210px;
.qrcode {
.size(@w: 360px , @h: 360px);
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 0 0 1px #dadada inset;
margin-bottom: 41px;
}
> h3 {
.size(@w: 319px , @h: 67px);
display: flex;
text-align: center;
word-break: break-word;
line-height: 1.27;
}
.popupBtn {
.size(@w: 300px , @h: 78px);
margin-top: 38px;
}
}
}

View File

@@ -0,0 +1,45 @@
import React from 'react';
import classNames from 'classnames';
import Spottable from '@enact/spotlight/Spottable';
import { $L } from '../../../utils/helperMethods';
import css from './PlayerOverlayHeader.module.less';
const SpottableBtn = Spottable("button");
export default function PlayerOverlayHeader({
panelInfo,
playListInfo,
selectedIndex,
onClick,
}) {
const onClickBack = () => {
if (onClick) {
onClick();
}
};
return (
<>
<div className={classNames(css.overIcon, css.backLiveicon)}>
<SpottableBtn onClick={onClickBack} className={css.backIcon} />
<div className={panelInfo?.type === "LIVE" && css.liveIcon} />
<img src={playListInfo[selectedIndex]?.patncLogoPath} alt="" />
<h2 className={css.patnerName}>
{playListInfo[selectedIndex]?.patncNm}
</h2>
<h3 className={css.title}>{playListInfo[selectedIndex]?.showNm}</h3>
</div>
{playListInfo && (
<div className={css.disclaimer}>
<span className={css.icon} />
<h3>
{$L(
"This program was previously recorded. Offers, pricing, and availability may have changed."
)}
</h3>
</div>
)}
</>
);
}

View File

@@ -0,0 +1,100 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.overIcon {
position: absolute;
z-index: 2;
&.backLiveicon {
display: flex;
top: 66px;
left: 60px;
.backIcon {
.size(@w: 60px, @h: 60px);
background-size: contain;
background-image: url("../../../../assets/images/btn/btn-60-wh-back-nor@3x.png");
&:focus {
background-image: url("../../../../assets/images/btn/btn-60-wh-back-foc@3x.png");
}
}
.liveIcon {
margin: 6px 0 6px 30px;
.size(@w: 108px, @h: 48px);
background-size: contain;
background-image: url("../../../../assets/images/tag-liveshow.png");
vertical-align: top;
}
}
// logo
> img {
margin-left: 30px;
}
.patnerName {
font-size: 44px;
font-weight: bold;
color: #fcfcfc;
align-items: center;
display: flex;
margin-left: 14px;
}
.title {
display: flex;
align-items: center;
font-size: 44px;
color: #fcfcfc;
margin-left: 35px;
}
&.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");
}
}
}
}
.disclaimer {
.size(@w: 1800px , @h: 54px);
display: flex;
background-color: #000000;
opacity: 0.5;
position: absolute;
top: 140px;
left: 60px;
align-items: center;
> span {
.size(@w: 18px , @h: 18px);
background-image: url("../../../../assets/images/icons/ic-alert-20@3x.png");
background-position: center;
background-size: cover;
margin: 0 12px 0 20px;
}
> h3 {
color: #ffffff;
font-size: 20px;
}
}

View File

@@ -0,0 +1,20 @@
import React from 'react';
import TQRCode from '../../../components/TQRCode/TQRCode';
import { $L } from '../../../utils/helperMethods';
import css from './PlayerOverlayQRCode.module.less';
export default function PlayerOverlayQRCode() {
return (
<div className={css.container}>
<div className={css.qrWrap}>
<TQRCode text="" width="" height="" />
</div>
<div className={css.text}>
<p>{$L("Unable to retrieve chat history.")}</p>
<p>{$L("Scan the QR code to go to the partner's homepage.")}</p>
</div>
</div>
);
}

View File

@@ -0,0 +1,35 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
.size(@w: 402px , @h: 640px);
.position(@position: absolute, @top: auto, @right: auto, @bottom: 220px, @left: 60px);
.flex(@display: flex, @justifyCenter: "", @alignCenter: center, @direction: column);
padding: 21px 18px 18px 18px;
background-color: #1e1e1e;
border-radius: 10px;
padding: 70px 18px 70px 18px;
border: solid 2px rgba(255, 255, 255, 0.7);
box-shadow: 5px 8.7px 15px 0 rgba(6, 0, 1, 0.5);
font-size: 30px;
line-height: 1.27;
color: #808080;
border-top: solid 3px #ffffff;
.qrWrap {
.size(@w: 252px , @h: 252px);
background-color: #ffffff;
border-radius: 6px;
box-shadow: 0 0 0 1px #dadada inset;
}
.text {
// .size(@w: 345px , @h: 181px);
display: flex;
text-align: center;
flex-wrap: wrap;
word-break: break-word;
margin: 48px 0 70px 0;
}
}

View File

@@ -2,7 +2,6 @@ import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
@@ -25,16 +24,18 @@ import {
getMainLiveShowNowProduct,
} from '../../actions/mainActions';
import * as PanelActions from '../../actions/panelActions';
import { getChatLog } from '../../actions/playActions';
import { MediaControls } from '../../components/MediaPlayer';
import TButton from '../../components/TButton/TButton';
import TButtonTab, { LIST_TYPE } from '../../components/TButtonTab/TButtonTab';
import TItemCard, { TYPES } from '../../components/TItemCard/TItemCard';
import TPanel from '../../components/TPanel/TPanel';
import TVirtualGridList
from '../../components/TVirtualGridList/TVirtualGridList';
import VideoOverlayWithPhoneNumber
from '../../components/VideoOverlayWithPhoneNumber/VideoOverlayWithPhoneNumber';
import { VideoPlayer } from '../../components/VideoPlayer/VideoPlayer';
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';
@@ -42,7 +43,6 @@ import ShopNowContents from './PlayerTabContents/ShopNowContents';
import YouMayLikeContents from './PlayerTabContents/YouMayLikeContents';
const SpottableBtn = Spottable("button");
const SpottableComponent = Spottable("div");
const Container = SpotlightContainerDecorator(
{ enterTo: "default-element", preserveId: true },
"div"
@@ -61,16 +61,22 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
const [sideOpen, setSideOpen] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
const featuredShowsInfos = useSelector(
(state) => state.main.featuredShowsInfos
);
const liveChannelInfos = useSelector((state) => state.main.liveChannelInfos);
const showNowProduct = useSelector((state) => state.main.showNowProduct);
const data = useSelector((state) => state.main.data);
const fullVideoData = useSelector((state) => state.main.fullVideoData);
const panels = useSelector((state) => state.panels.panels);
console.log("#data", data);
const tabList = [
$L("SHOP NOW"),
$L(panelInfo.type === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
];
const onClickBack = useCallback(
(ev) => {
console.log("onClickBack ev...", ev);
dispatch(PanelActions.popPanel());
},
[dispatch]
@@ -126,26 +132,20 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
}
}, [panelInfo]);
// const getVideoArrayIndex = () => {
// switch (panelInfo.type) {
// case "VOD":
// if (featuredShowsInfos && featuredShowsInfos.length > 0) {
// console.log("#panel", panelInfo.showId);
// console.log("#panel", featuredShowsInfos);
// for (let i = 0; i < featuredShowsInfos.length; i++) {
// if (featuredShowsInfos[i].showId === panelInfo.showId) {
// setSelectedIndex(i);
// console.log("#selectedIndex", selectedIndex);
// }
// }
// }
// break;
// case "LIVE":
// "";
// break;
// }
// };
const handleUpClick = () => {
if (selectedIndex !== 0) {
setSelectedIndex((prev) => prev + 1);
}
};
const handleDownClick = () => {
if (selectedIndex.length - 1 === selectedIndex) {
return;
}
setSelectedIndex((prev) => prev + 1);
};
console.log("#fullVideoData", fullVideoData);
useEffect(() => {
getPanelInfo();
}, [panels, panelInfo, dispatch]);
@@ -164,19 +164,47 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
showId: panelInfo.showId,
})
);
}
}, [dispatch, panelInfo]);
// useEffect(() => {
// getVideoArrayIndex();
// }, [featuredShowsInfos, selectedIndex]);
dispatch(
getChatLog({ patnrId: panelInfo.patnrId, showId: panelInfo.showId })
);
}
}, [dispatch, panelInfo, selectedIndex]);
useEffect(() => {
console.log("#fullVideoData", fullVideoData);
console.log("#panelInfo", panelInfo);
if (panelInfo.type === "LIVE") {
setPlayListInfo(liveChannelInfos);
} else if (panelInfo.type === "VOD") {
setPlayListInfo(featuredShowsInfos);
}
}, [featuredShowsInfos, liveChannelInfos, selectedIndex]);
console.log("#selectedTab", tab);
}, [fullVideoData]);
useEffect(() => {
switch (panelInfo.type) {
case "VOD":
if (featuredShowsInfos && featuredShowsInfos.length > 0) {
for (let i = 0; i < featuredShowsInfos.length; i++) {
if (featuredShowsInfos[i].showId === panelInfo.showId) {
setSelectedIndex(i);
}
}
}
break;
case "LIVE":
if (liveChannelInfos && liveChannelInfos.length > 0) {
for (let i = 0; i < liveChannelInfos.length; i++) {
if (liveChannelInfos[i].showId === panelInfo.showId) {
setSelectedIndex(i);
}
}
}
break;
}
}, []);
console.log("#playlist", playListInfo);
console.log("#full", fullVideoData);
console.log("#panelInfo", panelInfo);
useEffect(() => {
if (!isActive) {
@@ -200,14 +228,25 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
noAutoPlay={false} // 오토플레이
backButton={backButton()} // 뒤로가기 버튼
>
<source src={panelInfo.showUrl} type="type=application/mpegurl" />
<source
src={
playListInfo &&
playListInfo.length > 0 &&
playListInfo[selectedIndex].showUrl
}
type="type=application/mpegurl"
/>
<MediaControls></MediaControls>
</VideoPlayer>
) : (
<ReactPlayer
className={""}
url={panelInfo.showUrl} // 플레이어 url
url={
playListInfo &&
playListInfo.length > 0 &&
playListInfo[selectedIndex].showUrl
} // 플레이어 url
playing={true} // 자동 재생 on = true off = false
muted={false} // 자동 재생 on = true off = false
width={"1920"} // 플레이어 크기 (가로)
@@ -216,19 +255,29 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
onEnded={onClickBack} // 플레이어가 끝날때 호출
/>
)}
{/* <Container> */}
<div className={classNames(css.overIcon, css.backLiveicon)}>
<SpottableBtn onClick={onClickBack} className={css.backIcon} />
<div className={panelInfo?.type === "LIVE" && css.liveIcon} />
<div className={css.logo}>{"123"}</div>
</div>
{/* 백버튼, 로고 , 타이틀 */}
<PlayerOverlayHeader
selectedIndex={selectedIndex}
panelInfo={panelInfo}
playListInfo={playListInfo}
onClick={onClickBack}
/>
{/* 인디게이터 버튼 */}
<div className={classNames(css.overIcon, css.topIcon)}>
<SpottableBtn />
<SpottableBtn onClick={handleUpClick} />
</div>
<div className={classNames(css.overIcon, css.downIcon)}>
<SpottableBtn />
<SpottableBtn onClick={handleDownClick} />
</div>
{/* CalltoOrder */}
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
<VideoOverlayWithPhoneNumber
className={css.videoOverlayWithPhoneNumber}
show
/>
)}
{panelInfo?.type === "LIVE" && <PlayerOverlayChat />}
{/* <PlayerOverlayQRCode /> */}
<div
className={classNames(
css.arrow,

View File

@@ -55,6 +55,7 @@
right: 0;
top: 0;
padding: 48px 30px 0 30px;
z-index: 3;
.tTab {
border-radius: 12px;
overflow: hidden;
@@ -69,31 +70,16 @@
}
}
}
.videoOverlayWithPhoneNumber {
bottom: 210px;
left: 60px;
}
.overIcon {
position: absolute;
z-index: 2;
&.backLiveicon {
display: flex;
top: 66px;
left: 60px;
.backIcon {
.size(@w: 60px, @h: 60px);
background-size: contain;
background-image: url("../../../assets/images/btn/btn-60-wh-back-nor@3x.png");
&:focus {
background-image: url("../../../assets/images/btn/btn-60-wh-back-foc@3x.png");
}
}
.liveIcon {
margin: 6px 0 6px 30px;
.size(@w: 108px, @h: 48px);
background-size: contain;
background-image: url("../../../assets/images/tag-liveshow.png");
vertical-align: top;
}
}
&.topIcon {
top: 12px;
left: 936px;

View File

@@ -14,7 +14,7 @@
}
> div {
.size(@w: 311px , @h: 65px);
.size(@w: 311px , @h: 80px);
text-align: center;
}
}

View File

@@ -1,20 +1,28 @@
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 { pushPanel } 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";
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 PlayerTabLoading from './PlayerTabLoading';
import css from './ShopNowContents.module.less';
export default function ShopNowContents() {
const dispatch = useDispatch();
const showNowProduct = useSelector((state) => state.main.showNowProduct);
const [height, setHeight] = useState();
console.log("#showNowProduct", showNowProduct);
const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]);
useEffect(() => {