[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",
SET_DEFAULT_FOCUS: "SET_DEFAULT_FOCUS",
SET_BANNER_INDEX: "SET_BANNER_INDEX",
RESET_HOME_INFO: "RESET_HOME_INFO",
UPDATE_HOME_INFO: "UPDATE_HOME_INFO",
// brand actions

View File

@@ -256,6 +256,10 @@ export const clearThemeMenuShelfInfo = () => ({
type: types.CLEAR_THEME_MENU_SHELF_INFO,
});
export const resetHomeInfo = () => ({
type: types.RESET_HOME_INFO,
});
export const updateHomeInfo = (homeInfo) => {
return {
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 { gnbOpened } from "../../actions/commonActions";
import {
checkEnterThroughGNB,
updateHomeInfo,
} from "../../actions/homeActions";
import { checkEnterThroughGNB, resetHomeInfo } from "../../actions/homeActions";
import { resetPanels } from "../../actions/panelActions";
import usePrevious from "../../hooks/usePrevious";
import useScrollTo from "../../hooks/useScrollTo";
@@ -487,16 +484,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel();
dispatch(resetPanels());
dispatch(checkEnterThroughGNB(true));
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
dispatch(resetHomeInfo());
return;
}
@@ -509,16 +497,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel();
}
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
dispatch(resetHomeInfo());
},
[deActivateTab, dispatch, panels]
);
@@ -539,16 +518,7 @@ export default function TabLayout({ topPanelName, onTabActivated, panelInfo }) {
spotToPanel();
}
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: {
currentSpot: null,
currentCatCd: null,
y: null,
},
})
);
dispatch(resetHomeInfo());
},
[dispatch, deActivateTab, selectedSubItemId]
);

View File

@@ -124,9 +124,23 @@ export const homeReducer = (state = initialState, action) => {
case types.UPDATE_HOME_INFO: {
return {
...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: {
return {
...state,

View File

@@ -9,8 +9,10 @@ import React, {
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
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 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 liveShow from "../../../../assets/images/tag-liveshow.png";
import { changeAppStatus } from "../../../actions/commonActions";
import { updateHomeInfo } from "../../../actions/homeActions";
import { sendLogTopContents } from "../../../actions/logActions";
import { pushPanel } from "../../../actions/panelActions";
import {
@@ -349,6 +352,17 @@ export default function RandomUnit({
// 비디오 클릭
const videoClick = useCallback(() => {
const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
if (lastFocusedTargetId) {
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: { lastFocusedTargetId },
})
);
}
dispatch(
startVideoPlayer({
showUrl: randomData.showUrl,

View File

@@ -9,8 +9,10 @@ import React, {
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
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 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 { LOG_MENU, LOG_TP_NO, panel_names } from "../../../utils/Config";
import { $L, formatGMTString } from "../../../utils/helperMethods";
import css from "./RollingUnit.module.less";
const SpottableComponent = Spottable("div");
@@ -386,6 +387,17 @@ export default function RollingUnit({
]);
const videoClick = useCallback(() => {
const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
if (lastFocusedTargetId) {
dispatch(
updateHomeInfo({
name: panel_names.HOME_PANEL,
panelInfo: { lastFocusedTargetId },
})
);
}
if (bannerId) {
dispatch(setBannerIndex(bannerId, startIndex));
}

View File

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

View File

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