[홈패널] 비디오 플레이어 추가
This commit is contained in:
453
com.twin.app.shoptime/src/components/MediaItem/MediaItem.js
Normal file
453
com.twin.app.shoptime/src/components/MediaItem/MediaItem.js
Normal file
@@ -0,0 +1,453 @@
|
||||
/**
|
||||
* Item Module of contents list
|
||||
*
|
||||
* @module MediaItem
|
||||
*/
|
||||
import React, { useCallback, useEffect, useMemo } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
import compose from "ramda/src/compose";
|
||||
import { shallowEqual, useSelector } from "react-redux";
|
||||
|
||||
import { Image } from "@enact/sandstone/Image";
|
||||
import { Marquee, MarqueeController } from "@enact/sandstone/Marquee";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
import { Cell, Column } from "@enact/ui/Layout";
|
||||
import { VoiceControlDecorator } from "@enact/webos/speech";
|
||||
|
||||
import * as Config from "../../utils/Config";
|
||||
// import YOUTUBE_BADGE_LOGO from "../../../assets/list/icon/icon_youtube.png";
|
||||
import * as ContentType from "../../utils/Config";
|
||||
import * as Utils from "../../utils/helperMethods";
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
import SpotlightIds from "../../utils/SpotlightIds";
|
||||
import css from "./MediaItem.module.less";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {itemSize} "small", "big", 'plan'
|
||||
* @returns
|
||||
*/
|
||||
const MediaItemBase = ({
|
||||
itemSize,
|
||||
supportFavBtn,
|
||||
favBtnFocused,
|
||||
caption,
|
||||
onItemClick,
|
||||
forceFocus,
|
||||
listspotlightid,
|
||||
style,
|
||||
onFavBtnFocused,
|
||||
itemInfo,
|
||||
playing,
|
||||
selectMode,
|
||||
...rest
|
||||
}) => {
|
||||
const contentsMyFavorites = useSelector(
|
||||
(state) => state.contentsMyFavorites,
|
||||
shallowEqual
|
||||
);
|
||||
const contentInfos = useSelector((state) => state.contentInfos);
|
||||
const panelInfo = useSelector((state) => state.panels);
|
||||
|
||||
const updatedContentInfo = useSelector(
|
||||
(state) => state.updatedContentInfo,
|
||||
(newState) => {
|
||||
if (!itemInfo || !newState) {
|
||||
return true;
|
||||
}
|
||||
if (itemInfo.contentId === newState.contentId) {
|
||||
Utils.jsonConcat(itemInfo, newState);
|
||||
return false;
|
||||
}
|
||||
if (itemInfo.youtubeId && itemInfo.youtubeId === newState.youtubeId) {
|
||||
Utils.jsonConcat(itemInfo, newState);
|
||||
return false;
|
||||
}
|
||||
if (itemInfo.contentType === ContentType.PLAN) {
|
||||
let matched = false;
|
||||
if (itemInfo.items) {
|
||||
for (let j = 0; j < itemInfo.items.length; j++) {
|
||||
if (itemInfo.items[j].contentId === newState.contentId) {
|
||||
Utils.jsonConcat(itemInfo.items[j], newState);
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
if (itemInfo.items && itemInfo.items[0]) {
|
||||
itemInfo.thumbnailImageUrl = itemInfo.items[0].thumbnailImageUrl;
|
||||
itemInfo.postImageUrl = itemInfo.items[0].postImageUrl;
|
||||
}
|
||||
if (matched) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; //it's same item. Will not update.
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (itemInfo && itemInfo.contentType === ContentType.PLAN) {
|
||||
if (itemInfo.items) {
|
||||
for (let j in itemInfo.items) {
|
||||
if (
|
||||
itemInfo.items[j].contentId &&
|
||||
contentInfos[itemInfo.items[j].contentId]
|
||||
) {
|
||||
Utils.jsonConcat(
|
||||
itemInfo.items[j],
|
||||
contentInfos[itemInfo.items[j].contentId]
|
||||
);
|
||||
}
|
||||
}
|
||||
if (itemInfo.items && itemInfo.items[0]) {
|
||||
itemInfo.thumbnailImageUrl = itemInfo.items[0].thumbnailImageUrl;
|
||||
itemInfo.postImageUrl = itemInfo.items[0].postImageUrl;
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
itemInfo &&
|
||||
itemInfo.contentId &&
|
||||
contentInfos[itemInfo.contentId]
|
||||
) {
|
||||
Utils.jsonConcat(itemInfo, contentInfos[itemInfo.contentId]);
|
||||
}
|
||||
}, [itemInfo, contentInfos, updatedContentInfo]);
|
||||
|
||||
const iamFavContent = useMemo(() => {
|
||||
let ret = false;
|
||||
if (listspotlightid === SpotlightIds.LIST_MYFAVORITE) {
|
||||
ret = true;
|
||||
} else if (
|
||||
itemInfo &&
|
||||
contentsMyFavorites &&
|
||||
contentsMyFavorites.length > 0
|
||||
) {
|
||||
const id = itemInfo.contentId;
|
||||
for (let index in contentsMyFavorites) {
|
||||
if (id === contentsMyFavorites[index].contentId) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}, [contentsMyFavorites, itemInfo, listspotlightid]);
|
||||
|
||||
const onFavMouseEnter = useCallback(() => {
|
||||
if (!supportFavBtn) {
|
||||
return;
|
||||
}
|
||||
onFavBtnFocused(true);
|
||||
}, [onFavBtnFocused, supportFavBtn]);
|
||||
const onFavMouseLeave = useCallback(() => {
|
||||
onFavBtnFocused(false);
|
||||
}, [onFavBtnFocused]);
|
||||
|
||||
const onClick = useCallback(
|
||||
(ev) => {
|
||||
console.log("onClick..", ev);
|
||||
if (onItemClick) {
|
||||
onItemClick(ev);
|
||||
}
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
},
|
||||
[onItemClick]
|
||||
);
|
||||
|
||||
let thumbnail = "",
|
||||
placeholder = "";
|
||||
if (itemSize !== "small" && itemInfo && itemInfo.postImageUrl) {
|
||||
thumbnail = itemInfo.postImageUrl;
|
||||
} else {
|
||||
thumbnail = itemInfo && itemInfo.thumbnailImageUrl;
|
||||
}
|
||||
placeholder = itemInfo && itemInfo.thumbnailImageUrl;
|
||||
|
||||
const captionContainer = useCallback(
|
||||
(_isYoutubeChannel, _isApp, _isSpecialButton) => {
|
||||
const marqueeAlign =
|
||||
_isYoutubeChannel || _isApp || _isSpecialButton ? "center" : "left";
|
||||
const replaceHtmlEntitesCaption = Utils.replaceHtmlEntites(caption);
|
||||
if (!itemInfo || itemInfo.contentType === ContentType.PLAN) {
|
||||
return null;
|
||||
}
|
||||
let splitTitle = [];
|
||||
if (Object.keys(itemInfo).includes("dayTitle")) {
|
||||
splitTitle = replaceHtmlEntitesCaption.split(":");
|
||||
}
|
||||
return (
|
||||
<Cell
|
||||
align="center"
|
||||
key="captionContainer"
|
||||
className={classNames(
|
||||
css.captionContainer,
|
||||
_isYoutubeChannel ? css.channel : null,
|
||||
_isApp ? css.app : null,
|
||||
_isSpecialButton ? css.innerText : null
|
||||
)}
|
||||
>
|
||||
<Marquee
|
||||
marqueeDisabled={!forceFocus || favBtnFocused}
|
||||
alignment={marqueeAlign}
|
||||
key="caption"
|
||||
className={css.caption}
|
||||
marqueeOn={!favBtnFocused && forceFocus ? "render" : undefined}
|
||||
>
|
||||
{Object.keys(itemInfo).includes("dayTitle") ? (
|
||||
<>
|
||||
<span className={css.emphasisFont}>
|
||||
{" "}
|
||||
{splitTitle[0] + " :"}{" "}
|
||||
</span>
|
||||
{splitTitle[1]}
|
||||
</>
|
||||
) : (
|
||||
replaceHtmlEntitesCaption
|
||||
)}
|
||||
</Marquee>
|
||||
</Cell>
|
||||
);
|
||||
},
|
||||
[itemInfo, caption, forceFocus, favBtnFocused]
|
||||
);
|
||||
|
||||
const planItemDetail = useCallback(
|
||||
(itemSize) => {
|
||||
if (itemInfo && itemSize === "plan") {
|
||||
return (
|
||||
<div className={css.planItemDetail}>
|
||||
<Marquee
|
||||
marqueeDisabled={!forceFocus}
|
||||
onClick={onClick}
|
||||
className={css.planTitle}
|
||||
marqueeOn={forceFocus ? "render" : undefined}
|
||||
>
|
||||
{Utils.replaceHtmlEntites(itemInfo.title)}
|
||||
</Marquee>
|
||||
{itemInfo.items &&
|
||||
itemInfo.items.map((item, index) => (
|
||||
<div className={css.planList} key={index}>
|
||||
<div className={css.plancountcontainer}>
|
||||
<div className={css.repeatImage} />
|
||||
<div>{item && item.repeatCount}</div>
|
||||
</div>
|
||||
<Marquee
|
||||
marqueeDisabled={!forceFocus}
|
||||
className={css.planlisttitle}
|
||||
alignment={"left"}
|
||||
marqueeOn={forceFocus ? "render" : undefined}
|
||||
>
|
||||
{item && item.title}
|
||||
</Marquee>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(
|
||||
css.captionContainer,
|
||||
isYoutubeChannel ? css.channelPlayIcon : null,
|
||||
isMoreButton ? css.moreIcon : null,
|
||||
isAddPlanButton ? css.addPlanIcon : null,
|
||||
playing ? css.playing : null
|
||||
)}
|
||||
>
|
||||
<Marquee
|
||||
className={css.caption}
|
||||
marqueeDisabled={!forceFocus}
|
||||
onClick={onClick}
|
||||
marqueeOn={forceFocus ? "render" : undefined}
|
||||
>
|
||||
{Utils.replaceHtmlEntites(itemInfo.title)}
|
||||
</Marquee>
|
||||
</div>
|
||||
<div className={css.repeatCountList}>
|
||||
<span>{itemInfo.items.length}</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
},
|
||||
[itemInfo, itemSize, forceFocus, onClick]
|
||||
);
|
||||
|
||||
const playerRepeat = useCallback(() => {
|
||||
if (itemInfo) {
|
||||
return (
|
||||
<div className={css.playerRepeatContainer}>
|
||||
<div className={css.repeatImage} />
|
||||
<div>{itemInfo.repeatCount}</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [itemInfo]);
|
||||
|
||||
const supportBadge = useMemo(() => {
|
||||
let supported = false,
|
||||
badgeStyle = {};
|
||||
if (itemInfo) {
|
||||
if (itemInfo.contentType === ContentType.YOUTUBE_VIDEO) {
|
||||
supported = true;
|
||||
// badgeStyle = { backgroundImage: `url(${YOUTUBE_BADGE_LOGO})` };
|
||||
} else if (itemInfo.contentType === ContentType.CP_CONTENT) {
|
||||
supported = true;
|
||||
// badgeStyle = { backgroundImage: `url(${itemInfo.badgeIconUrl})` };
|
||||
}
|
||||
}
|
||||
return { supported, badgeStyle };
|
||||
}, [itemInfo]);
|
||||
|
||||
const isYoutubeChannel =
|
||||
itemInfo && itemInfo.contentType === ContentType.YOUTUBE_CHANNEL;
|
||||
const isYoutubeVideo =
|
||||
itemInfo && itemInfo.contentType === ContentType.YOUTUBE_VIDEO;
|
||||
const isMoreButton = itemInfo && itemInfo.contentType === ContentType.MORE;
|
||||
const isAddPlanButton =
|
||||
itemInfo && itemInfo.contentType === ContentType.ADD_PLAN;
|
||||
const isSpecialButton = isMoreButton || isAddPlanButton;
|
||||
const isApp = itemInfo && itemInfo.contentType === ContentType.APP;
|
||||
const isYoutubeAppMoveIcon =
|
||||
panelInfo.length > 0 && panelInfo[0].name === "moreformedlist";
|
||||
const moveAppIcon =
|
||||
itemInfo &&
|
||||
(itemInfo.contentType === ContentType.APP ||
|
||||
itemInfo.contentType === ContentType.CP_CONTENT);
|
||||
const playtime =
|
||||
itemInfo && itemInfo.playtime
|
||||
? Utils.transSecToText(itemInfo.playtime)
|
||||
: null;
|
||||
const useNewTodayIcon = Config.USE_NEW_TODAY_ICON;
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
className={classNames(
|
||||
forceFocus ? css.forceFocus : null,
|
||||
css.mediaImage,
|
||||
itemSize === "big"
|
||||
? css.bigItem
|
||||
: itemSize === "plan"
|
||||
? css.planItem
|
||||
: null
|
||||
)}
|
||||
style={style}
|
||||
onClick={onClick}
|
||||
>
|
||||
<Column
|
||||
className={classNames(
|
||||
css.imageItem,
|
||||
favBtnFocused ? css.favFocus : null
|
||||
)}
|
||||
>
|
||||
<Cell
|
||||
key="thumbContainer"
|
||||
className={classNames(
|
||||
css.thumbContainer,
|
||||
isYoutubeChannel ? css.thumbContaineryoutubeChannel : null,
|
||||
isApp ? css.thumbContainerApp : null,
|
||||
isSpecialButton ? css.specialBtnContainer : null
|
||||
)}
|
||||
>
|
||||
{thumbnail && (
|
||||
<Image
|
||||
className={classNames(
|
||||
css.image,
|
||||
isYoutubeChannel ? css.youtubeChannel : null,
|
||||
isApp ? css.applogo : null,
|
||||
isYoutubeVideo ? css.youtubeVideo : null
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
src={thumbnail}
|
||||
/>
|
||||
)}
|
||||
{listspotlightid === SpotlightIds.LIST_TODAYTOP && (
|
||||
<div
|
||||
className={classNames(
|
||||
css.top10Number,
|
||||
css["index_" + (rest.index + 1)]
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{itemInfo && itemInfo.isToday && (
|
||||
<div
|
||||
className={classNames(
|
||||
css.toDayStr,
|
||||
useNewTodayIcon && css.newTodayStr
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{captionContainer(isYoutubeChannel, isApp, isSpecialButton)}
|
||||
{!forceFocus && playtime && (
|
||||
<div className={classNames(!isYoutubeChannel ? css.subtime : null)}>
|
||||
{playtime}
|
||||
</div>
|
||||
)}
|
||||
{supportBadge.supported && (
|
||||
<div className={css.badgelogo} style={supportBadge.badgeStyle} />
|
||||
)}
|
||||
{itemInfo && (!selectMode || isAddPlanButton) && (
|
||||
<div
|
||||
className={classNames(
|
||||
css.playIcon,
|
||||
isYoutubeAppMoveIcon
|
||||
? css.appIcon
|
||||
: isYoutubeChannel
|
||||
? css.channelPlayIcon
|
||||
: null,
|
||||
moveAppIcon ? css.appIcon : null,
|
||||
isMoreButton ? css.moreIcon : null,
|
||||
isAddPlanButton
|
||||
? itemSize === "plan"
|
||||
? css.addPlanIcon
|
||||
: css.moreIcon
|
||||
: null,
|
||||
playing ? css.playing : isYoutubeVideo ? css.appIcon : null
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{itemInfo &&
|
||||
itemInfo.contentType === ContentType.PLAN &&
|
||||
planItemDetail(itemSize)}
|
||||
{itemInfo && itemInfo.repeatCount && playerRepeat()}
|
||||
</Cell>
|
||||
{supportFavBtn && (
|
||||
<div
|
||||
isfavbtn={"true"}
|
||||
className={classNames(
|
||||
css.addToFavoriteBtn,
|
||||
favBtnFocused ? css.focus : null
|
||||
)}
|
||||
onMouseEnter={onFavMouseEnter}
|
||||
onMouseLeave={onFavMouseLeave}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
css.favIcon,
|
||||
iamFavContent ? css.removeFav : null
|
||||
)}
|
||||
/>
|
||||
<div className={css.favText}>
|
||||
{iamFavContent
|
||||
? $L("Remove from Favorite").toUpperCase()
|
||||
: $L("Add to Favorite").toUpperCase()}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Column>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ImageItemDecorator = compose(
|
||||
MarqueeController({ marqueeOnFocus: true }),
|
||||
VoiceControlDecorator,
|
||||
Spottable
|
||||
);
|
||||
const MediaItem = ImageItemDecorator(MediaItemBase);
|
||||
export default MediaItem;
|
||||
Reference in New Issue
Block a user