[SHOPTIME-2753] Launching Animation 끊김 현상 수정
원인 : 애니메이션 이미지의 첫프레임과 마지막 프레임을 분리하여 타이밍 별로 3단계 이미징 하는데 마지막 이미지를 표기하는 타이밍이 실제 애니메이션 시간과 맞지 않음 대책: 마지막 이미지는 교체 필요없음. 애니메이션 종료시 마지막 프레임이 표시되므로, 이미지 교체를 2단계로 축소
This commit is contained in:
@@ -1,45 +1,28 @@
|
|||||||
import React, {
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from "classnames";
|
||||||
import {
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
useDispatch,
|
|
||||||
useSelector,
|
|
||||||
} from 'react-redux';
|
|
||||||
|
|
||||||
import { Job } from '@enact/core/util';
|
import { Job } from "@enact/core/util";
|
||||||
import { Panel } from '@enact/sandstone/Panels';
|
import { Panel } from "@enact/sandstone/Panels";
|
||||||
import Region from '@enact/sandstone/Region';
|
import Region from "@enact/sandstone/Region";
|
||||||
import Spotlight from '@enact/spotlight';
|
import Spotlight from "@enact/spotlight";
|
||||||
import Cancelable from '@enact/ui/Cancelable';
|
import Cancelable from "@enact/ui/Cancelable";
|
||||||
|
|
||||||
import LoadingPreloadImage
|
import LoadingPreloadImage from "../../../assets/images/intro/splash_02_stop.webp";
|
||||||
from '../../../assets/images/intro/splash_02_stop.webp';
|
import LoadingAnimation from "../../../assets/images/intro/splash_03_end.webp";
|
||||||
import LoadingAnimation from '../../../assets/images/intro/splash_03_end.webp';
|
import LoadingCompleteImage from "../../../assets/images/intro/splash_04_end.webp";
|
||||||
import LoadingCompleteImage
|
import LoadingShopOnTvImage from "../../../assets/images/intro/splash_end.jpg";
|
||||||
from '../../../assets/images/intro/splash_04_end.webp';
|
import { changeAppStatus, loadingComplete } from "../../actions/commonActions";
|
||||||
import LoadingShopOnTvImage from '../../../assets/images/intro/splash_end.jpg';
|
import CustomImage from "../../components/CustomImage/CustomImage";
|
||||||
import {
|
import Loader from "../../components/Loader/Loader";
|
||||||
changeAppStatus,
|
import PreloadImage from "../../components/PreloadImage/PreloadImage";
|
||||||
loadingComplete,
|
import TPopUp from "../../components/TPopUp/TPopUp";
|
||||||
} from '../../actions/commonActions';
|
import { $L } from "../../utils/helperMethods";
|
||||||
import CustomImage from '../../components/CustomImage/CustomImage';
|
import css from "./LoadingPanel.module.less";
|
||||||
import Loader from '../../components/Loader/Loader';
|
import useWhyDidYouUpdate from "../../hooks/useWhyDidYouUpdate";
|
||||||
import PreloadImage from '../../components/PreloadImage/PreloadImage';
|
|
||||||
import TPopUp from '../../components/TPopUp/TPopUp';
|
|
||||||
import { $L } from '../../utils/helperMethods';
|
|
||||||
import css from './LoadingPanel.module.less';
|
|
||||||
|
|
||||||
const loadingImages = [
|
const loadingImages = [LoadingPreloadImage, LoadingAnimation, LoadingCompleteImage];
|
||||||
LoadingPreloadImage,
|
|
||||||
LoadingAnimation,
|
|
||||||
LoadingCompleteImage,
|
|
||||||
];
|
|
||||||
|
|
||||||
const MIN_SHOWING_TIME = { launching: 4500, wait: 300, default: 1000 };
|
const MIN_SHOWING_TIME = { launching: 4500, wait: 300, default: 1000 };
|
||||||
const MAX_SHOWING_TIME = 60000;
|
const MAX_SHOWING_TIME = 60000;
|
||||||
@@ -47,32 +30,29 @@ const MAX_SHOWING_TIME_UNLIMITED = Number.MAX_SAFE_INTEGER;
|
|||||||
const DUMMY_DELAY = 1000;
|
const DUMMY_DELAY = 1000;
|
||||||
const HIDING_TIME = 300;
|
const HIDING_TIME = 300;
|
||||||
|
|
||||||
const CancelablePanel = Cancelable(
|
const CancelablePanel = Cancelable({ modal: true, onCancel: "handleCancel" }, Panel);
|
||||||
{ modal: true, onCancel: "handleCancel" },
|
|
||||||
Panel
|
|
||||||
);
|
|
||||||
|
|
||||||
let minShowingTimeJob, hidingJob, maxShowingTimeJob;
|
let minShowingTimeJob, hidingJob, maxShowingTimeJob;
|
||||||
|
|
||||||
export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
||||||
|
const { USE_STATE, USE_SELECTOR } = useWhyDidYouUpdate("LoadingPanel", {
|
||||||
|
showLoadingPanel,
|
||||||
|
...rest,
|
||||||
|
});
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [showingStatus, setShowingStatus] = useState({
|
const [showingStatus, setShowingStatus] = USE_STATE("showingStatus", {
|
||||||
showing: true,
|
showing: true,
|
||||||
hiding: false,
|
hiding: false,
|
||||||
});
|
});
|
||||||
const [loadingSign, setLoadingSign] = useState("");
|
const [loadingType, setLoadingType] = USE_STATE("loadingType", "wait");
|
||||||
const [loadingType, setLoadingType] = useState("wait");
|
const [readyToAni, setReadyToAni] = USE_STATE("readyToAni", false);
|
||||||
const [loadingImage, setLoadingImage] = useState("");
|
const [readyToHide, setReadyToHide] = USE_STATE("readyToHide", false);
|
||||||
const [readyToAni, setReadyToAni] = useState(false);
|
|
||||||
const [readyToHide, setReadyToHide] = useState(false);
|
|
||||||
|
|
||||||
const [loadingStep, setLoadingStep] = useState(0);
|
const [loadingStep, setLoadingStep] = USE_STATE("loadingStep", 0);
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = USE_STATE("isVisible", false);
|
||||||
const webOSVersion = useSelector(
|
const webOSVersion = USE_SELECTOR("webOSVersion", (state) => state.common.appStatus?.webOSVersion);
|
||||||
(state) => state.common.appStatus?.webOSVersion
|
|
||||||
);
|
|
||||||
|
|
||||||
const httpHeader = useSelector((state) => state.common.httpHeader);
|
const httpHeader = USE_SELECTOR("httpHeader", (state) => state.common.httpHeader);
|
||||||
const deviceCountryCode = httpHeader?.["X-Device-Country"] || "";
|
const deviceCountryCode = httpHeader?.["X-Device-Country"] || "";
|
||||||
|
|
||||||
const resumeSpotlightTimeoutRef = useRef(null);
|
const resumeSpotlightTimeoutRef = useRef(null);
|
||||||
@@ -126,6 +106,7 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
} else {
|
} else {
|
||||||
setReadyToHide(false);
|
setReadyToHide(false);
|
||||||
setReadyToAni(false);
|
setReadyToAni(false);
|
||||||
|
|
||||||
minShowingTimeJob && minShowingTimeJob.stop();
|
minShowingTimeJob && minShowingTimeJob.stop();
|
||||||
hidingJob && hidingJob.stop();
|
hidingJob && hidingJob.stop();
|
||||||
maxShowingTimeJob && maxShowingTimeJob.stop();
|
maxShowingTimeJob && maxShowingTimeJob.stop();
|
||||||
@@ -156,39 +137,13 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showLoadingPanel.show) {
|
if (showLoadingPanel.show) {
|
||||||
if (!maxShowingTimeJob) {
|
if (!maxShowingTimeJob) {
|
||||||
maxShowingTimeJob = new Job(
|
maxShowingTimeJob = new Job(() => {
|
||||||
() => {
|
setShowingStatus({ showing: false, hiding: true });
|
||||||
setShowingStatus({ showing: false, hiding: true });
|
});
|
||||||
},
|
|
||||||
showLoadingPanel.type === "wait"
|
|
||||||
? MAX_SHOWING_TIME_UNLIMITED
|
|
||||||
: MAX_SHOWING_TIME
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
maxShowingTimeJob.startAfter(showLoadingPanel.type === "wait" ? MAX_SHOWING_TIME_UNLIMITED : MAX_SHOWING_TIME);
|
||||||
maxShowingTimeJob.start();
|
|
||||||
|
|
||||||
setShowingStatus({ showing: true, hiding: false });
|
setShowingStatus({ showing: true, hiding: false });
|
||||||
|
|
||||||
let signText = "",
|
|
||||||
img = "";
|
|
||||||
|
|
||||||
switch (showLoadingPanel.type) {
|
|
||||||
case "launching": {
|
|
||||||
signText = $L("Loading");
|
|
||||||
img = LoadingAnimation;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "wait": {
|
|
||||||
signText = $L("Please wait");
|
|
||||||
img = LoadingAnimation;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setLoadingSign(signText);
|
|
||||||
setLoadingImage(img);
|
|
||||||
setLoadingType(showLoadingPanel.type);
|
setLoadingType(showLoadingPanel.type);
|
||||||
}
|
}
|
||||||
}, [showLoadingPanel]);
|
}, [showLoadingPanel]);
|
||||||
@@ -232,14 +187,11 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let timer;
|
let timer;
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
if (loadingStep < 2) {
|
if (loadingStep < 1) {
|
||||||
timer = setTimeout(
|
timer = setTimeout(() => {
|
||||||
() => {
|
setIsVisible(false); // 다음 이미지를 로드하기 전에 숨김
|
||||||
setIsVisible(false); // 다음 이미지를 로드하기 전에 숨김
|
setLoadingStep((prevStep) => prevStep + 1);
|
||||||
setLoadingStep((prevStep) => prevStep + 1);
|
}, 1000);
|
||||||
},
|
|
||||||
loadingStep === 0 ? 1000 : loadingStep === 1 ? 1500 : 2000
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -247,11 +199,6 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [isVisible, loadingStep]);
|
}, [isVisible, loadingStep]);
|
||||||
|
|
||||||
// const getImageSrc = () => {
|
|
||||||
// if (webOSVersion && Number(webOSVersion) < 5) return LoadingCompleteImage;
|
|
||||||
// else return loadingImages[loadingStep];
|
|
||||||
// };
|
|
||||||
|
|
||||||
const renderImages = useCallback(() => {
|
const renderImages = useCallback(() => {
|
||||||
switch (loadingType) {
|
switch (loadingType) {
|
||||||
case "launching":
|
case "launching":
|
||||||
@@ -265,14 +212,9 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
alt="Loading Image"
|
alt="Loading Image"
|
||||||
/>
|
/>
|
||||||
) : webOSVersion && Number(webOSVersion) < 5 ? ( // webOs5.0 미만 loading image
|
) : webOSVersion && Number(webOSVersion) < 5 ? ( // webOs5.0 미만 loading image
|
||||||
<img
|
<img className={css.fullpageImage} src={LoadingCompleteImage} onLoad={handleLoad} alt="Loading Image" />
|
||||||
className={css.fullpageImage}
|
|
||||||
src={LoadingCompleteImage}
|
|
||||||
onLoad={handleLoad}
|
|
||||||
alt="Loading Image"
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
loadingStep < 3 && ( // normal loading image
|
loadingStep < 2 && ( // normal loading image
|
||||||
<img
|
<img
|
||||||
className={css.fullpageImage}
|
className={css.fullpageImage}
|
||||||
src={loadingImages[loadingStep]}
|
src={loadingImages[loadingStep]}
|
||||||
@@ -295,23 +237,13 @@ export default function LoadingPanel({ showLoadingPanel, ...rest }) {
|
|||||||
}
|
}
|
||||||
}, [loadingType, loadingStep, deviceCountryCode, webOSVersion]);
|
}, [loadingType, loadingStep, deviceCountryCode, webOSVersion]);
|
||||||
|
|
||||||
const hidingStyle = showingStatus.hiding
|
const hidingStyle = showingStatus.hiding ? { transition: "opacity " + HIDING_TIME + "ms ease", opacity: 0 } : {};
|
||||||
? { transition: "opacity " + HIDING_TIME + "ms ease", opacity: 0 }
|
|
||||||
: {};
|
|
||||||
|
|
||||||
if (showingStatus.showing || showingStatus.hiding) {
|
if (showingStatus.showing || showingStatus.hiding) {
|
||||||
return (
|
return (
|
||||||
<Region title={"LG Shoptime logo"} aria-label="LG Shoptime logo">
|
<Region title={"LG Shoptime logo"} aria-label="LG Shoptime logo">
|
||||||
<CancelablePanel
|
<CancelablePanel {...rest} className={css.panel} style={hidingStyle} handleCancel={handleCancel}>
|
||||||
{...rest}
|
<PreloadImage preloadImages={loadingImages} onLoadComplete={onPreImageLoadComplete} />
|
||||||
className={css.panel}
|
|
||||||
style={hidingStyle}
|
|
||||||
handleCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<PreloadImage
|
|
||||||
preloadImages={[loadingImage]}
|
|
||||||
onLoadComplete={onPreImageLoadComplete}
|
|
||||||
/>
|
|
||||||
{readyToAni && (
|
{readyToAni && (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
|||||||
Reference in New Issue
Block a user