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",
|
||||
"axios": "^0.21.1",
|
||||
"ilib": "^14.3.0",
|
||||
"moment": "^2.30.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"qrcode": "^1.5.3",
|
||||
"raw-loader": "^4.0.2",
|
||||
|
||||
@@ -96,7 +96,6 @@ export default function HotelOption({
|
||||
|
||||
setAmenitiesInfos(amenitiesArr);
|
||||
};
|
||||
console.log("#am", amenitiesInfos);
|
||||
return (
|
||||
<>
|
||||
<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 moment from "moment";
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
@@ -30,7 +31,7 @@ export const removeDotAndColon = (string) => {
|
||||
return /[.:]/.test(string) ? string.replace(/[.:]/g, "") : string;
|
||||
};
|
||||
|
||||
export default memo(function TItemCard({
|
||||
export default memo(function PlayerItemCard({
|
||||
children,
|
||||
disabled,
|
||||
imageAlt,
|
||||
@@ -45,10 +46,16 @@ export default memo(function TItemCard({
|
||||
soldoutFlag,
|
||||
spotlightId,
|
||||
patnerName,
|
||||
startDt,
|
||||
endDt,
|
||||
timezone,
|
||||
type = TYPES.liveHorizontal,
|
||||
...rest
|
||||
}) {
|
||||
const [gaugeWidth, setGaugeWidth] = useState(0);
|
||||
const [focused, setFocused] = useState(false);
|
||||
const _onBlur = useCallback(() => {
|
||||
setFocused(false);
|
||||
if (onBlur) {
|
||||
onBlur();
|
||||
}
|
||||
@@ -68,11 +75,35 @@ export default memo(function TItemCard({
|
||||
[onClick, disabled]
|
||||
);
|
||||
const _onFocus = useCallback(() => {
|
||||
setFocused(true);
|
||||
if (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 (
|
||||
<SpottableComponent
|
||||
className={classNames(css[type])}
|
||||
@@ -96,6 +127,16 @@ export default memo(function TItemCard({
|
||||
<h3 className={css.brandName}>{patnerName}</h3>
|
||||
</div>
|
||||
<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>
|
||||
</SpottableComponent>
|
||||
);
|
||||
|
||||
@@ -62,6 +62,25 @@
|
||||
overflow: hidden;
|
||||
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
|
||||
|
||||
@@ -244,9 +244,10 @@ const PlayerPanel = ({ hideChildren, isTabActivated, ...props }) => {
|
||||
/>
|
||||
|
||||
{tab === 0 && <ShopNowContents />}
|
||||
{showNowProduct && showNowProduct.length < 3 && tab === 0 && (
|
||||
<YouMayLikeContents />
|
||||
)}
|
||||
{showNowProduct !== "undefined" &&
|
||||
showNowProduct &&
|
||||
showNowProduct.length < 3 &&
|
||||
tab === 0 && <YouMayLikeContents />}
|
||||
{panelInfo.type === "LIVE" && tab === 1 && <LiveChannelContents />}
|
||||
{panelInfo.type === "VOD" && tab === 1 && <FeaturedShowContents />}
|
||||
</Container>
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
&.backLiveicon {
|
||||
display: flex;
|
||||
top: 66px;
|
||||
left: 60px;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridL
|
||||
import { panel_names } from "../../../utils/Config";
|
||||
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
||||
import css from "./LiveChannelContents.module.less";
|
||||
import PlayerTabLoading from "./PlayerTabLoading";
|
||||
|
||||
export default function FeaturedShowContents() {
|
||||
const dispatch = useDispatch();
|
||||
@@ -41,7 +42,7 @@ export default function FeaturedShowContents() {
|
||||
return (
|
||||
<>
|
||||
<div className={css.container}>
|
||||
{featuredShowsInfos && featuredShowsInfos.length > 0 && (
|
||||
{featuredShowsInfos && featuredShowsInfos.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
dataSize={featuredShowsInfos.length}
|
||||
direction="vertical"
|
||||
@@ -51,6 +52,8 @@ export default function FeaturedShowContents() {
|
||||
spacing={12}
|
||||
className={css.itemList}
|
||||
/>
|
||||
) : (
|
||||
<PlayerTabLoading />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
@@ -7,23 +7,25 @@ import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridL
|
||||
import { panel_names } from "../../../utils/Config";
|
||||
import PlayerItemCard, { TYPES } from "../PlayerItemCard/PlayerItemCard";
|
||||
import css from "./LiveChannelContents.module.less";
|
||||
import PlayerTabLoading from "./PlayerTabLoading";
|
||||
|
||||
export default function LiveChannelContents() {
|
||||
const dispatch = useDispatch();
|
||||
const liveChannelInfos = useSelector((state) => state.main.liveChannelInfos);
|
||||
|
||||
console.log("#liveChannelInfos", liveChannelInfos);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const {
|
||||
dfltThumbnailImgPath,
|
||||
patncLogoPath,
|
||||
patnrId,
|
||||
prdtId,
|
||||
prdtNm,
|
||||
priceInfo,
|
||||
offerInfo,
|
||||
showNm,
|
||||
patncNm,
|
||||
strtDt,
|
||||
endDt,
|
||||
timezone,
|
||||
} = liveChannelInfos[index];
|
||||
|
||||
const handleItemClick = () => {};
|
||||
@@ -35,8 +37,11 @@ export default function LiveChannelContents() {
|
||||
imageAlt={prdtId}
|
||||
logo={patncLogoPath}
|
||||
imageSource={dfltThumbnailImgPath}
|
||||
productName={prdtNm}
|
||||
productName={showNm}
|
||||
patnerName={patncNm}
|
||||
startDt={strtDt}
|
||||
endDt={endDt}
|
||||
timezone={timezone}
|
||||
onClick={handleItemClick}
|
||||
type={TYPES.liveHorizontal}
|
||||
/>
|
||||
@@ -47,7 +52,7 @@ export default function LiveChannelContents() {
|
||||
return (
|
||||
<>
|
||||
<div className={css.container}>
|
||||
{liveChannelInfos && liveChannelInfos.length > 0 && (
|
||||
{liveChannelInfos && liveChannelInfos.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
dataSize={liveChannelInfos.length}
|
||||
direction="vertical"
|
||||
@@ -57,6 +62,8 @@ export default function LiveChannelContents() {
|
||||
spacing={12}
|
||||
className={css.itemList}
|
||||
/>
|
||||
) : (
|
||||
<PlayerTabLoading />
|
||||
)}
|
||||
</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 SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
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() {
|
||||
@@ -62,7 +61,7 @@ export default function ShopNowContents() {
|
||||
return (
|
||||
<>
|
||||
<div className={css.container}>
|
||||
{showNowProduct && showNowProduct.length > 0 && (
|
||||
{showNowProduct && showNowProduct.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
style={gridStyle}
|
||||
dataSize={showNowProduct.length}
|
||||
@@ -73,6 +72,8 @@ export default function ShopNowContents() {
|
||||
spacing={12}
|
||||
className={css.itemList}
|
||||
/>
|
||||
) : (
|
||||
<PlayerTabLoading />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -7,6 +7,7 @@ import TItemCard, { TYPES } from "../../../components/TItemCard/TItemCard";
|
||||
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import { panel_names } from "../../../utils/Config";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import PlayerTabLoading from "./PlayerTabLoading";
|
||||
import css from "./YouMayLikeContents.module.less";
|
||||
|
||||
export default function YouMayLikeContents() {
|
||||
@@ -17,6 +18,8 @@ export default function YouMayLikeContents() {
|
||||
|
||||
const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]);
|
||||
|
||||
console.log("#youmaylikeInfos", youmaylikeInfos);
|
||||
|
||||
useEffect(() => {
|
||||
if (showNowProduct && showNowProduct.length === 2) {
|
||||
setHeight(300);
|
||||
@@ -65,7 +68,7 @@ export default function YouMayLikeContents() {
|
||||
<div className={css.title}>{$L("YOU MAY LIKE")}</div>
|
||||
<div className={css.line}></div>
|
||||
|
||||
{youmaylikeInfos && youmaylikeInfos.length > 0 && (
|
||||
{youmaylikeInfos && youmaylikeInfos.length > 0 ? (
|
||||
<TVirtualGridList
|
||||
style={gridStyle}
|
||||
dataSize={youmaylikeInfos.length}
|
||||
@@ -76,6 +79,8 @@ export default function YouMayLikeContents() {
|
||||
spacing={12}
|
||||
className={css.itemList}
|
||||
/>
|
||||
) : (
|
||||
<PlayerTabLoading />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user