moment.js 추가 && playerPanel live 프로그래스바 추가
This commit is contained in:
BIN
com.twin.app.shoptime/assets/images/img-contents-loading@3x.png
Normal file
BIN
com.twin.app.shoptime/assets/images/img-contents-loading@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -41,6 +41,7 @@
|
|||||||
"@enact/webos": "^3.3.0",
|
"@enact/webos": "^3.3.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"ilib": "^14.3.0",
|
"ilib": "^14.3.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ export default function HotelOption({
|
|||||||
|
|
||||||
setAmenitiesInfos(amenitiesArr);
|
setAmenitiesInfos(amenitiesArr);
|
||||||
};
|
};
|
||||||
console.log("#am", amenitiesInfos);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { memo, useCallback } from "react";
|
import React, { memo, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
import Spottable from "@enact/spotlight/Spottable";
|
import Spottable from "@enact/spotlight/Spottable";
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ export const removeDotAndColon = (string) => {
|
|||||||
return /[.:]/.test(string) ? string.replace(/[.:]/g, "") : string;
|
return /[.:]/.test(string) ? string.replace(/[.:]/g, "") : string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(function TItemCard({
|
export default memo(function PlayerItemCard({
|
||||||
children,
|
children,
|
||||||
disabled,
|
disabled,
|
||||||
imageAlt,
|
imageAlt,
|
||||||
@@ -45,10 +46,16 @@ export default memo(function TItemCard({
|
|||||||
soldoutFlag,
|
soldoutFlag,
|
||||||
spotlightId,
|
spotlightId,
|
||||||
patnerName,
|
patnerName,
|
||||||
|
startDt,
|
||||||
|
endDt,
|
||||||
|
timezone,
|
||||||
type = TYPES.liveHorizontal,
|
type = TYPES.liveHorizontal,
|
||||||
...rest
|
...rest
|
||||||
}) {
|
}) {
|
||||||
|
const [gaugeWidth, setGaugeWidth] = useState(0);
|
||||||
|
const [focused, setFocused] = useState(false);
|
||||||
const _onBlur = useCallback(() => {
|
const _onBlur = useCallback(() => {
|
||||||
|
setFocused(false);
|
||||||
if (onBlur) {
|
if (onBlur) {
|
||||||
onBlur();
|
onBlur();
|
||||||
}
|
}
|
||||||
@@ -68,11 +75,35 @@ export default memo(function TItemCard({
|
|||||||
[onClick, disabled]
|
[onClick, disabled]
|
||||||
);
|
);
|
||||||
const _onFocus = useCallback(() => {
|
const _onFocus = useCallback(() => {
|
||||||
|
setFocused(true);
|
||||||
if (onFocus) {
|
if (onFocus) {
|
||||||
onFocus();
|
onFocus();
|
||||||
}
|
}
|
||||||
}, [onFocus]);
|
}, [onFocus]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const today = moment();
|
||||||
|
const startDtMoment = moment(startDt);
|
||||||
|
const endDtMoment = moment(endDt);
|
||||||
|
|
||||||
|
//라이브 영상 시간 (분)
|
||||||
|
const liveTime = endDtMoment.diff(startDtMoment, "minutes");
|
||||||
|
//경과시간 (분)
|
||||||
|
const elapsedTime = today.diff(startDtMoment, "minutes");
|
||||||
|
|
||||||
|
const progressPercentage = (elapsedTime / liveTime) * 100;
|
||||||
|
|
||||||
|
if (elapsedTime > 0) {
|
||||||
|
setGaugeWidth(progressPercentage);
|
||||||
|
} else {
|
||||||
|
setGaugeWidth(0);
|
||||||
|
}
|
||||||
|
}, [gaugeWidth]);
|
||||||
|
const progressStyle = useMemo(
|
||||||
|
() => ({ width: `${gaugeWidth}%` }),
|
||||||
|
[gaugeWidth]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SpottableComponent
|
<SpottableComponent
|
||||||
className={classNames(css[type])}
|
className={classNames(css[type])}
|
||||||
@@ -96,6 +127,16 @@ export default memo(function TItemCard({
|
|||||||
<h3 className={css.brandName}>{patnerName}</h3>
|
<h3 className={css.brandName}>{patnerName}</h3>
|
||||||
</div>
|
</div>
|
||||||
<h3 className={css.title}>{productName}</h3>
|
<h3 className={css.title}>{productName}</h3>
|
||||||
|
{endDt && startDt && (
|
||||||
|
<div className={css.progressBarWrap}>
|
||||||
|
<div className={css.progressBar}>
|
||||||
|
<div
|
||||||
|
className={classNames(css.gauge, focused && css.focused)}
|
||||||
|
style={progressStyle}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</SpottableComponent>
|
</SpottableComponent>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -62,6 +62,25 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.progressBarWrap {
|
||||||
|
.progressBar {
|
||||||
|
.size(@w: 344px , @h: 8px);
|
||||||
|
position: relative;
|
||||||
|
background-color: #e7e7e7;
|
||||||
|
|
||||||
|
.gauge {
|
||||||
|
max-width: 344px;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #808080;
|
||||||
|
height: 8px;
|
||||||
|
|
||||||
|
&.focused {
|
||||||
|
background-color: #c70850;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// focused
|
// focused
|
||||||
|
|||||||
@@ -244,9 +244,10 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{tab === 0 && <ShopNowContents />}
|
{tab === 0 && <ShopNowContents />}
|
||||||
{showNowProduct && showNowProduct.length < 3 && tab === 0 && (
|
{showNowProduct !== "undefined" &&
|
||||||
<YouMayLikeContents />
|
showNowProduct &&
|
||||||
)}
|
showNowProduct.length < 3 &&
|
||||||
|
tab === 0 && <YouMayLikeContents />}
|
||||||
{panelInfo.type === "LIVE" && tab === 1 && <LiveChannelContents />}
|
{panelInfo.type === "LIVE" && tab === 1 && <LiveChannelContents />}
|
||||||
{panelInfo.type === "VOD" && tab === 1 && <FeaturedShowContents />}
|
{panelInfo.type === "VOD" && tab === 1 && <FeaturedShowContents />}
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -73,6 +73,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
&.backLiveicon {
|
&.backLiveicon {
|
||||||
|
display: flex;
|
||||||
top: 66px;
|
top: 66px;
|
||||||
left: 60px;
|
left: 60px;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridL
|
|||||||
import { panel_names } from "../../../utils/Config";
|
import { panel_names } from "../../../utils/Config";
|
||||||
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
||||||
import css from "./LiveChannelContents.module.less";
|
import css from "./LiveChannelContents.module.less";
|
||||||
|
import PlayerTabLoading from "./PlayerTabLoading";
|
||||||
|
|
||||||
export default function FeaturedShowContents() {
|
export default function FeaturedShowContents() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -41,7 +42,7 @@ export default function FeaturedShowContents() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
{featuredShowsInfos && featuredShowsInfos.length > 0 && (
|
{featuredShowsInfos && featuredShowsInfos.length > 0 ? (
|
||||||
<TVirtualGridList
|
<TVirtualGridList
|
||||||
dataSize={featuredShowsInfos.length}
|
dataSize={featuredShowsInfos.length}
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
@@ -51,6 +52,8 @@ export default function FeaturedShowContents() {
|
|||||||
spacing={12}
|
spacing={12}
|
||||||
className={css.itemList}
|
className={css.itemList}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<PlayerTabLoading />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
@@ -7,23 +7,25 @@ import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridL
|
|||||||
import { panel_names } from "../../../utils/Config";
|
import { panel_names } from "../../../utils/Config";
|
||||||
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
||||||
import css from "./LiveChannelContents.module.less";
|
import css from "./LiveChannelContents.module.less";
|
||||||
|
import PlayerTabLoading from "./PlayerTabLoading";
|
||||||
|
|
||||||
export default function LiveChannelContents() {
|
export default function LiveChannelContents() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const liveChannelInfos = useSelector((state) => state.main.liveChannelInfos);
|
const liveChannelInfos = useSelector((state) => state.main.liveChannelInfos);
|
||||||
|
|
||||||
console.log("#liveChannelInfos", liveChannelInfos);
|
console.log("#liveChannelInfos", liveChannelInfos);
|
||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
({ index, ...rest }) => {
|
({ index, ...rest }) => {
|
||||||
const {
|
const {
|
||||||
dfltThumbnailImgPath,
|
dfltThumbnailImgPath,
|
||||||
patncLogoPath,
|
patncLogoPath,
|
||||||
patnrId,
|
|
||||||
prdtId,
|
prdtId,
|
||||||
prdtNm,
|
showNm,
|
||||||
priceInfo,
|
|
||||||
offerInfo,
|
|
||||||
patncNm,
|
patncNm,
|
||||||
|
strtDt,
|
||||||
|
endDt,
|
||||||
|
timezone,
|
||||||
} = liveChannelInfos[index];
|
} = liveChannelInfos[index];
|
||||||
|
|
||||||
const handleItemClick = () => {};
|
const handleItemClick = () => {};
|
||||||
@@ -35,8 +37,11 @@ export default function LiveChannelContents() {
|
|||||||
imageAlt={prdtId}
|
imageAlt={prdtId}
|
||||||
logo={patncLogoPath}
|
logo={patncLogoPath}
|
||||||
imageSource={dfltThumbnailImgPath}
|
imageSource={dfltThumbnailImgPath}
|
||||||
productName={prdtNm}
|
productName={showNm}
|
||||||
patnerName={patncNm}
|
patnerName={patncNm}
|
||||||
|
startDt={strtDt}
|
||||||
|
endDt={endDt}
|
||||||
|
timezone={timezone}
|
||||||
onClick={handleItemClick}
|
onClick={handleItemClick}
|
||||||
type={TYPES.liveHorizontal}
|
type={TYPES.liveHorizontal}
|
||||||
/>
|
/>
|
||||||
@@ -47,7 +52,7 @@ export default function LiveChannelContents() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
{liveChannelInfos && liveChannelInfos.length > 0 && (
|
{liveChannelInfos && liveChannelInfos.length > 0 ? (
|
||||||
<TVirtualGridList
|
<TVirtualGridList
|
||||||
dataSize={liveChannelInfos.length}
|
dataSize={liveChannelInfos.length}
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
@@ -57,6 +62,8 @@ export default function LiveChannelContents() {
|
|||||||
spacing={12}
|
spacing={12}
|
||||||
className={css.itemList}
|
className={css.itemList}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<PlayerTabLoading />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
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() {
|
||||||
|
return (
|
||||||
|
<div className={css.loadingContainer}>
|
||||||
|
<img src={loading} alt="" />
|
||||||
|
<div>{$L("Loading Product Details. Please Wait...")}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
@import "../../../style/utils.module.less";
|
||||||
|
.loadingContainer {
|
||||||
|
height: 250px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 30px;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: #8290a0;
|
||||||
|
margin-top: 60px;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
.size(@w: 360px , @h: 174px);
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
.size(@w: 311px , @h: 65px);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,11 @@ 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 { pushPanel } from "../../../actions/panelActions";
|
import { pushPanel } from "../../../actions/panelActions";
|
||||||
import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
|
import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
|
||||||
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
||||||
import { panel_names } from "../../../utils/Config";
|
import { panel_names } from "../../../utils/Config";
|
||||||
|
import PlayerTabLoading from "./PlayerTabLoading";
|
||||||
import css from "./ShopNowContents.module.less";
|
import css from "./ShopNowContents.module.less";
|
||||||
|
|
||||||
export default function ShopNowContents() {
|
export default function ShopNowContents() {
|
||||||
@@ -62,7 +61,7 @@ export default function ShopNowContents() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
{showNowProduct && showNowProduct.length > 0 && (
|
{showNowProduct && showNowProduct.length > 0 ? (
|
||||||
<TVirtualGridList
|
<TVirtualGridList
|
||||||
style={gridStyle}
|
style={gridStyle}
|
||||||
dataSize={showNowProduct.length}
|
dataSize={showNowProduct.length}
|
||||||
@@ -73,6 +72,8 @@ export default function ShopNowContents() {
|
|||||||
spacing={12}
|
spacing={12}
|
||||||
className={css.itemList}
|
className={css.itemList}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<PlayerTabLoading />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
|
|||||||
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
||||||
import { panel_names } from "../../../utils/Config";
|
import { panel_names } from "../../../utils/Config";
|
||||||
import { $L } from "../../../utils/helperMethods";
|
import { $L } from "../../../utils/helperMethods";
|
||||||
|
import PlayerTabLoading from "./PlayerTabLoading";
|
||||||
import css from "./YouMayLikeContents.module.less";
|
import css from "./YouMayLikeContents.module.less";
|
||||||
|
|
||||||
export default function YouMayLikeContents() {
|
export default function YouMayLikeContents() {
|
||||||
@@ -17,6 +18,8 @@ export default function YouMayLikeContents() {
|
|||||||
|
|
||||||
const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]);
|
const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]);
|
||||||
|
|
||||||
|
console.log("#youmaylikeInfos", youmaylikeInfos);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showNowProduct && showNowProduct.length === 2) {
|
if (showNowProduct && showNowProduct.length === 2) {
|
||||||
setHeight(300);
|
setHeight(300);
|
||||||
@@ -65,7 +68,7 @@ export default function YouMayLikeContents() {
|
|||||||
<div className={css.title}>{$L("YOU MAY LIKE")}</div>
|
<div className={css.title}>{$L("YOU MAY LIKE")}</div>
|
||||||
<div className={css.line}></div>
|
<div className={css.line}></div>
|
||||||
|
|
||||||
{youmaylikeInfos && youmaylikeInfos.length > 0 && (
|
{youmaylikeInfos && youmaylikeInfos.length > 0 ? (
|
||||||
<TVirtualGridList
|
<TVirtualGridList
|
||||||
style={gridStyle}
|
style={gridStyle}
|
||||||
dataSize={youmaylikeInfos.length}
|
dataSize={youmaylikeInfos.length}
|
||||||
@@ -76,6 +79,8 @@ export default function YouMayLikeContents() {
|
|||||||
spacing={12}
|
spacing={12}
|
||||||
className={css.itemList}
|
className={css.itemList}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<PlayerTabLoading />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user