🕐 커밋 시간: 2025. 11. 24. 19:23:39 📊 변경 통계: • 총 파일: 8개 • 추가: +142줄 • 삭제: -31줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/playActions.js ~ com.twin.app.shoptime/src/components/MediaItem/MediaItem.js ~ com.twin.app.shoptime/src/components/VideoPlayer/MediaTitle.js ~ com.twin.app.shoptime/src/components/VideoPlayer/TReactPlayer.jsx ~ com.twin.app.shoptime/src/components/VideoPlayer/VideoPlayer.js ~ com.twin.app.shoptime/src/hooks/useReviews/useReviews.js ~ com.twin.app.shoptime/src/utils/helperMethods.js ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerPanel.jsx 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • UI 컴포넌트 아키텍처 개선 • 공통 유틸리티 함수 최적화 • 중간 규모 기능 개선 • 모듈 구조 개선
194 lines
5.3 KiB
JavaScript
194 lines
5.3 KiB
JavaScript
import React from "react";
|
|
|
|
import PropTypes from "prop-types";
|
|
import onlyUpdateForKeys from "recompose/onlyUpdateForKeys";
|
|
|
|
import EnactPropTypes from "@enact/core/internal/prop-types";
|
|
import kind from "@enact/core/kind";
|
|
import Marquee from "@enact/sandstone/Marquee";
|
|
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
|
import ForwardRef from "@enact/ui/ForwardRef";
|
|
|
|
import { $L } from "../../utils/helperMethods";
|
|
import { SpotlightIds } from "../../utils/SpotlightIds";
|
|
import TButton from "../TButton/TButton";
|
|
import css from "./MediaTitle.module.less";
|
|
|
|
const Container = SpotlightContainerDecorator(
|
|
{ enterTo: null, preserveId: true },
|
|
"div"
|
|
);
|
|
/**
|
|
* MediaTitle {@link sandstone/VideoPlayer}.
|
|
*
|
|
* @class MediaTitle
|
|
* @memberof sandstone/VideoPlayer
|
|
* @ui
|
|
* @private
|
|
*/
|
|
const MediaTitleBase = kind({
|
|
name: "MediaTitle",
|
|
|
|
propTypes: /** @lends sandstone/VideoPlayer.MediaTitle.prototype */ {
|
|
/**
|
|
* DOM id for the component. Also define ids for the title and node wrapping the `children`
|
|
* in the forms `${id}_title` and `${id}_info`, respectively.
|
|
*
|
|
* @type {String}
|
|
* @required
|
|
* @public
|
|
*/
|
|
id: PropTypes.string.isRequired,
|
|
|
|
/**
|
|
* Anything supplied to `children` will be rendered. Typically this will be informational
|
|
* badges indicating aspect ratio, audio channels, etc., but it could also be a description.
|
|
*
|
|
* @type {Node}
|
|
* @public
|
|
*/
|
|
children: PropTypes.node,
|
|
backButton: PropTypes.node,
|
|
promotionTitle: PropTypes.string,
|
|
|
|
introPer: PropTypes.number,
|
|
onClickSkipIntro: PropTypes.func,
|
|
onIntroDisabled: PropTypes.func,
|
|
/**
|
|
* Forwards a reference to the MediaTitle component.
|
|
*
|
|
* @type {Object|Function}
|
|
* @private
|
|
*/
|
|
forwardRef: EnactPropTypes.ref,
|
|
|
|
/**
|
|
* Control whether the children (infoComponents) are displayed.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
* @public
|
|
*/
|
|
infoVisible: PropTypes.bool,
|
|
|
|
/**
|
|
* A title string to identify the media's title.
|
|
*
|
|
* @type {String|Node}
|
|
* @public
|
|
*/
|
|
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
|
|
/**
|
|
* Setting this to false effectively hides the entire component. Setting it to `false` after
|
|
* the control has rendered causes a fade-out transition. Setting to `true` after or during
|
|
* the transition makes the component immediately visible again, without delay or transition.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
* @public
|
|
*/
|
|
// This property uniquely defaults to true, because it doesn't make sense to have it false
|
|
// and have the control be initially invisible, and is named "visible" to match the other
|
|
// props (current and possible future). Having an `infoVisible` and a `hidden` prop seems weird.
|
|
visible: PropTypes.bool,
|
|
},
|
|
|
|
defaultProps: {
|
|
infoVisible: false,
|
|
visible: true,
|
|
},
|
|
|
|
styles: {
|
|
css,
|
|
className: "titleFrame",
|
|
},
|
|
|
|
computed: {
|
|
childrenClassName: ({ infoVisible, styler }) =>
|
|
styler.join("infoComponents", infoVisible ? "visible" : "hidden"),
|
|
className: ({ visible, styler }) =>
|
|
styler.append(visible ? "visible" : "hidden"),
|
|
titleClassName: ({ infoVisible, styler }) =>
|
|
styler.join({
|
|
title: true,
|
|
infoVisible,
|
|
}),
|
|
},
|
|
|
|
render: ({
|
|
children,
|
|
backButton,
|
|
childrenClassName,
|
|
id,
|
|
forwardRef,
|
|
title,
|
|
titleClassName,
|
|
introPer,
|
|
onClickSkipIntro,
|
|
onIntroDisabled,
|
|
promotionTitle,
|
|
...rest
|
|
}) => {
|
|
delete rest.infoVisible;
|
|
delete rest.visible;
|
|
delete rest.spotlightDown;
|
|
return (
|
|
<Container {...rest} id={id} ref={forwardRef}>
|
|
{backButton}
|
|
<Marquee
|
|
id={`${id}_title`}
|
|
className={titleClassName}
|
|
marqueeOn="render"
|
|
>
|
|
{title}
|
|
</Marquee>
|
|
{introPer >= 0 && introPer < 100 ? (
|
|
<div id={`${id}_skipIntro`} className={css.skipIntro}>
|
|
<TButton
|
|
allowClickOnPreview
|
|
spotlightId={SpotlightIds.PLAYER_SKIPINTRO}
|
|
type={"skipIntro"}
|
|
fillPer={introPer}
|
|
onClick={onClickSkipIntro}
|
|
onDisabled={onIntroDisabled}
|
|
>
|
|
{$L("SKIP INTRO")}
|
|
</TButton>
|
|
</div>
|
|
) : (
|
|
promotionTitle && (
|
|
<div id={`${id}_skipIntro`} className={css.skipIntro}>
|
|
<TButton
|
|
withMarquee
|
|
spotlightId={SpotlightIds.PLAYER_SKIPINTRO}
|
|
onClick={onClickSkipIntro}
|
|
>
|
|
{promotionTitle}
|
|
</TButton>
|
|
</div>
|
|
)
|
|
)}
|
|
<div id={`${id}_info`} className={childrenClassName}>
|
|
{" "}
|
|
{/* tabIndex={-1} */}
|
|
{children}
|
|
</div>
|
|
</Container>
|
|
);
|
|
},
|
|
});
|
|
|
|
const MediaTitle = ForwardRef(
|
|
onlyUpdateForKeys([
|
|
"children",
|
|
"title",
|
|
"infoVisible",
|
|
"visible",
|
|
"introPer",
|
|
])(MediaTitleBase)
|
|
);
|
|
|
|
export default MediaTitle;
|
|
export { MediaTitle, MediaTitleBase };
|