[홈패널] 비디오 플레이어 추가

This commit is contained in:
sungmin.in
2024-03-05 10:05:34 +09:00
parent 2eea50e57e
commit eaac5e73ac
99 changed files with 10666 additions and 57 deletions

View 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;