[DetailPanel] themeIndicator css 수정 & Media 에서 보이게 수정
This commit is contained in:
@@ -106,6 +106,7 @@ export const types = {
|
||||
GET_BEST_SELLER: "GET_BEST_SELLER",
|
||||
GET_PRODUCT_GROUP: "GET_PRODUCT_GROUP",
|
||||
GET_PRODUCT_OPTION: "GET_PRODUCT_OPTION",
|
||||
GET_PRODUCT_IMAGE_LENGTH: "GET_PRODUCT_IMAGE_LENGTH",
|
||||
|
||||
// search actions
|
||||
GET_SEARCH: "GET_SEARCH",
|
||||
|
||||
@@ -90,3 +90,12 @@ export const getProductOption = (props) => (dispatch, getState) => {
|
||||
export const clearProductDetail = () => ({
|
||||
type: types.CLEAR_PRODUCT_DETAIL,
|
||||
});
|
||||
|
||||
export const getProductImageLength =
|
||||
({ imageLength }) =>
|
||||
(dispatch) => {
|
||||
dispatch({
|
||||
type: types.GET_PRODUCT_IMAGE_LENGTH,
|
||||
payload: imageLength,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,18 +7,15 @@
|
||||
* @exports VideoPlayerBase
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import DurationFmt from 'ilib/lib/DurationFmt';
|
||||
import PropTypes from 'prop-types';
|
||||
import shallowEqual from 'recompose/shallowEqual';
|
||||
import classNames from "classnames";
|
||||
import DurationFmt from "ilib/lib/DurationFmt";
|
||||
import PropTypes from "prop-types";
|
||||
import shallowEqual from "recompose/shallowEqual";
|
||||
|
||||
import {
|
||||
off,
|
||||
on,
|
||||
} from '@enact/core/dispatcher';
|
||||
import { off, on } from "@enact/core/dispatcher";
|
||||
import {
|
||||
adaptEvent,
|
||||
call,
|
||||
@@ -29,57 +26,46 @@ import {
|
||||
preventDefault,
|
||||
returnsTrue,
|
||||
stopImmediate,
|
||||
} from '@enact/core/handle';
|
||||
import ApiDecorator from '@enact/core/internal/ApiDecorator';
|
||||
import EnactPropTypes from '@enact/core/internal/prop-types';
|
||||
import { is } from '@enact/core/keymap';
|
||||
import { platform } from '@enact/core/platform';
|
||||
import {
|
||||
Job,
|
||||
memoize,
|
||||
perfNow,
|
||||
} from '@enact/core/util';
|
||||
import { I18nContextDecorator } from '@enact/i18n/I18nDecorator';
|
||||
import { toUpperCase } from '@enact/i18n/util';
|
||||
import Skinnable from '@enact/sandstone/Skinnable';
|
||||
import {
|
||||
getDirection,
|
||||
Spotlight,
|
||||
} from '@enact/spotlight';
|
||||
import {
|
||||
SpotlightContainerDecorator,
|
||||
} from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import { Spottable } from '@enact/spotlight/Spottable';
|
||||
import Announce from '@enact/ui/AnnounceDecorator/Announce';
|
||||
import ComponentOverride from '@enact/ui/ComponentOverride';
|
||||
import { FloatingLayerDecorator } from '@enact/ui/FloatingLayer';
|
||||
import {
|
||||
FloatingLayerContext,
|
||||
} from '@enact/ui/FloatingLayer/FloatingLayerDecorator';
|
||||
import Slottable from '@enact/ui/Slottable';
|
||||
import Touchable from '@enact/ui/Touchable';
|
||||
} from "@enact/core/handle";
|
||||
import ApiDecorator from "@enact/core/internal/ApiDecorator";
|
||||
import EnactPropTypes from "@enact/core/internal/prop-types";
|
||||
import { is } from "@enact/core/keymap";
|
||||
import { platform } from "@enact/core/platform";
|
||||
import { Job, memoize, perfNow } from "@enact/core/util";
|
||||
import { I18nContextDecorator } from "@enact/i18n/I18nDecorator";
|
||||
import { toUpperCase } from "@enact/i18n/util";
|
||||
import Skinnable from "@enact/sandstone/Skinnable";
|
||||
import { getDirection, Spotlight } from "@enact/spotlight";
|
||||
import { SpotlightContainerDecorator } from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import { Spottable } from "@enact/spotlight/Spottable";
|
||||
import Announce from "@enact/ui/AnnounceDecorator/Announce";
|
||||
import ComponentOverride from "@enact/ui/ComponentOverride";
|
||||
import { FloatingLayerDecorator } from "@enact/ui/FloatingLayer";
|
||||
import { FloatingLayerContext } from "@enact/ui/FloatingLayer/FloatingLayerDecorator";
|
||||
import Slottable from "@enact/ui/Slottable";
|
||||
import Touchable from "@enact/ui/Touchable";
|
||||
|
||||
import { $L } from '../../utils/helperMethods';
|
||||
import { SpotlightIds } from '../../utils/SpotlightIds';
|
||||
import PlayerOverlayContents
|
||||
from '../../views/PlayerPanel/PlayerOverlay/PlayerOverlayContents';
|
||||
import Loader from '../Loader/Loader';
|
||||
import { $L } from "../../utils/helperMethods";
|
||||
import { SpotlightIds } from "../../utils/SpotlightIds";
|
||||
import ThemeIndicator from "../../views/DetailPanel/components/indicator/ThemeIndicator";
|
||||
import ThemeIndicatorArrow from "../../views/DetailPanel/components/indicator/ThemeIndicatorArrow";
|
||||
import PlayerOverlayContents from "../../views/PlayerPanel/PlayerOverlay/PlayerOverlayContents";
|
||||
import Loader from "../Loader/Loader";
|
||||
import {
|
||||
MediaControls,
|
||||
MediaSlider,
|
||||
secondsToTime,
|
||||
Times,
|
||||
} from '../MediaPlayer';
|
||||
import VideoOverlayWithPhoneNumber
|
||||
from '../VideoOverlayWithPhoneNumber/VideoOverlayWithPhoneNumber';
|
||||
import FeedbackContent from './FeedbackContent';
|
||||
import FeedbackTooltip from './FeedbackTooltip';
|
||||
import Media from './Media';
|
||||
import MediaTitle from './MediaTitle';
|
||||
import Overlay from './Overlay';
|
||||
import TReactPlayer from './TReactPlayer';
|
||||
import Video from './Video';
|
||||
import css from './VideoPlayer.module.less';
|
||||
} from "../MediaPlayer";
|
||||
import VideoOverlayWithPhoneNumber from "../VideoOverlayWithPhoneNumber/VideoOverlayWithPhoneNumber";
|
||||
import FeedbackContent from "./FeedbackContent";
|
||||
import FeedbackTooltip from "./FeedbackTooltip";
|
||||
import Media from "./Media";
|
||||
import MediaTitle from "./MediaTitle";
|
||||
import Overlay from "./Overlay";
|
||||
import TReactPlayer from "./TReactPlayer";
|
||||
import Video from "./Video";
|
||||
import css from "./VideoPlayer.module.less";
|
||||
|
||||
const isEnter = is("enter");
|
||||
const isLeft = is("left");
|
||||
@@ -2093,6 +2079,8 @@ const VideoPlayerBase = class extends React.Component {
|
||||
mediaDisclaimer,
|
||||
liveTotalTime,
|
||||
currentLiveTimeSeconds,
|
||||
themeProductInfos,
|
||||
detailThemeProductImageLength,
|
||||
orderPhnNo,
|
||||
...mediaProps
|
||||
} = this.props;
|
||||
@@ -2180,6 +2168,12 @@ const VideoPlayerBase = class extends React.Component {
|
||||
<div className={css.disclaimer}> {mediaDisclaimer}</div>
|
||||
</div>
|
||||
)}
|
||||
{panelInfo.modal && type === "MEDIA" && (
|
||||
<ThemeIndicatorArrow
|
||||
themeProductInfos={themeProductInfos}
|
||||
imageLength={detailThemeProductImageLength}
|
||||
/>
|
||||
)}
|
||||
{panelInfo.modal && orderPhnNo && type !== "MEDIA" && (
|
||||
<VideoOverlayWithPhoneNumber
|
||||
className={css.videoOverlayWithPhoneNumber}
|
||||
|
||||
@@ -14,6 +14,16 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #000;
|
||||
&:after {
|
||||
width: 560px;
|
||||
height: 200px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
content: "";
|
||||
background: linear-gradient(to top, rgba(255, 255, 255, 1), transparent);
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.preloadVideo {
|
||||
@@ -29,6 +39,7 @@
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.videoOverlayWithPhoneNumber {
|
||||
width: 250px;
|
||||
height: 106px;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { types } from "../actions/actionTypes";
|
||||
|
||||
const initialState = {
|
||||
bestSellerData: {},
|
||||
productImageLength: 0,
|
||||
};
|
||||
|
||||
export const productReducer = (state = initialState, action) => {
|
||||
@@ -21,6 +22,11 @@ export const productReducer = (state = initialState, action) => {
|
||||
...state,
|
||||
groupInfo: action.payload.groupInfo,
|
||||
};
|
||||
case types.GET_PRODUCT_IMAGE_LENGTH:
|
||||
return {
|
||||
...state,
|
||||
productImageLength: action.payload + 1,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { finishVideoPreview } from "../../actions/playActions";
|
||||
import {
|
||||
clearProductDetail,
|
||||
getProductGroup,
|
||||
getProductImageLength,
|
||||
} from "../../actions/productActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import THeader from "../../components/THeader/THeader";
|
||||
@@ -186,6 +187,22 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
}
|
||||
}, [panelInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
((themeProductInfos && themeProductInfos.length > 0) ||
|
||||
(hotelInfos && hotelInfos.length > 0)) &&
|
||||
selectedIndex !== undefined
|
||||
) {
|
||||
if (type === "theme") {
|
||||
const imgUrls600 = themeProductInfos[selectedIndex]?.imgUrls600 || [];
|
||||
dispatch(getProductImageLength({ imageLength: imgUrls600.length }));
|
||||
return;
|
||||
}
|
||||
const imgUrls600 = hotelInfos[selectedIndex]?.imgUrls600 || [];
|
||||
dispatch(getProductImageLength({ imageLength: imgUrls600.length }));
|
||||
}
|
||||
}, [dispatch, themeProductInfos, selectedIndex, hotelInfos]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TPanel
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import { getProductImageLength } from "../../../actions/productActions";
|
||||
import IndicatorOptions from "../components/indicator/IndicatorOptions";
|
||||
import ThemeIndicator from "../components/indicator/ThemeIndicator";
|
||||
import ShowSingleOption from "./ShowOptions/ShowSingleOption";
|
||||
@@ -28,6 +29,8 @@ export default function ShowOption({
|
||||
);
|
||||
const productData = useSelector((state) => state.home.productData);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const showProductInfo = useMemo(() => {
|
||||
if (productData && productInfo) {
|
||||
const themeInfo = productData?.themeInfo[0];
|
||||
|
||||
@@ -63,6 +63,7 @@ function Indicator({
|
||||
}
|
||||
if (autoPlaying && productInfo?.prdtMediaUrl) {
|
||||
//auto play.
|
||||
console.log("#autoPlay indicator");
|
||||
dispatch(
|
||||
startVideoPlayer({
|
||||
showUrl: productInfo?.prdtMediaUrl,
|
||||
@@ -73,7 +74,7 @@ function Indicator({
|
||||
disclaimer: productInfo?.disclaimer,
|
||||
subtitle: productInfo?.prdtMediaSubtitlUrl,
|
||||
shptmBanrTpNm: "MEDIA",
|
||||
modal: autoPlaying,
|
||||
modal: isAutoPlaying,
|
||||
modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
|
||||
modalClassName: modalClassNameChange(),
|
||||
spotlightDisable: true,
|
||||
@@ -82,6 +83,13 @@ function Indicator({
|
||||
}
|
||||
}, [dispatch, productInfo, autoPlaying, focused, selectedIndex]);
|
||||
|
||||
const isAutoPlaying = useMemo(() => {
|
||||
if (autoPlaying) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, [autoPlaying]);
|
||||
|
||||
const modalClassNameChange = useCallback(() => {
|
||||
if (selectedIndex === 0) {
|
||||
if (focused) {
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import Image from '@enact/sandstone/Image';
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
import Image from "@enact/sandstone/Image";
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import defaultImage
|
||||
from '../../../../../assets/images/img-thumb-empty-144@3x.png';
|
||||
import { startVideoPlayer } from '../../../../actions/playActions';
|
||||
import TVirtualGridList
|
||||
from '../../../../components/TVirtualGridList/TVirtualGridList';
|
||||
import useScrollTo from '../../../../hooks/useScrollTo';
|
||||
import { panel_names } from '../../../../utils/Config';
|
||||
import { scaleW } from '../../../../utils/helperMethods';
|
||||
import css from './ThemeIndicator.module.less';
|
||||
import defaultImage from "../../../../../assets/images/img-thumb-empty-144@3x.png";
|
||||
import { startVideoPlayer } from "../../../../actions/playActions";
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { panel_names } from "../../../../utils/Config";
|
||||
import { $L, scaleW } from "../../../../utils/helperMethods";
|
||||
import css from "./ThemeIndicator.module.less";
|
||||
import ThemeIndicatorArrow from "./ThemeIndicatorArrow";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused", preserveld: true },
|
||||
@@ -58,13 +48,14 @@ export default function ThemeIndicator({
|
||||
const imageLength = thumbnailUrls && thumbnailUrls.length;
|
||||
const topPanel = panels[panels.length - 1];
|
||||
const { getScrollTo, scrollTop } = useScrollTo();
|
||||
let imagePosition = IMAGE_WIDTH * selectedIndex - IMAGE_WIDTH;
|
||||
|
||||
let imagePosition = IMAGE_WIDTH * selectedIndex - IMAGE_WIDTH;
|
||||
const getProductMediaUrlStatus = useCallback(() => {
|
||||
return (
|
||||
themeProductInfo?.prdtMediaUrl && themeProductInfo?.prdtMediaUrl !== null
|
||||
);
|
||||
}, [themeProductInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (thumbnailUrls) {
|
||||
if (getProductMediaUrlStatus()) {
|
||||
@@ -140,26 +131,6 @@ export default function ThemeIndicator({
|
||||
}
|
||||
}, [autoPlaying, themeProductInfo, imageSelectedIndex]);
|
||||
|
||||
const handlePrevClick = () => {
|
||||
if (imageSelectedIndex > 0) {
|
||||
setImageSelectedIndex((prev) => prev - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextClick = () => {
|
||||
const hasMediaUrl = getProductMediaUrlStatus();
|
||||
|
||||
if (hasMediaUrl && imageSelectedIndex + 1 < imageLength + 1) {
|
||||
setImageSelectedIndex((prev) => prev + 1);
|
||||
} else if (imageSelectedIndex + 1 < imageLength) {
|
||||
setImageSelectedIndex((prev) => prev + 1);
|
||||
}
|
||||
|
||||
if (imageLength === imageSelectedIndex) {
|
||||
Spotlight.focus("");
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpClick = useCallback(() => {
|
||||
if (selectedIndex === 0) {
|
||||
return;
|
||||
@@ -288,17 +259,7 @@ export default function ThemeIndicator({
|
||||
}
|
||||
}, [canPlayVideo, imageSelectedIndex]);
|
||||
|
||||
// const currentSpotlightDisabled = useMemo(() => {
|
||||
// if ( imageLength === (imageSelectedIndex || 1) ||
|
||||
// (!themeProductInfo?.prdtMediaUrl &&
|
||||
// imageLength - 1 === imageSelectedIndex)) {
|
||||
// return true
|
||||
// }
|
||||
// }, [])
|
||||
|
||||
const renderThumbnail = useCallback(() => {
|
||||
const hasMediaUrl = getProductMediaUrlStatus();
|
||||
|
||||
return (
|
||||
<div className={css.thumbnailContainer}>
|
||||
<SpottableComponent
|
||||
@@ -316,55 +277,16 @@ export default function ThemeIndicator({
|
||||
alt=""
|
||||
/>
|
||||
</SpottableComponent>
|
||||
<div className={css.thumbnailIndicator}>
|
||||
{soldoutFlag ? (
|
||||
<h3>SOLD OUT</h3>
|
||||
) : (
|
||||
<>
|
||||
<SpottableComponent
|
||||
className={classNames(
|
||||
css.prevButton,
|
||||
imageSelectedIndex === 0 && css.disable
|
||||
)}
|
||||
onClick={handlePrevClick}
|
||||
spotlightDisabled={
|
||||
imageSelectedIndex === -1 ||
|
||||
(!themeProductInfo?.prdtMediaUrl &&
|
||||
imageSelectedIndex === 0) ||
|
||||
(themeProductInfo?.prdtMediaUrl && imageSelectedIndex === 0)
|
||||
}
|
||||
spotlightId="thumbnailPrevButton"
|
||||
/>
|
||||
{hasMediaUrl ? (
|
||||
<span>
|
||||
{imageSelectedIndex + 1} / {imageLength + 1}
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
{imageSelectedIndex + 1} / {imageLength}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<SpottableComponent
|
||||
className={classNames(
|
||||
css.nextButton,
|
||||
imageLength === (imageSelectedIndex || 1) && css.disable,
|
||||
!themeProductInfo?.prdtMediaUrl &&
|
||||
imageLength - 1 === imageSelectedIndex &&
|
||||
css.disable
|
||||
)}
|
||||
onClick={handleNextClick}
|
||||
spotlightDisabled={
|
||||
imageLength === (imageSelectedIndex || 1) ||
|
||||
(!themeProductInfo?.prdtMediaUrl &&
|
||||
imageLength - 1 === imageSelectedIndex &&
|
||||
css.disable)
|
||||
}
|
||||
spotlightId="thumbnailNextButton"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{soldoutFlag ? (
|
||||
<h3>{$L("SOLD OUT")}</h3>
|
||||
) : (
|
||||
<ThemeIndicatorArrow
|
||||
imageSelectedIndex={imageSelectedIndex}
|
||||
setImageSelectedIndex={setImageSelectedIndex}
|
||||
themeProductInfo={themeProductInfo}
|
||||
imageLength={imageLength}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}, [
|
||||
|
||||
@@ -38,63 +38,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnailIndicator {
|
||||
width: 100%;
|
||||
margin-top: auto;
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
margin-bottom: 30px;
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
|
||||
.prevButton {
|
||||
.size(@w:42px, @h: 42px);
|
||||
.position(@position: absolute, @left: 190px, @bottom: 0 , @top: 0);
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-nor.svg");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-foc.svg");
|
||||
}
|
||||
|
||||
&.disable {
|
||||
opacity: 0.1;
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-nor.svg");
|
||||
}
|
||||
}
|
||||
.nextButton {
|
||||
.size(@w:42px, @h: 42px);
|
||||
.position(@position: absolute, @right: 190px, @bottom: 0 , @top: 0);
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-foc.svg");
|
||||
}
|
||||
&.disable {
|
||||
opacity: 0.1;
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
|
||||
}
|
||||
}
|
||||
//soldout
|
||||
> h3 {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-bottom: 237px;
|
||||
}
|
||||
> span {
|
||||
// .size(@w: 51px , @h: 21px);
|
||||
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.7);
|
||||
color: #222222;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
.size(@w: 560px, @h: 560px);
|
||||
box-shadow: 0 0 0 1px #dadada inset;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import css from "./ThemeIndicatorArrow.module.less";
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
export default function ThemeIndicatorArrow({
|
||||
imageSelectedIndex = 0,
|
||||
setImageSelectedIndex,
|
||||
themeProductInfo,
|
||||
imageLength,
|
||||
}) {
|
||||
const getProductMediaUrlStatus = useCallback(() => {
|
||||
return (
|
||||
themeProductInfo?.prdtMediaUrl && themeProductInfo?.prdtMediaUrl !== null
|
||||
);
|
||||
}, [themeProductInfo]);
|
||||
|
||||
const hasMediaUrl = getProductMediaUrlStatus();
|
||||
|
||||
const handlePrevClick = () => {
|
||||
if (imageSelectedIndex > 0) {
|
||||
setImageSelectedIndex((prev) => prev - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextClick = () => {
|
||||
if (hasMediaUrl && imageSelectedIndex + 1 < imageLength + 1) {
|
||||
setImageSelectedIndex((prev) => prev + 1);
|
||||
} else if (imageSelectedIndex + 1 < imageLength) {
|
||||
setImageSelectedIndex((prev) => prev + 1);
|
||||
}
|
||||
|
||||
if (imageLength === imageSelectedIndex) {
|
||||
Spotlight.focus("");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={css.thumbnailIndicator}>
|
||||
<>
|
||||
<SpottableComponent
|
||||
className={classNames(
|
||||
css.prevButton,
|
||||
imageSelectedIndex === 0 && css.disable
|
||||
)}
|
||||
onClick={handlePrevClick}
|
||||
spotlightDisabled={
|
||||
imageSelectedIndex === -1 ||
|
||||
(!themeProductInfo?.prdtMediaUrl && imageSelectedIndex === 0) ||
|
||||
(themeProductInfo?.prdtMediaUrl && imageSelectedIndex === 0)
|
||||
}
|
||||
spotlightId="thumbnailPrevButton"
|
||||
/>
|
||||
{hasMediaUrl ? (
|
||||
<span>
|
||||
{imageSelectedIndex + 1} / {imageLength + 1}
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
{imageSelectedIndex + 1} / {imageLength}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<SpottableComponent
|
||||
className={classNames(
|
||||
css.nextButton,
|
||||
imageLength === (imageSelectedIndex || 1) && css.disable,
|
||||
!themeProductInfo?.prdtMediaUrl &&
|
||||
imageLength - 1 === imageSelectedIndex &&
|
||||
css.disable
|
||||
)}
|
||||
onClick={handleNextClick}
|
||||
spotlightDisabled={
|
||||
imageLength === (imageSelectedIndex || 1) ||
|
||||
(!themeProductInfo?.prdtMediaUrl &&
|
||||
imageLength - 1 === imageSelectedIndex &&
|
||||
css.disable)
|
||||
}
|
||||
spotlightId="thumbnailNextButton"
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.thumbnailIndicator {
|
||||
width: 100%;
|
||||
margin-top: auto;
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
margin-bottom: 30px;
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
|
||||
.prevButton {
|
||||
.size(@w:42px, @h: 42px);
|
||||
.position(@position: absolute, @left: 190px, @bottom: 0 , @top: 0);
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-nor.svg");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-foc.svg");
|
||||
}
|
||||
|
||||
&.disable {
|
||||
opacity: 0.1;
|
||||
background-image: url("../../../../../assets/images/btn/btn-prev-thumb-nor.svg");
|
||||
}
|
||||
}
|
||||
.nextButton {
|
||||
.size(@w:42px, @h: 42px);
|
||||
.position(@position: absolute, @right: 190px, @bottom: 0 , @top: 0);
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
&:focus {
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-foc.svg");
|
||||
}
|
||||
&.disable {
|
||||
opacity: 0.1;
|
||||
background-image: url("../../../../../assets/images/btn/btn-next-thumb-nor.svg");
|
||||
}
|
||||
}
|
||||
//soldout
|
||||
> h3 {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-bottom: 237px;
|
||||
}
|
||||
> span {
|
||||
// .size(@w: 51px , @h: 21px);
|
||||
-webkit-text-stroke: 1px rgba(255, 255, 255, 0.7);
|
||||
color: #222222;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ const findSelector = (selector, maxAttempts = 5, currentAttempts = 0) => {
|
||||
return findSelector(selector, maxAttempts, currentAttempts + 1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
// console.error(error.message);
|
||||
}
|
||||
};
|
||||
const PlayerPanel = ({
|
||||
@@ -93,6 +93,15 @@ const PlayerPanel = ({
|
||||
const panels = useSelector((state) => state.panels.panels);
|
||||
const chatData = useSelector((state) => state.play.chatData);
|
||||
const showDetailInfo = useSelector((state) => state.main.showDetailInfo);
|
||||
const productImageLength = useSelector(
|
||||
(state) => state.product.productImageLength
|
||||
);
|
||||
const themeProductInfos = useSelector(
|
||||
(state) => state.home.themeCurationDetailInfoData
|
||||
);
|
||||
const hotelInfos = useSelector(
|
||||
(state) => state.home.themeCurationHotelDetailData
|
||||
);
|
||||
const captionEnable = useSelector(
|
||||
(state) => state.common.appStatus.captionEnable
|
||||
);
|
||||
@@ -107,10 +116,15 @@ const PlayerPanel = ({
|
||||
const vodSubtitleData = useSelector((state) => state.play.subTitleBlobs);
|
||||
|
||||
const initialFocusTimeoutJob = useRef(new Job((func) => func(), 600));
|
||||
|
||||
console.log("#productImageLength", productImageLength);
|
||||
const onClickBack = useCallback(
|
||||
(ev) => {
|
||||
//modal로부터 Full 전환된 경우 다시 preview 모드로 돌아감.
|
||||
console.log("####onClickBack onEnded1111", panelInfo.modal);
|
||||
console.log("#panelInfo", panelInfo);
|
||||
if (panelInfo.modalContainerId && !panelInfo.modal) {
|
||||
console.log("####onClickBack onEnded22222");
|
||||
dispatch(
|
||||
startVideoPlayer({
|
||||
...panelInfo,
|
||||
@@ -124,6 +138,7 @@ const PlayerPanel = ({
|
||||
return;
|
||||
}
|
||||
if (!panelInfo.modal) {
|
||||
console.log("####onClickBack onEnded3333333");
|
||||
dispatch(PanelActions.popPanel());
|
||||
ev?.stopPropagation();
|
||||
ev?.preventDefault();
|
||||
@@ -583,6 +598,10 @@ const PlayerPanel = ({
|
||||
smallestOffsetHourIndex &&
|
||||
shopNowInfo[smallestOffsetHourIndex]?.disclaimer
|
||||
}
|
||||
themeProductInfos={
|
||||
themeProductInfos ? themeProductInfos : hotelInfos
|
||||
}
|
||||
detailThemeProductImageLength={productImageLength}
|
||||
shopNowInfos={shopNowInfo}
|
||||
playListInfo={playListInfo && playListInfo}
|
||||
selectedIndex={selectedIndex}
|
||||
|
||||
Reference in New Issue
Block a user