[playerpanel] TabButton in overlay && chat tabcontents error

This commit is contained in:
고동영
2024-05-10 17:59:58 +09:00
parent afd7e7ee66
commit 95e5285d73
9 changed files with 163 additions and 88 deletions

View File

@@ -723,7 +723,7 @@ const VideoPlayerBase = class extends React.Component {
static contextType = FloatingLayerContext; static contextType = FloatingLayerContext;
static defaultProps = { static defaultProps = {
// autoCloseTimeout: 5000, autoCloseTimeout: 10000,
feedbackHideDelay: 3000, feedbackHideDelay: 3000,
initialJumpDelay: 400, initialJumpDelay: 400,
jumpBy: 30, jumpBy: 30,
@@ -2067,6 +2067,9 @@ const VideoPlayerBase = class extends React.Component {
thumbnailUrl, thumbnailUrl,
type, type,
isYoutube, isYoutube,
sideContentsVisible,
setSideContentsVisible,
...mediaProps ...mediaProps
} = this.props; } = this.props;
@@ -2187,6 +2190,8 @@ const VideoPlayerBase = class extends React.Component {
panelInfo={panelInfo} panelInfo={panelInfo}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
setIsSubtitleActive={setIsSubtitleActive} setIsSubtitleActive={setIsSubtitleActive}
sideContentsVisible={sideContentsVisible}
setSideContentsVisible={setSideContentsVisible}
type={type} type={type}
/> />
</div> </div>

View File

@@ -1,22 +1,19 @@
import React, { import React, { useCallback, useEffect, useMemo } from "react";
useCallback,
useEffect,
useMemo,
} from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from "react-redux";
import Spotlight from '@enact/spotlight'; import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
from '@enact/spotlight/SpotlightContainerDecorator'; import Spottable from "@enact/spotlight/Spottable";
import Spottable from '@enact/spotlight/Spottable'; import Marquee from "@enact/ui/Marquee";
import Marquee from '@enact/ui/Marquee';
import { updatePanel } from '../../../actions/panelActions'; import { updatePanel } from "../../../actions/panelActions";
import { panel_names } from '../../../utils/Config'; import { panel_names } from "../../../utils/Config";
import { $L } from '../../../utils/helperMethods'; import { $L } from "../../../utils/helperMethods";
import { SpotlightIds } from '../../../utils/SpotlightIds'; import { SpotlightIds } from "../../../utils/SpotlightIds";
import css from './PlayerOverlayContents.module.less'; import PlayerTabButton from "../PlayerTabContents/TabButton/PlayerTabButton";
import TabContainer from "../PlayerTabContents/TabContaienr";
import css from "./PlayerOverlayContents.module.less";
const SpottableBtn = Spottable("button"); const SpottableBtn = Spottable("button");
@@ -32,6 +29,8 @@ export default function PlayerOverlayContents({
onClick, onClick,
setSelectedIndex, setSelectedIndex,
setIsSubtitleActive, setIsSubtitleActive,
sideContentsVisible,
setSideContentsVisible,
type, type,
}) { }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -42,7 +41,10 @@ export default function PlayerOverlayContents({
} }
}; };
const handleSubtitleOnClick = () => { const handleSubtitleOnClick = (e) => {
// e.stopPropagation();
// e.preventDefault();
setIsSubtitleActive((prev) => !prev); setIsSubtitleActive((prev) => !prev);
}; };
@@ -124,6 +126,16 @@ export default function PlayerOverlayContents({
}, },
[panelInfo] [panelInfo]
); );
const currentSideButtonStatus = useMemo(() => {
if (
panelInfo?.shptmBanrTpNm !== "MEDIA" &&
!panelInfo?.modal &&
!sideContentsVisible
) {
return true;
}
return false;
}, [panelInfo, sideContentsVisible]);
return ( return (
<> <>
@@ -151,6 +163,14 @@ export default function PlayerOverlayContents({
onSpotlightRight={onSpotlightMoveSlider} onSpotlightRight={onSpotlightMoveSlider}
/> />
</div> </div>
{currentSideButtonStatus && (
<PlayerTabButton
setSideContentsVisible={setSideContentsVisible}
sideContentsVisible={sideContentsVisible}
/>
)}
<div className={css.videoButtonContainer}> <div className={css.videoButtonContainer}>
<SpottableBtn <SpottableBtn
className={css.subtitleButton} className={css.subtitleButton}

View File

@@ -62,11 +62,12 @@ const PlayerPanel = ({
const [playListInfo, setPlayListInfo] = useState(""); const [playListInfo, setPlayListInfo] = useState("");
const [shopNowInfo, setShopNowInfo] = useState(); const [shopNowInfo, setShopNowInfo] = useState();
const [modalStyle, setModalStyle] = useState({}); const [modalStyle, setModalStyle] = useState({});
const [sideOpen, setSideOpen] = useState(true); const [sideContentsVisible, setSideContentsVisible] = useState(true);
const [selectedIndex, setSelectedIndex] = useState(0); const [selectedIndex, setSelectedIndex] = useState(0);
const [isUpdate, setIsUpdate] = useState(false); const [isUpdate, setIsUpdate] = useState(false);
const [currentTime, setCurrentTime] = useState(); const [currentTime, setCurrentTime] = useState();
const [isSubtitleActive, setIsSubtitleActive] = useState(false); const [isChatVisible, setIsChatVisible] = useState(true);
const [isSubtitleActive, setIsSubtitleActive] = useState(true);
const panels = useSelector((state) => state.panels.panels); const panels = useSelector((state) => state.panels.panels);
const chatData = useSelector((state) => state.play.chatData); const chatData = useSelector((state) => state.play.chatData);
const showDetailInfo = useSelector((state) => state.main.showDetailInfo); const showDetailInfo = useSelector((state) => state.main.showDetailInfo);
@@ -149,10 +150,10 @@ const PlayerPanel = ({
); );
const autoCloseVideoOverlay = useMemo(() => { const autoCloseVideoOverlay = useMemo(() => {
if (!sideOpen && panelInfo.modal === false) { if (!sideContentsVisible && panelInfo.modal === false) {
return 3000; return 10000;
} }
}, [sideOpen, panelInfo]); }, [sideContentsVisible, panelInfo]);
const mediainfoHandler = useCallback( const mediainfoHandler = useCallback(
(ev) => { (ev) => {
@@ -190,7 +191,7 @@ const PlayerPanel = ({
window.addEventListener("click", handleAction); window.addEventListener("click", handleAction);
window.addEventListener("keydown", handleAction); window.addEventListener("keydown", handleAction);
sideCotnentsTimer = setTimeout(() => setSideOpen(false), 10000); sideCotnentsTimer = setTimeout(() => setSideContentsVisible(false), 10000);
return () => { return () => {
window.removeEventListener("click", handleAction); window.removeEventListener("click", handleAction);
@@ -306,12 +307,6 @@ const PlayerPanel = ({
} }
}, [isActive]); }, [isActive]);
// useEffect(() => {
// if (!panelInfo.modal) {
// Spotlight.focus("videoPlayer");
// }
// }, [panelInfo.modal]);
useEffect(() => { useEffect(() => {
if (panelInfo.modal && panelInfo.modalContainerId) { if (panelInfo.modal && panelInfo.modalContainerId) {
const node = document.querySelector( const node = document.querySelector(
@@ -388,6 +383,20 @@ const PlayerPanel = ({
return true; return true;
}, [currentPlayingUrl, currentSubtTitleUrl, currentSubtitleBlob]); }, [currentPlayingUrl, currentSubtTitleUrl, currentSubtitleBlob]);
const chatVisible = useMemo(() => {
if (playListInfo && chatData && !panelInfo.modal && isChatVisible) {
return true;
}
return false;
}, [playListInfo, chatData, panelInfo.modal, isChatVisible]);
const isQRCodeVisible = useMemo(() => {
if (playListInfo && shopNowInfo && !panelInfo.modal) {
return true;
}
return false;
}, [playListInfo, shopNowInfo, panelInfo.modal]);
useEffect(() => { useEffect(() => {
if (currentSubtTitleUrl) { if (currentSubtTitleUrl) {
dispatch(getSubTitle({ showSubtitleUrl: currentSubtTitleUrl })); dispatch(getSubTitle({ showSubtitleUrl: currentSubtTitleUrl }));
@@ -411,6 +420,27 @@ const PlayerPanel = ({
} }
}, [currentSubtitleBlob, isSubtitleActive]); }, [currentSubtitleBlob, isSubtitleActive]);
useEffect(() => {
if (!panelInfo.modal) {
Spotlight.focus("videoPlayer");
}
}, [panelInfo.modal]);
const currentSideButtonStatus = useMemo(() => {
if (
panelInfo?.shptmBanrTpNm !== "MEDIA" &&
!panelInfo?.modal &&
sideContentsVisible
) {
return true;
}
return false;
}, [panelInfo, sideContentsVisible]);
useEffect(() => {
Spotlight.focus("player-tab-arrow");
}, [sideContentsVisible]);
return ( return (
<TPanel <TPanel
isTabActivated={false} isTabActivated={false}
@@ -428,32 +458,36 @@ const PlayerPanel = ({
<VideoPlayer <VideoPlayer
setApiProvider={getPlayer} setApiProvider={getPlayer}
disabled={panelInfo.modal} disabled={panelInfo.modal}
onEnded={onClickBack} // 플레이어가 끝날때 호출 onEnded={onClickBack}
noAutoPlay={cannotPlay} // 오토플레이 noAutoPlay={cannotPlay}
autoCloseTimeout={autoCloseVideoOverlay} // 컨트롤 버튼 숨기는 시간 autoCloseTimeout={autoCloseVideoOverlay}
playListInfo={playListInfo && playListInfo} // 비디오 데이터 stopAutoCloseTimeout={sideContentsVisible}
onBackButton={onClickBack} // 뒤로가기 버튼 onBackButton={onClickBack}
panelInfo={panelInfo} // 패널정보 (라이브,VOD) spotlightDisabled={sideContentsVisible || panelInfo.modal}
spotlightDisabled={sideOpen || panelInfo.modal}
onLoadedData={mediainfoHandler} onLoadedData={mediainfoHandler}
onLoadedMetadata={mediainfoHandler} onLoadedMetadata={mediainfoHandler}
onDurationChange={mediainfoHandler} onDurationChange={mediainfoHandler}
onTimeUpdate={mediainfoHandler} onTimeUpdate={mediainfoHandler}
isYoutube={isYoutube}
src={currentPlayingUrl} src={currentPlayingUrl}
style={panelInfo.modal ? modalStyle : {}} style={panelInfo.modal ? modalStyle : {}}
modalClassName={panelInfo.modal && panelInfo.modalClassName} modalClassName={panelInfo.modal && panelInfo.modalClassName}
reactPlayerConfig={reactPlayerSubtitleConfig} reactPlayerConfig={reactPlayerSubtitleConfig}
thumbnailUrl={playListInfo[selectedIndex]?.thumbnailUrl} thumbnailUrl={playListInfo[selectedIndex]?.thumbnailUrl}
type={panelInfo?.shptmBanrTpNm}
setSelectedIndex={setSelectedIndex} // 선택한 인덱스 Set
selectedIndex={selectedIndex} // 선택한 인덱스
setIsSubtitleActive={setIsSubtitleActive}
isYoutube={isYoutube}
videoComponent={ videoComponent={
(typeof window === "object" && !window.PalmSystem) || isYoutube (typeof window === "object" && !window.PalmSystem) || isYoutube
? TReactPlayer ? TReactPlayer
: Media : Media
} }
// VideoOverlay props
type={panelInfo?.shptmBanrTpNm}
panelInfo={panelInfo}
playListInfo={playListInfo && playListInfo}
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
setIsSubtitleActive={setIsSubtitleActive}
setSideContentsVisible={setSideContentsVisible}
sideContentsVisible={sideContentsVisible}
> >
{typeof window === "object" && window.PalmSystem && ( {typeof window === "object" && window.PalmSystem && (
<source src={currentPlayingUrl} type="application/mpegurl" /> <source src={currentPlayingUrl} type="application/mpegurl" />
@@ -469,28 +503,24 @@ const PlayerPanel = ({
{/* Overlay Area */} {/* Overlay Area */}
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && ( {isQRCodeVisible && (
<VideoOverlayWithPhoneNumber
className={css.videoOverlayWithPhoneNumber}
orderPhnNo={playListInfo[selectedIndex]?.orderPhnNo}
show
/>
)}
{playListInfo && shopNowInfo && !panelInfo.modal && (
<PlayerOverlayQRCode <PlayerOverlayQRCode
shopNowInfos={shopNowInfo} shopNowInfos={shopNowInfo}
currentTime={currentTime} currentTime={currentTime}
type={panelInfo?.shptmBanrTpNm} type={panelInfo?.shptmBanrTpNm}
/> />
)} )}
{playListInfo && chatData && !panelInfo.modal && (
<PlayerOverlayChat currentTime={currentTime} /> {chatVisible && <PlayerOverlayChat currentTime={currentTime} />}
)}
{panelInfo?.shptmBanrTpNm !== "MEDIA" && !panelInfo?.modal && ( {currentSideButtonStatus && (
<PlayerTabButton setSideOpen={setSideOpen} sideOpen={sideOpen} /> <PlayerTabButton
setSideContentsVisible={setSideContentsVisible}
sideContentsVisible={sideContentsVisible}
/>
)} )}
{sideOpen && {sideContentsVisible &&
panelInfo?.shptmBanrTpNm !== "MEDIA" && panelInfo?.shptmBanrTpNm !== "MEDIA" &&
!panelInfo?.modal && ( !panelInfo?.modal && (
<TabContainer <TabContainer
@@ -499,8 +529,8 @@ const PlayerPanel = ({
playListInfo={playListInfo} playListInfo={playListInfo}
setSelectedIndex={setSelectedIndex} setSelectedIndex={setSelectedIndex}
liveChannelInfos={liveChannelInfos || liveShowInfos} liveChannelInfos={liveChannelInfos || liveShowInfos}
sideOpen={sideOpen} setSideContentsVisible={setSideContentsVisible}
setSideOpen={setSideOpen} setIsChatVisible={setIsChatVisible}
/> />
)} )}
</Container> </Container>

View File

@@ -1,68 +1,72 @@
import React, { import React, { useCallback, useEffect } from "react";
useCallback,
useEffect,
} from 'react';
import classNames from 'classnames'; import classNames from "classnames";
import Spotlight from '@enact/spotlight'; import Spotlight from "@enact/spotlight";
import Spottable from '@enact/spotlight/Spottable'; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import css from './PlayerTabButton.module.less'; import css from "./PlayerTabButton.module.less";
const SpottableComponent = Spottable("button"); const SpottableComponent = Spottable("button");
export default function PlayerTabButton({ sideOpen, setSideOpen }) { const Container = SpotlightContainerDecorator(
{ enterTo: "default-element", preserveld: true },
"div"
);
export default function PlayerTabButton({
sideContentsVisible,
setSideContentsVisible,
}) {
const handleTabOnClick = (e) => { const handleTabOnClick = (e) => {
e.stopPropagation(); setSideContentsVisible((prev) => !prev);
setSideOpen((prev) => !prev);
}; };
const onSpotlightLeft = useCallback( const onSpotlightLeft = useCallback(
(e) => { (e) => {
if (!sideOpen) { if (!sideContentsVisible) {
e.stopPropagation(); e.stopPropagation();
Spotlight.focus("videoIndicator-up-button"); Spotlight.focus("videoIndicator-up-button");
} }
}, },
[sideOpen] [sideContentsVisible]
); );
const onSpotlightDown = useCallback( const onSpotlightDown = useCallback(
(e) => { (e) => {
if (!sideOpen) { if (!sideContentsVisible) {
e.stopPropagation(); e.stopPropagation();
Spotlight.focus("player-shrinkbutton"); Spotlight.focus("player-shrinkbutton");
} }
}, },
[sideOpen] [sideContentsVisible]
); );
const onSpotlightUp = useCallback( const onSpotlightUp = useCallback(
(e) => { (e) => {
if (!sideOpen) { if (!sideContentsVisible) {
e.stopPropagation(); e.stopPropagation();
Spotlight.focus("videoIndicator-up-button"); Spotlight.focus("videoIndicator-up-button");
} }
}, },
[sideOpen] [sideContentsVisible]
); );
return ( return (
<div <Container
className={classNames( className={classNames(
css.arrow, css.arrow,
sideOpen ? css.arrowOpen : css.arrowClose sideContentsVisible && css.arrowOpen,
!sideContentsVisible && css.arrowClose
)} )}
> >
<SpottableComponent <SpottableComponent
spotlightId={"player-tab-arrow"} spotlightId={"player-tab-arrow"}
onClick={handleTabOnClick} onClick={handleTabOnClick}
onSpotlightLeft={onSpotlightLeft} onSpotlightLeft={onSpotlightLeft}
// onSpotlightRight={onSpotlightUp}
onSpotlightUp={onSpotlightUp} onSpotlightUp={onSpotlightUp}
onSpotlightDown={onSpotlightDown} onSpotlightDown={onSpotlightDown}
className={css.button} className={css.button}
/> />
</div> </Container>
); );
} }

View File

@@ -4,7 +4,7 @@
.size(@w: 48px, @h: 144px); .size(@w: 48px, @h: 144px);
text-align: center; text-align: center;
position: absolute; position: absolute;
top: 468px;
z-index: 11; z-index: 11;
> button { > button {
.size(@w: 48px, @h: 144px); .size(@w: 48px, @h: 144px);
@@ -16,6 +16,8 @@
cursor: pointer; cursor: pointer;
} }
&.arrowClose { &.arrowClose {
top: 400px;
z-index: 11;
right: -2px; right: -2px;
> button { > button {
&.button { &.button {
@@ -27,6 +29,7 @@
} }
} }
&.arrowOpen { &.arrowOpen {
top: 468px;
right: 658px; right: 658px;
z-index: 11; z-index: 11;
> button { > button {

View File

@@ -1,5 +1,6 @@
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import TButtonTab, { import TButtonTab, {
@@ -24,6 +25,8 @@ export default function TabContainer({
shopNowInfo, shopNowInfo,
setSelectedIndex, setSelectedIndex,
liveChannelInfos, liveChannelInfos,
setSideContentsVisible,
setIsChatVisible,
}) { }) {
const [tab, setTab] = useState(0); const [tab, setTab] = useState(0);
@@ -50,7 +53,13 @@ export default function TabContainer({
listType={LIST_TYPE.small} listType={LIST_TYPE.small}
/> />
{tab === 0 && <ShopNowContents shopNowInfo={shopNowInfo} />} {tab === 0 && (
<ShopNowContents
shopNowInfo={shopNowInfo}
setSideContentsVisible={setSideContentsVisible}
setIsChatVisible={setIsChatVisible}
/>
)}
{panelInfo?.shptmBanrTpNm === "VOD" && tab === 1 && ( {panelInfo?.shptmBanrTpNm === "VOD" && tab === 1 && (
<FeaturedShowContents <FeaturedShowContents
featuredShowsInfos={playListInfo} featuredShowsInfos={playListInfo}

View File

@@ -2,9 +2,9 @@
@import "../../../style/utils.module.less"; @import "../../../style/utils.module.less";
.tabContainer { .tabContainer {
.size(@w:660px, @h:100%); .size(@w:660px, @h:1080px);
background: #2c343f; background: #2c343f;
position: absolute; position: fixed;
right: 0; right: 0;
top: 0; top: 0;
padding: 48px 30px 0 30px; padding: 48px 30px 0 30px;

View File

@@ -63,11 +63,9 @@ export default function LiveChannelContents({ liveInfos, setSelectedIndex }) {
); );
useEffect(() => { useEffect(() => {
const timer = setTimeout(() => { setTimeout(() => {
Spotlight.focus("liveChannel-Item-0"); Spotlight.focus("liveChannel-Item-0");
}); });
return () => clearTimeout(timer);
}, [liveInfos]); }, [liveInfos]);
return ( return (
<> <>

View File

@@ -4,7 +4,7 @@ import { useDispatch } from "react-redux";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { pushPanel } from "../../../../actions/panelActions"; import { pushPanel, updatePanel } 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";
@@ -15,7 +15,11 @@ const Container = SpotlightContainerDecorator(
{ enterTo: "default-element", preserveId: true }, { enterTo: "default-element", preserveId: true },
"div" "div"
); );
export default function ShopNowContents({ shopNowInfo }) { export default function ShopNowContents({
shopNowInfo,
setSideContentsVisible,
setIsChatVisible,
}) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [height, setHeight] = useState(); const [height, setHeight] = useState();
@@ -35,6 +39,8 @@ export default function ShopNowContents({ shopNowInfo }) {
shopNowInfo[index]; shopNowInfo[index];
const handleItemClick = () => { const handleItemClick = () => {
setSideContentsVisible(false);
setIsChatVisible(false);
dispatch( dispatch(
pushPanel({ pushPanel({
name: panel_names.DETAIL_PANEL, name: panel_names.DETAIL_PANEL,