[SHOPTIME-3604] Home > Live 진입 후 [back] 버튼 > 다시 Home으로 진입 시 화면 이슈

1. actionTypes.js
2. homeActions.js
3. TabLayout.jsx
4. homeReducer.js
5. HomePanel.jsx
6. RandomUnit.jsx
7. RollingUnit.jsx
8. MainView.jsx

- 원인: 기존의 panel 구조로는 Player를 Full로 시청할 경우 Home관련 elements가 삭제되어 결국 다시 mount 되는 것이 원인
- 대책: panel 구조 변경
This commit is contained in:
younghoon100.park
2024-11-26 17:57:22 +09:00
parent 710235c5f7
commit d4c33b7410
8 changed files with 142 additions and 120 deletions

View File

@@ -63,6 +63,7 @@ export const types = {
CHECK_ENTER_THROUGH_GNB: "CHECK_ENTER_THROUGH_GNB", CHECK_ENTER_THROUGH_GNB: "CHECK_ENTER_THROUGH_GNB",
SET_DEFAULT_FOCUS: "SET_DEFAULT_FOCUS", SET_DEFAULT_FOCUS: "SET_DEFAULT_FOCUS",
SET_BANNER_INDEX: "SET_BANNER_INDEX", SET_BANNER_INDEX: "SET_BANNER_INDEX",
RESET_HOME_INFO: "RESET_HOME_INFO",
UPDATE_HOME_INFO: "UPDATE_HOME_INFO", UPDATE_HOME_INFO: "UPDATE_HOME_INFO",
// brand actions // brand actions

View File

@@ -256,6 +256,10 @@ export const clearThemeMenuShelfInfo = () => ({
type: types.CLEAR_THEME_MENU_SHELF_INFO, type: types.CLEAR_THEME_MENU_SHELF_INFO,
}); });
export const resetHomeInfo = () => ({
type: types.RESET_HOME_INFO,
});
export const updateHomeInfo = (homeInfo) => { export const updateHomeInfo = (homeInfo) => {
return { return {
type: types.UPDATE_HOME_INFO, type: types.UPDATE_HOME_INFO,

View File

@@ -21,10 +21,7 @@ import shoptimeFullIconRuc from "../../../assets/images/icons/ic-lnb-logo-shopti
//이미지 //이미지
import shoptimeFullIcon from "../../../assets/images/icons/ic-lnb-logo-shoptime@3x.png"; import shoptimeFullIcon from "../../../assets/images/icons/ic-lnb-logo-shoptime@3x.png";
import { gnbOpened } from "../../actions/commonActions"; import { gnbOpened } from "../../actions/commonActions";
import { import { checkEnterThroughGNB, resetHomeInfo } from "../../actions/homeActions";
checkEnterThroughGNB,
updateHomeInfo,
} from "../../actions/homeActions";
import { resetPanels } from "../../actions/panelActions"; import { resetPanels } from "../../actions/panelActions";
import usePrevious from "../../hooks/usePrevious"; import usePrevious from "../../hooks/usePrevious";
import useScrollTo from "../../hooks/useScrollTo"; import useScrollTo from "../../hooks/useScrollTo";
@@ -487,16 +484,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel(); spotToPanel();
dispatch(resetPanels()); dispatch(resetPanels());
dispatch(checkEnterThroughGNB(true)); dispatch(checkEnterThroughGNB(true));
dispatch( dispatch(resetHomeInfo());
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
return; return;
} }
@@ -509,16 +497,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel(); spotToPanel();
} }
dispatch( dispatch(resetHomeInfo());
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
}, },
[deActivateTab, dispatch, panels] [deActivateTab, dispatch, panels]
); );
@@ -539,16 +518,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel(); spotToPanel();
} }
dispatch( dispatch(resetHomeInfo());
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
}, },
[dispatch, deActivateTab, selectedSubItemId] [dispatch, deActivateTab, selectedSubItemId]
); );

View File

@@ -124,9 +124,23 @@ export const homeReducer = (state = initialState, action) => {
case types.UPDATE_HOME_INFO: { case types.UPDATE_HOME_INFO: {
return { return {
...state, ...state,
homeInfo: action.payload, homeInfo: {
...action.payload,
panelInfo: {
...state.homeInfo?.panelInfo,
...action.payload?.panelInfo,
},
},
}; };
} }
case types.RESET_HOME_INFO: {
return {
...state,
homeInfo: {},
};
}
case types.CLEAR_THEME_DETAIL: { case types.CLEAR_THEME_DETAIL: {
return { return {
...state, ...state,

View File

@@ -9,8 +9,10 @@ import React, {
import classNames from "classnames"; import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable"; import Spottable from "@enact/spotlight/Spottable";
import { getContainerId } from "@enact/spotlight/src/container";
import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png"; import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png";
import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png"; import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png";
@@ -19,6 +21,7 @@ import emptyVerImage from "../../../../assets/images/img-home-banner-empty-ver.p
import defaultImageItem from "../../../../assets/images/img-thumb-empty-product@3x.png"; import defaultImageItem from "../../../../assets/images/img-thumb-empty-product@3x.png";
import liveShow from "../../../../assets/images/tag-liveshow.png"; import liveShow from "../../../../assets/images/tag-liveshow.png";
import { changeAppStatus } from "../../../actions/commonActions"; import { changeAppStatus } from "../../../actions/commonActions";
import { updateHomeInfo } from "../../../actions/homeActions";
import { sendLogTopContents } from "../../../actions/logActions"; import { sendLogTopContents } from "../../../actions/logActions";
import { pushPanel } from "../../../actions/panelActions"; import { pushPanel } from "../../../actions/panelActions";
import { import {
@@ -349,6 +352,17 @@ export default function RandomUnit({
// 비디오 클릭 // 비디오 클릭
const videoClick = useCallback(() => { const videoClick = useCallback(() => {
const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
if (lastFocusedTargetId) {
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: { lastFocusedTargetId },
})
);
}
dispatch( dispatch(
startVideoPlayer({ startVideoPlayer({
showUrl: randomData.showUrl, showUrl: randomData.showUrl,

View File

@@ -9,8 +9,10 @@ import React, {
import classNames from "classnames"; import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable"; import Spottable from "@enact/spotlight/Spottable";
import { getContainerId } from "@enact/spotlight/src/container";
import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png"; import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png";
import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png"; import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png";
@@ -26,7 +28,6 @@ import CustomImage from "../../../components/CustomImage/CustomImage";
import usePriceInfo from "../../../hooks/usePriceInfo"; import usePriceInfo from "../../../hooks/usePriceInfo";
import { LOG_MENU, LOG_TP_NO, panel_names } from "../../../utils/Config"; import { LOG_MENU, LOG_TP_NO, panel_names } from "../../../utils/Config";
import { $L, formatGMTString } from "../../../utils/helperMethods"; import { $L, formatGMTString } from "../../../utils/helperMethods";
import css from "./RollingUnit.module.less"; import css from "./RollingUnit.module.less";
const SpottableComponent = Spottable("div"); const SpottableComponent = Spottable("div");
@@ -386,6 +387,17 @@ export default function RollingUnit({
]); ]);
const videoClick = useCallback(() => { const videoClick = useCallback(() => {
const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
if (lastFocusedTargetId) {
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: { lastFocusedTargetId },
})
);
}
if (bannerId) { if (bannerId) {
dispatch(setBannerIndex(bannerId, startIndex)); dispatch(setBannerIndex(bannerId, startIndex));
} }

View File

@@ -60,7 +60,7 @@ const TEMPLATE_CODE_CONF = {
BEST_SELLER: "DSP00105", BEST_SELLER: "DSP00105",
}; };
export default function HomePanel({ isOnTop }) { const HomePanel = ({ isOnTop }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
useDebugKey({ isLandingPage: true }); useDebugKey({ isLandingPage: true });
@@ -491,6 +491,16 @@ export default function HomePanel({ isOnTop }) {
} }
}, [dispatch]); }, [dispatch]);
useEffect(() => {
if (
isOnTop &&
panelInfo?.focusedContainerId === TEMPLATE_CODE_CONF.TOP &&
panelInfo?.lastFocusedTargetId
) {
Spotlight.focus(panelInfo.lastFocusedTargetId);
}
}, [isOnTop]);
useEffect(() => { useEffect(() => {
return () => { return () => {
const c = Spotlight.getCurrent(); const c = Spotlight.getCurrent();
@@ -503,6 +513,8 @@ export default function HomePanel({ isOnTop }) {
targetSpotlightCateNm = c.getAttribute("data-catcd-nm"); targetSpotlightCateNm = c.getAttribute("data-catcd-nm");
} }
console.log("pyh ~ return ~ targetSpotlightId: ", targetSpotlightId);
const tBody = document.querySelector( const tBody = document.querySelector(
`[data-spotlight-id="${SpotlightIds.HOME_TBODY}"]` `[data-spotlight-id="${SpotlightIds.HOME_TBODY}"]`
); );
@@ -585,4 +597,6 @@ export default function HomePanel({ isOnTop }) {
</TPanel> </TPanel>
</> </>
); );
} };
export default HomePanel;

View File

@@ -4,30 +4,23 @@ import React, {
useMemo, useMemo,
useRef, useRef,
useState, useState,
} from 'react'; } from "react";
import classNames from 'classnames'; import classNames from "classnames";
import { indexOf } from 'ilib/lib/JSUtils'; import { indexOf } from "ilib/lib/JSUtils";
import { import { useDispatch, useSelector } from "react-redux";
useDispatch,
useSelector,
} from 'react-redux';
import platform from '@enact/core/platform'; import platform from "@enact/core/platform";
import Spotlight from '@enact/spotlight'; import Spotlight from "@enact/spotlight";
import defaultWatchItem import defaultWatchItem from "../../../assets/images/img-alert-banner-st@3x.png";
from '../../../assets/images/img-alert-banner-st@3x.png';
// 테스트용 - TODO: 메인 홈 화면에 나와야 하는 이미지들 추가 후 preloadImages에 추가 // 테스트용 - TODO: 메인 홈 화면에 나와야 하는 이미지들 추가 후 preloadImages에 추가
import testImage from '../../../assets/images/img-banner-myinfo-login@3x.png'; import testImage from "../../../assets/images/img-banner-myinfo-login@3x.png";
import defaultImageItem import defaultImageItem from "../../../assets/images/img-thumb-empty-product@3x.png";
from '../../../assets/images/img-thumb-empty-product@3x.png'; import LoadingPreloadImage from "../../../assets/images/intro/splash_02_stop.webp";
import LoadingPreloadImage import LoadingAnimation from "../../../assets/images/intro/splash_03_end.webp";
from '../../../assets/images/intro/splash_02_stop.webp'; import LoadingCompleteImage from "../../../assets/images/intro/splash_04_end.webp";
import LoadingAnimation from '../../../assets/images/intro/splash_03_end.webp'; import LoadingShopOnTvImage from "../../../assets/images/intro/splash_end.jpg";
import LoadingCompleteImage
from '../../../assets/images/intro/splash_04_end.webp';
import LoadingShopOnTvImage from '../../../assets/images/intro/splash_end.jpg';
import { import {
alertToast, alertToast,
changeAppStatus, changeAppStatus,
@@ -36,67 +29,58 @@ import {
setExitApp, setExitApp,
setHidePopup, setHidePopup,
setShowPopup, setShowPopup,
} from '../../actions/commonActions'; } from "../../actions/commonActions";
import { import { getHomeMenu, getHomeTerms } from "../../actions/homeActions";
getHomeMenu,
getHomeTerms,
} from '../../actions/homeActions';
import { import {
sendLogAlarmClick, sendLogAlarmClick,
sendLogAlarmPop, sendLogAlarmPop,
sendLogLive, sendLogLive,
sendLogVOD, sendLogVOD,
} from '../../actions/logActions'; } from "../../actions/logActions";
import { import {
getMyUpcomingAlertShow, getMyUpcomingAlertShow,
setMyTermsWithdraw, setMyTermsWithdraw,
} from '../../actions/myPageActions'; } from "../../actions/myPageActions";
import { import { popPanel, pushPanel, resetPanels } from "../../actions/panelActions";
popPanel, import EndOfServicePopUp from "../../components/EndOfServicePopUp/EndOfServicePopUp";
pushPanel, import Loader from "../../components/Loader/Loader";
resetPanels, import { convertUtcToLocal } from "../../components/MediaPlayer/util";
} from '../../actions/panelActions'; import PreloadImage from "../../components/PreloadImage/PreloadImage";
import EndOfServicePopUp import SystemNotification from "../../components/SystemNotification/SystemNotification";
from '../../components/EndOfServicePopUp/EndOfServicePopUp'; import TabLayout from "../../components/TabLayout/TabLayout";
import Loader from '../../components/Loader/Loader'; import TButton from "../../components/TButton/TButton";
import { convertUtcToLocal } from '../../components/MediaPlayer/util'; import TPopUp from "../../components/TPopUp/TPopUp";
import PreloadImage from '../../components/PreloadImage/PreloadImage'; import usePrevious from "../../hooks/usePrevious";
import SystemNotification import * as Config from "../../utils/Config";
from '../../components/SystemNotification/SystemNotification'; import { panel_names } from "../../utils/Config";
import TabLayout from '../../components/TabLayout/TabLayout';
import TButton from '../../components/TButton/TButton';
import TPopUp from '../../components/TPopUp/TPopUp';
import usePrevious from '../../hooks/usePrevious';
import * as Config from '../../utils/Config';
import { panel_names } from '../../utils/Config';
import { import {
$L, $L,
getErrorMessage, getErrorMessage,
getSpottableDescendants, getSpottableDescendants,
} from '../../utils/helperMethods'; } from "../../utils/helperMethods";
import { SpotlightIds } from '../../utils/SpotlightIds'; import { SpotlightIds } from "../../utils/SpotlightIds";
import CartPanel from '../CartPanel/CartPanel'; import CartPanel from "../CartPanel/CartPanel";
import CategoryPanel from '../CategoryPanel/CategoryPanel'; import CategoryPanel from "../CategoryPanel/CategoryPanel";
import CheckOutPanel from '../CheckOutPanel/CheckOutPanel'; import CheckOutPanel from "../CheckOutPanel/CheckOutPanel";
import ConfirmPanel from '../ConfirmPanel/ConfirmPanel'; import ConfirmPanel from "../ConfirmPanel/ConfirmPanel";
import DebugPanel from '../DebugPanel/DebugPanel'; import DebugPanel from "../DebugPanel/DebugPanel";
import DetailPanel from '../DetailPanel/DetailPanel'; import DetailPanel from "../DetailPanel/DetailPanel";
import ErrorPanel from '../ErrorPanel/ErrorPanel'; import ErrorPanel from "../ErrorPanel/ErrorPanel";
import FeaturedBrandsPanel from '../FeaturedBrandsPanel/FeaturedBrandsPanel'; import FeaturedBrandsPanel from "../FeaturedBrandsPanel/FeaturedBrandsPanel";
import HomePanel from '../HomePanel/HomePanel'; import HomePanel from "../HomePanel/HomePanel";
import HotPicksPanel from '../HotPicksPanel/HotPicksPanel'; import HotPicksPanel from "../HotPicksPanel/HotPicksPanel";
import ImagePanel from '../ImagePanel/ImagePanel'; import ImagePanel from "../ImagePanel/ImagePanel";
import IntroPanel from '../IntroPanel/IntroPanel'; import IntroPanel from "../IntroPanel/IntroPanel";
import LoadingPanel from '../LoadingPanel/LoadingPanel'; import LoadingPanel from "../LoadingPanel/LoadingPanel";
import MyPagePanel from '../MyPagePanel/MyPagePanel'; import MyPagePanel from "../MyPagePanel/MyPagePanel";
import OnSalePanel from '../OnSalePanel/OnSalePanel'; import OnSalePanel from "../OnSalePanel/OnSalePanel";
import PlayerPanel from '../PlayerPanel/PlayerPanel'; import PlayerPanel from "../PlayerPanel/PlayerPanel";
import SearchPanel from '../SearchPanel/SearchPanel'; import SearchPanel from "../SearchPanel/SearchPanel";
import ThemeCurationPanel from '../ThemeCurationPanel/ThemeCurationPanel'; import ThemeCurationPanel from "../ThemeCurationPanel/ThemeCurationPanel";
import TrendingNowPanel from '../TrendingNowPanel/TrendingNowPanel'; import TrendingNowPanel from "../TrendingNowPanel/TrendingNowPanel";
import VideoTestPanel from '../VideoTestPanel/VideoTestPanel'; import VideoTestPanel from "../VideoTestPanel/VideoTestPanel";
import WelcomeEventPanel from '../WelcomeEventPanel/WelcomeEventPanel'; import WelcomeEventPanel from "../WelcomeEventPanel/WelcomeEventPanel";
import css from './MainView.module.less'; import css from "./MainView.module.less";
const preloadImages = [ const preloadImages = [
LoadingPreloadImage, LoadingPreloadImage,
@@ -199,19 +183,26 @@ export default function MainView({ className }) {
const renderTopPanel = useCallback(() => { const renderTopPanel = useCallback(() => {
if (panels && panels.length > 0) { if (panels && panels.length > 0) {
let renderringPanels = []; let renderingPanels = [];
if ( if (
panels[panels.length - 1]?.name === Config.panel_names.PLAYER_PANEL || panels[panels.length - 1]?.name === Config.panel_names.PLAYER_PANEL ||
panels[panels.length - 2]?.name === Config.panel_names.PLAYER_PANEL panels[panels.length - 2]?.name === Config.panel_names.PLAYER_PANEL
) { ) {
renderringPanels = panels.slice(-2); renderingPanels = panels.slice(-2);
} else { } else {
renderringPanels = panels.slice(-1); renderingPanels = panels.slice(-1);
} }
return ( return (
<> <>
{isHomeOnTop && <HomePanel isOnTop={isHomeOnTop} />} {(isHomeOnTop ||
{renderringPanels.map((panel, index) => { (panels.length === 1 &&
panels[0]?.name === Config.panel_names.PLAYER_PANEL)) && (
<HomePanel
key={Config.panel_names.HOME_PANEL}
isOnTop={isHomeOnTop}
/>
)}
{renderingPanels.map((panel, index) => {
const Component = panelMap[panel.name]; const Component = panelMap[panel.name];
// render last two panels if there's videoplayer // render last two panels if there's videoplayer
let isPanelOnTop = false; let isPanelOnTop = false;
@@ -219,21 +210,21 @@ export default function MainView({ className }) {
{ {
/* if ( /* if (
index === 0 && index === 0 &&
renderringPanels.length === 2 && renderingPanels.length === 2 &&
renderringPanels[1].name === Config.panel_names.PLAYER_PANEL && renderingPanels[1].name === Config.panel_names.PLAYER_PANEL &&
renderringPanels[1].panelInfo.modal renderingPanels[1].panelInfo.modal
) { */ ) { */
} }
if ( if (
index === 0 && index === 0 &&
renderringPanels.length === 2 && renderingPanels.length === 2 &&
renderringPanels[1].name === Config.panel_names.PLAYER_PANEL && renderingPanels[1].name === Config.panel_names.PLAYER_PANEL &&
renderringPanels[1].panelInfo.modal renderingPanels[1].panelInfo.modal
) { ) {
isPanelOnTop = true; isPanelOnTop = true;
} }
// normal case // normal case
if (index === renderringPanels.length - 1) { if (index === renderingPanels.length - 1) {
isPanelOnTop = true; isPanelOnTop = true;
} }
@@ -250,7 +241,9 @@ export default function MainView({ className }) {
</> </>
); );
} else if (isHomeOnTop) { } else if (isHomeOnTop) {
return <HomePanel isOnTop={isHomeOnTop} />; return (
<HomePanel key={Config.panel_names.HOME_PANEL} isOnTop={isHomeOnTop} />
);
} }
return null; return null;