vertical pagenator

This commit is contained in:
yonghyon
2024-05-31 15:58:08 +09:00
parent 80f1967f6f
commit dd705d0071
17 changed files with 428 additions and 304 deletions

View File

@@ -0,0 +1,3 @@
ES5='true'
DISABLE_NEW_JSX_TRANSFORM='true'
REACT_APP_MODE=DEBUG

View File

@@ -201,11 +201,14 @@ function AppBase(props) {
useEffect(() => {
const keyDownEvent = (event) => {
dispatch(changeAppStatus({ cursorVisible: false }));
Spotlight.setPointerMode(false);
};
const mouseMoveEvent = (event) => {
dispatch(changeAppStatus({ cursorVisible: true }));
Spotlight.setPointerMode(true);
hideCursor.current.start(() => {
dispatch(changeAppStatus({ cursorVisible: false }));
Spotlight.setPointerMode(false);
});
};
if (typeof window === "object" && window.PalmSystem) {
@@ -222,9 +225,9 @@ function AppBase(props) {
document.addEventListener("webOSRelaunch", handleRelaunchEvent);
//local virtual cursorvisiblilty
if (typeof window === "object" && !window.PalmSystem) {
document.addEventListener("keydown", keyDownEvent);
document.addEventListener("mousemove", mouseMoveEvent);
document.addEventListener("wheel", mouseMoveEvent);
document.addEventListener("keydown", keyDownEvent, true);
document.addEventListener("mousemove", mouseMoveEvent, true);
document.addEventListener("wheel", mouseMoveEvent, true);
}
return () => {
document.removeEventListener("visibilitychange", visibilityChanged);

View File

@@ -102,7 +102,7 @@ export const getHttpHeaderForServiceRequest =
};
convertedRes["X-Device-Personalization"] = "Y";
if (window.PalmSystem && window.PalmSystem.identifier) {
if (window.PalmSystem && window.PalmSystem.identifier && process.env.REACT_APP_MODE !== "DEBUG") {
convertedRes["app_id"] = window.PalmSystem.identifier ?? appinfo.id;
} else {
convertedRes["app_id"] = appinfo.id;

View File

@@ -0,0 +1,170 @@
/**
* TVerticalPagenator
*
* @module TVerticalPagenator
*/
import classNames from 'classnames';
import React, {useState, useCallback, useEffect, useRef} from 'react';
import css from './TVerticalPagenator.module.less';
import TScroller from '../TScroller/TScroller';
import { useSelector } from 'react-redux';
import * as HelperMethods from "../../utils/helperMethods";
import usePrevious from '../../hooks/usePrevious';
import Spotlight from '@enact/spotlight';
const TVerticalPagenator = ({
className,
spotlightId,
defaultPageIndex=0,
children,
disabled,
pageSpotIds = [],
onPageChanged,
visible = "hidden",
scrollPositionRef,
cbChangePageRef,
scrollTop=false,
topMargin=0,
...rest
}) => {
const [pageIndex, setPageIndex] = useState(Number(defaultPageIndex) !== NaN ? Number(defaultPageIndex): 0);
const pagenatorRef = useRef(null);
const pageIndexRef = usePrevious(pageIndex);
const isScrolling = useRef(false);
const scrollTopPositionRef = useRef(0);
const scrollTo = useRef(null);
const cursorVisible = useSelector((state) => state.common.appStatus.cursorVisible);
const cursorVisibleRef = usePrevious(cursorVisible);
useEffect(() => {
if(spotlightId){
pagenatorRef.current = document.querySelector(`[data-spotlight-id="${spotlightId}"]`);
}
}, []);
const onFocusItem = useCallback((ev)=>{
if(!pagenatorRef.current){
return;
}
ev.stopPropagation();
ev.preventDefault();
if (cursorVisibleRef.current) {
return;
}
pageSpotIds.forEach((element, index) => {
const pageNode = document.querySelector(`[data-spotlight-id="${element}"]`);
if(pageNode.contains(ev.target))
setPageIndex(index);
}
);
},[pageSpotIds]);
const handleWheel = useCallback((ev) => {
if(pagenatorRef.current.contains(ev.target)){
ev.stopPropagation();
if(disabled){
return;
}
let newIndex = ev.deltaY > 0 ? pageIndexRef.current+1: pageIndexRef.current -1;
newIndex = Math.max(newIndex, 0);
newIndex = Math.min(newIndex, pageSpotIds.length-1);
setPageIndex(newIndex);
}
}, [disabled, pageSpotIds]);
const getScrollTo = useCallback((cbScrollTo) => {
scrollTo.current = cbScrollTo;
},[]);
useEffect(() => {
if (scrollTop && scrollTo.current) {
scrollTo.current({ position: { y: 0, x: 0 }, animate: true });
setPageIndex(0);
}
}, [scrollTop]);
useEffect(() => {
document.addEventListener("wheel", handleWheel, true);
return () => {
document.removeEventListener('wheel', handleWheel);
};
}, [handleWheel]);
useEffect(() => {
return () => {
scrollTo.current = null;
};
}, []);
const moveToPage = useCallback((index=0, animate=true)=>{
if(pageSpotIds[index]){
const currentNode = document.querySelector(
`[data-spotlight-id="${pageSpotIds[index]}"]`
);
if(currentNode){
const distance = Math.round(currentNode.offsetTop - HelperMethods.scaleH(topMargin));
scrollTo.current && scrollTo.current({ position:{x:0,y: distance >=0 ? distance:0}, animate: animate, focus: true });
Spotlight.focus(currentNode);
}
}
if(onPageChanged){
onPageChanged(index);
}
},[topMargin, pageSpotIds, onPageChanged]);
useEffect(() => {
moveToPage(pageIndex, true);
}, [pageIndex]);
useEffect(() => {
if(cbChangePageRef){
cbChangePageRef.current = (index)=>{
moveToPage(index, false);
setPageIndex(index);
};
}
}, [cbChangePageRef, moveToPage]);
const _onScrollStart = useCallback(() => {
isScrolling.current = true;
}, []);
const _onScrollStop = useCallback(() => {
isScrolling.current = false;
}, []);
const _onScroll = useCallback((ev) => {
isScrolling.current = true;
scrollTopPositionRef.current = ev.scrollTop;
if(scrollPositionRef){
scrollPositionRef.current = ev.scrollTop;
}
}, [scrollPositionRef]);
if(!spotlightId){
console.warn('TVerticalPagenator has no spotlightId');
return null;
}
return (
<TScroller
{...rest}
id={spotlightId}
spotlightId={spotlightId}
className={classNames(css.verticalPagenator, className)}
focusableScrollbar={visible !== "hidden"}
noScrollByWheel={true}
noScrollByDrag={true}
verticalScrollbar={visible}
onFocus={onFocusItem}
cbScrollTo={getScrollTo}
onScroll={_onScroll}
onScrollStart={_onScrollStart}
onScrollStop={_onScrollStop}
>
{children}
</TScroller>
);
};
export default TVerticalPagenator;

View File

@@ -0,0 +1,8 @@
@import "../../style/CommonStyle.module.less";
@import "../../style/utils.module.less";
.verticalPagenator {
// height: ~"calc(100% - @{fitTv-tHeader-height})";
width: 100%;
position: relative;
}

View File

@@ -0,0 +1,3 @@
{
"main": "TVerticalPagenator.jsx"
}

View File

@@ -6,21 +6,16 @@ export const getSystemInfo = (
parameters,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getSystemInfo");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.service.tv.systemproperty",
method: "getSystemInfo",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.service.tv.systemproperty",
method: "getSystemInfo",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
} else {
onSuccess({ returnValue: true, sdkVersion: "local" });
onComplete();
@@ -30,21 +25,16 @@ export const getDeviceId = (
parameters,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getDeviceId");
return "Some Hard Coded Mock Data";
} else {
return new LS2Request().send({
service: "luna://com.webos.service.sm",
method: "deviceid/getIDs",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
}
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.service.sm",
method: "deviceid/getIDs",
subscribe: false,
parameters: parameters,
onSuccess,
onFailure,
onComplete,
});
} else {
onSuccess({
returnValue: true,
@@ -57,11 +47,7 @@ export const getLoginUserData = (
parameters,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("getLoginUserData");
return "Mock Data";
} else {
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.service.accountmanager",
method: "getLoginID",
@@ -71,7 +57,6 @@ export const getLoginUserData = (
onFailure,
onComplete,
});
}
} else {
onSuccess({
subscribed: false,
@@ -119,11 +104,7 @@ export const launchMembershipAppNew = (
webOSVersion,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND launchMembershipAppNew");
return "Some Hard Coded Mock Data";
} else {
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.applicationManager",
method: "launchDefaultApp",
@@ -139,7 +120,6 @@ export const launchMembershipAppNew = (
onFailure,
onComplete,
});
}
}
};
@@ -147,11 +127,7 @@ export const launchMembershipApp = (
webOSVersion,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND launchMembershipApp");
return "Some Hard Coded Mock Data";
} else {
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.applicationManager",
method: "launch",
@@ -167,6 +143,5 @@ export const launchMembershipApp = (
onFailure,
onComplete,
});
}
}
};

View File

@@ -45,11 +45,7 @@ export const getHttpHeaderForServiceRequest = ({
onFailure,
onComplete,
}) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getHttpHeaderForServiceRequest");
return "Some Hard Coded Mock Data";
} else {
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
if (httpHeaderHandler) {
httpHeaderHandler.cancel();
}
@@ -63,7 +59,6 @@ export const getHttpHeaderForServiceRequest = ({
onComplete,
});
return httpHeaderHandler;
}
} else {
onSuccess({
HOST: "US.nextlgsdp.com",
@@ -92,11 +87,7 @@ export const getSystemSettings = (
parameters,
{ onSuccess, onFailure, onComplete }
) => {
if (typeof window === "object" && window.PalmSystem) {
if (process.env.REACT_APP_MODE === "DEBUG") {
console.log("LUNA SEND getSystemSettings");
return "Some Hard Coded Mock Data";
} else {
if (typeof window === "object" && window.PalmSystem && process.env.REACT_APP_MODE !== "DEBUG") {
return new LS2Request().send({
service: "luna://com.webos.settingsservice",
method: "getSystemSettings",
@@ -106,7 +97,6 @@ export const getSystemSettings = (
onFailure,
onComplete,
});
}
} else if (typeof window === "object") {
const language =
typeof window.navigator === "object"

View File

@@ -6,7 +6,7 @@ import stringReSourceRu from "../../resources/ru/strings.json";
import { Job } from "@enact/core/util";
let _boundingRectCache = {};
const BOUNDING_RECT_IGNORE_TIME = 100;
const BOUNDING_RECT_IGNORE_TIME = 10;
const generateUUID = () => {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
@@ -320,3 +320,15 @@ export const isChildFullyShowing = (parentNode, childNode) => {
return false;
};
export const getRectDiff = (element1, element2) => {
const element1Rect = getBoundingClientRect(element1);
const element2Rect = getBoundingClientRect(element2);
return ({
right: element1Rect.right - element2Rect.right,
left: element1Rect.left - element2Rect.left,
top: element1Rect.top - element2Rect.top,
bottom: element1Rect.bottom - element2Rect.bottom,
});
};

View File

@@ -12,8 +12,7 @@ import TItemCard from "../../../components/TItemCard/TItemCard";
import TScroller from "../../../components/TScroller/TScroller";
import useScrollReset from "../../../hooks/useScrollReset";
import useScrollTo from "../../../hooks/useScrollTo";
import useScrollTopByDistance from "../../../hooks/useScrollTopByDistance";
import { LOG_MENU, panel_names } from "../../../utils/Config";
import { panel_names } from "../../../utils/Config";
import { $L, scaleW } from "../../../utils/helperMethods";
import css from "./BestSeller.module.less";
@@ -23,13 +22,12 @@ const Container = SpotlightContainerDecorator(
"div"
);
const BestSeller = ({ order, scrollTopBody, handleItemFocus }) => {
const BestSeller = ({ order, scrollTopBody, spotlightId, handleItemFocus }) => {
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
true
);
const { scrollTopByDistance } = useScrollTopByDistance();
const dispatch = useDispatch();
@@ -90,20 +88,12 @@ const BestSeller = ({ order, scrollTopBody, handleItemFocus }) => {
if (cursorVisible) {
return;
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="homeBestSellerTitle"]`,
scrollTopBody,
36
);
},
[
cursorVisible,
_handleItemFocus,
handleScrollReset,
scrollTopBody,
scrollTopByDistance,
scrollTopBody
]
);
@@ -118,12 +108,12 @@ const BestSeller = ({ order, scrollTopBody, handleItemFocus }) => {
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.HOME_BEST_SELLER);
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container className={css.bestSellerWrap} style={orderStyle}>
<Container className={css.bestSellerWrap} style={orderStyle} spotlightId={spotlightId}>
<SectionTitle
title={$L("BEST SELLER")}
data-title-index="homeBestSellerTitle"

View File

@@ -10,7 +10,6 @@ import { changeAppStatus } from "../../../actions/commonActions";
import { getHomeMainContents } from "../../../actions/homeActions";
import CustomImage from "../../../components/CustomImage/CustomImage";
import useScrollReset from "../../../hooks/useScrollReset";
import { LOG_MENU } from "../../../utils/Config";
import css from "./HomeBanner.module.less";
import Random from "./RandomUnit";
import Rolling from "./RollingUnit";
@@ -32,6 +31,7 @@ export default function HomeBanner({
selectTemplate,
order,
firstSpot,
spotlightId,
handleItemFocus,
}) {
const dispatch = useDispatch();
@@ -188,12 +188,12 @@ export default function HomeBanner({
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.HOME_TOP);
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container className={css.container} spotlightId={"top"} style={orderStyle}>
<Container className={css.container} spotlightId={spotlightId} style={orderStyle}>
<div className={css.homeTemplateBox}>
<ContainerBasic
className={css.smallBox}

View File

@@ -8,8 +8,6 @@ import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import TScroller from "../../../components/TScroller/TScroller";
import useScrollReset from "../../../hooks/useScrollReset";
import useScrollTo from "../../../hooks/useScrollTo";
import useScrollTopByDistance from "../../../hooks/useScrollTopByDistance";
import { LOG_MENU } from "../../../utils/Config";
import { $L, scaleW } from "../../../utils/helperMethods";
import css from "./HomeOnSale.module.less";
import HomeOnSaleItem from "./HomeOnSaleItem/HomeOnSaleItem";
@@ -19,8 +17,8 @@ const Container = SpotlightContainerDecorator(
"div"
);
const HomeOnSale = ({ order, scrollTopBody, handleItemFocus, ...rest }) => {
const { scrollTopByDistance } = useScrollTopByDistance();
const HomeOnSale = ({ order, scrollTopBody, handleItemFocus,spotlightId, ...rest }) => {
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
@@ -59,13 +57,6 @@ const HomeOnSale = ({ order, scrollTopBody, handleItemFocus, ...rest }) => {
if (cursorVisible) {
return;
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="homeOnSale"]`,
scrollTopBody,
36
);
},
[
cursorVisible,
@@ -73,8 +64,7 @@ const HomeOnSale = ({ order, scrollTopBody, handleItemFocus, ...rest }) => {
handleScrollReset,
handleScrollRight,
homeOnSaleInfos?.length,
scrollTopBody,
scrollTopByDistance,
scrollTopBody
]
);
@@ -89,12 +79,12 @@ const HomeOnSale = ({ order, scrollTopBody, handleItemFocus, ...rest }) => {
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.HOME_ON_SALE);
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container {...rest} className={css.container} style={orderStyle}>
<Container {...rest} className={css.container} style={orderStyle} spotlightId={spotlightId}>
<div className={css.onSaleWrap}>
<SectionTitle
className={css.subTitle}

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
@@ -26,8 +26,7 @@ import TPanel from "../../components/TPanel/TPanel";
import TPopUp from "../../components/TPopUp/TPopUp";
import useDebugKey from "../../hooks/useDebugKey";
import useLogService from "../../hooks/useLogService";
import useScrollTo from "../../hooks/useScrollTo";
import { ACTIVE_POPUP, panel_names } from "../../utils/Config";
import { LOG_MENU, ACTIVE_POPUP, panel_names } from "../../utils/Config";
import { $L } from "../../utils/helperMethods";
import { SpotlightIds } from "../../utils/SpotlightIds";
import BestSeller from "../HomePanel/BestSeller/BestSeller";
@@ -37,6 +36,8 @@ import css from "../HomePanel/HomePanel.module.less";
import PopularShow from "../HomePanel/PopularShow/PopularShow";
import SubCategory from "../HomePanel/SubCategory/SubCategory";
import EventPopUpBanner from "./EventPopUpBanner/EventPopUpBanner";
import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator";
import usePrevious from "../../hooks/usePrevious";
const TEMPLATE_CODE_CONF = {
TOP: "DSP00101",
@@ -46,26 +47,18 @@ const TEMPLATE_CODE_CONF = {
BEST_SELLER: "DSP00105",
};
const getOrderByValue = (array, value) =>
array.find((obj) => obj["shptmApphmDspyOptCd"] === value)?.expsOrd;
const hasTemplateCodeWithValue = (array, value) =>
Array.isArray(array) &&
array.some(
(obj) =>
Object.prototype.hasOwnProperty.call(obj, "shptmApphmDspyOptCd") &&
obj["shptmApphmDspyOptCd"] === value
);
export default function HomePanel({ isOnTop }) {
const { sendLogGNB } = useLogService();
const dispatch = useDispatch();
const [selectTemplate, setSelectTemplate] = useState(null);
const [homeLayoutInfoDetail, setHomeLayoutInfoDetail] = useState([]);
const [pageIndex, setPageIndex] = useState(0);
const pageIndexRef = usePrevious(pageIndex);
const spotYoffsetRef = useRef(0);
const cbChangePageRef = useRef(null);
const [btnActive, setBtnActive] = useState(true);
const [arrowBottom, setArrowBottom] = useState(true);
useDebugKey({ isLandingPage: true });
const [firstSpot, setFirstSpot] = useState(false);
const [firstLgCatCd, setFirstLgCatCd] = useState(
@@ -102,17 +95,28 @@ export default function HomePanel({ isOnTop }) {
(state) => state.common.appStatus.webOSVersion
);
const arrowRef = useRef();
const scrollTimerRef = useRef();
const topRef = useRef();
const spotYoffsetRef = useRef(null);
const selectTemplate = useMemo(()=>{
if (homeTopDisplayInfos) {
return homeTopDisplayInfos[0].shptmTmplCd;
}
return null;
},[homeTopDisplayInfos]);
const {
getScrollTo: getScrollToBody,
scrollTop: scrollTopBody,
scrollToRef,
} = useScrollTo();
useDebugKey({ isLandingPage: true });
const sortedHomeLayoutInfo = useMemo(()=>{
if(selectTemplate && homeLayoutInfo && homeLayoutInfo.homeLayoutInfo){
const sorted = [...homeLayoutInfo.homeLayoutInfo].sort((x, y) => x.expsOrd - y.expsOrd);
return sorted;
}
return [];
},[homeLayoutInfo, selectTemplate]);
const pageSpotIds = useMemo(()=>{
const spots = [];
for(let i=0;i<sortedHomeLayoutInfo.length;i++){
spots.push(sortedHomeLayoutInfo[i].shptmApphmDspyOptCd);
}
return spots;
},[sortedHomeLayoutInfo]);
const onCancel = useCallback(() => {
if (!isOnTop) {
@@ -125,13 +129,6 @@ export default function HomePanel({ isOnTop }) {
dispatch(setShowPopup(ACTIVE_POPUP.exitPopup));
}, [isOnTop, isGnbOpened, dispatch]);
const handleItemFocus = useCallback(
(nowMenu) => {
sendLogGNB(nowMenu);
},
[sendLogGNB]
);
const onExit = useCallback(() => {
dispatch(setExitApp());
}, [dispatch]);
@@ -140,33 +137,6 @@ export default function HomePanel({ isOnTop }) {
dispatch(setHidePopup());
}, [dispatch]);
const _onScroll = useCallback(() => {
if (scrollTimerRef.current) {
clearTimeout(scrollTimerRef.current);
}
scrollTimerRef.current = setTimeout(() => {
const topElement = topRef.current;
if (!topElement) return;
const topRect = topElement.getBoundingClientRect();
const windowHeight = window.innerHeight;
const topRectRelativeToViewport =
topRect.top < windowHeight ? topRect.top : 0;
const threshold = windowHeight * 0.1; // 화면 높이의 10%
if (topRectRelativeToViewport > threshold) {
setArrowBottom(false);
} else {
setArrowBottom(true);
}
}, 0);
}, []);
const _onScrollStop = (e) => {
spotYoffsetRef.current = e.scrollTop;
};
const handleTopButtonClick = () => {
let spotId = "";
@@ -174,7 +144,9 @@ export default function HomePanel({ isOnTop }) {
if (Spotlight.focus("banner01")) {
spotId = "banner01";
}
scrollTopBody();
if(cbChangePageRef.current){
cbChangePageRef.current(0);
}
return Spotlight.focus(spotId);
}
@@ -182,7 +154,9 @@ export default function HomePanel({ isOnTop }) {
if (Spotlight.focus("banner03")) {
spotId = "banner03";
}
scrollTopBody();
if(cbChangePageRef.current){
cbChangePageRef.current(0);
}
return Spotlight.focus(spotId);
}
};
@@ -236,13 +210,15 @@ export default function HomePanel({ isOnTop }) {
let timer;
if (homeSpotlight) {
const { y } = homeSpotlight;
scrollTopBody({ y, animate: false });
if(cbChangePageRef.current){
cbChangePageRef.current(homeSpotlight.pageIndex);
}
timer = setTimeout(() => {
Spotlight.resume();
scrollTopBody({ y, animate: false }); //call again after some seconds
if(cbChangePageRef.current){ //call again after some seconds
cbChangePageRef.current(homeSpotlight.pageIndex);
}
if (homeSpotlight.currentCatCd) {
Spotlight.focus("spotlightId-" + homeSpotlight.currentCatCd);
@@ -284,7 +260,7 @@ export default function HomePanel({ isOnTop }) {
currentSpot: currentSpot,
currentCatCd: targetSpotlightCatcd,
currentCateName: targetSpotlightCateNm,
y: spotYoffsetRef.current,
pageIndex: pageIndexRef.current,
},
})
);
@@ -297,14 +273,121 @@ export default function HomePanel({ isOnTop }) {
}
}, [firstSpot]);
const doSendLogGNB = useCallback((index)=>{
let nowMenu = null;
if(pageSpotIds[index]){
switch(pageSpotIds[index]){
case TEMPLATE_CODE_CONF.TOP:
nowMenu=LOG_MENU.HOME_TOP;
break;
case TEMPLATE_CODE_CONF.CATEGORY_ITEM:
nowMenu=LOG_MENU.HOME_CATEGORY;
break;
case TEMPLATE_CODE_CONF.ON_SALE:
nowMenu=LOG_MENU.HOME_ON_SALE;
break;
case TEMPLATE_CODE_CONF.POPULAR_SHOW:
nowMenu=LOG_MENU.HOME_POPULAR_SHOWS;
break;
case TEMPLATE_CODE_CONF.BEST_SELLER:
nowMenu=LOG_MENU.HOME_BEST_SELLER;
break;
}
}
if(nowMenu){
sendLogGNB(nowMenu);
}
},[pageSpotIds, sendLogGNB]);
const handleItemFocus = useCallback((index)=> () => {
doSendLogGNB(index);
},
[doSendLogGNB]
);
useEffect(() => {
if (homeTopDisplayInfos) {
setSelectTemplate(homeTopDisplayInfos[0].shptmTmplCd);
doSendLogGNB(pageIndex);
}, [pageIndex]);
const renderPageItem = useCallback(()=>{
return (
<>
{
sortedHomeLayoutInfo.map((el, idx)=>{
switch(el.shptmApphmDspyOptCd){
case TEMPLATE_CODE_CONF.TOP:{
return (
<HomeBanner
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
selectTemplate={selectTemplate}
firstSpot={firstSpot}
className={css.homeBannerWrap}
handleItemFocus={handleItemFocus(idx)}
/>
)
}
case TEMPLATE_CODE_CONF.CATEGORY_ITEM:{
return (
<SubCategory
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
catCd={cateCd}
cateNm={cateNm}
handleItemFocus={handleItemFocus(idx)}
/>
)
}
case TEMPLATE_CODE_CONF.ON_SALE:{
return (
<HomeOnSale
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)}
/>
)
}
case TEMPLATE_CODE_CONF.POPULAR_SHOW:{
return (
<PopularShow
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)}
/>
)
}
case TEMPLATE_CODE_CONF.BEST_SELLER:{
return (
<BestSeller
key={el.shptmApphmDspyOptCd}
spotlightId={el.shptmApphmDspyOptCd}
handleItemFocus={handleItemFocus(idx)}
/>
)
}
}
})
}
<TButton
className={css.tButton}
onClick={handleTopButtonClick}
size={null}
type={TYPES.topButton}
spotlightId={"home-top-btn"}
spotlightDisabled={btnActive}
aria-label="Move to Top, Button"
/>
</>
);
},[sortedHomeLayoutInfo, selectTemplate, cateCd,cateNm, handleItemFocus, handleTopButtonClick, btnActive]);
const onPageChanged = useCallback((index) => {
if(pageSpotIds.length <=index+1){
setArrowBottom(false);
}else{
setArrowBottom(true);
}
if (homeLayoutInfo) {
setHomeLayoutInfoDetail(homeLayoutInfo.homeLayoutInfo);
}
}, [homeTopDisplayInfos, homeLayoutInfo]);
setPageIndex(index);
}, [pageSpotIds]);
return (
<>
@@ -313,95 +396,20 @@ export default function HomePanel({ isOnTop }) {
<TBody
spotlightId={SpotlightIds.HOME_TBODY}
className={css.tBody}
cbScrollTo={getScrollToBody}
onScrollStop={_onScrollStop}
onScroll={_onScroll}
scrollable={false}
>
<div data-marker="scroll-marker" ref={arrowRef} />
<div className={css.orderableFlexContainer}>
{hasTemplateCodeWithValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.TOP
) &&
selectTemplate && (
<HomeBanner
selectTemplate={selectTemplate}
scrollTopBody={scrollTopBody}
order={getOrderByValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.TOP
)}
firstSpot={firstSpot}
className={css.homeBannerWrap}
handleItemFocus={handleItemFocus}
/>
)}
{hasTemplateCodeWithValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.CATEGORY_ITEM
) && (
<SubCategory
order={getOrderByValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.CATEGORY_ITEM
)}
scrollTopBody={scrollTopBody}
catCd={cateCd}
cateNm={cateNm}
handleItemFocus={handleItemFocus}
/>
)}
{hasTemplateCodeWithValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.ON_SALE
) && (
<HomeOnSale
order={getOrderByValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.ON_SALE
)}
scrollTopBody={scrollTopBody}
handleItemFocus={handleItemFocus}
/>
)}
{hasTemplateCodeWithValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.POPULAR_SHOW
) && (
<PopularShow
order={getOrderByValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.POPULAR_SHOW
)}
scrollTopBody={scrollTopBody}
handleItemFocus={handleItemFocus}
/>
)}
{hasTemplateCodeWithValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.BEST_SELLER
) && (
<BestSeller
order={getOrderByValue(
homeLayoutInfoDetail,
TEMPLATE_CODE_CONF.BEST_SELLER
)}
scrollTopBody={scrollTopBody}
handleItemFocus={handleItemFocus}
/>
)}
</div>
<div ref={topRef}>
<TButton
className={css.tButton}
onClick={handleTopButtonClick}
size={null}
type={TYPES.topButton}
spotlightId={"home-top-btn"}
spotlightDisabled={btnActive}
aria-label={$L("TOP")}
/>
</div>
<TVerticalPagenator
className={css.tVerticalPagenator}
spotlightId={'home_verticalPagenator'}
defaultPageIndex={homeSpotlight?.pageIndex ?? 0}
disabled={!isOnTop}
pageSpotIds={pageSpotIds}
onPageChanged={onPageChanged}
scrollPositionRef={spotYoffsetRef}
cbChangePageRef={cbChangePageRef}
topMargin={36}>
{renderPageItem()}
</TVerticalPagenator>
</TBody>
{arrowBottom && (

View File

@@ -6,15 +6,14 @@
}
.tBody {
height: @globalHeight;
.orderableFlexContainer {
display: flex;
flex-direction: column;
> div {
.tVerticalPagenator {
height: 100vh !important;
>div>div>div{
margin-bottom: 70px;
}
}
.tButton {
margin-top: -10px;
margin-top: 60px;
}
}
.arrow {

View File

@@ -15,8 +15,7 @@ import TItemCard, {
import TScroller from "../../../components/TScroller/TScroller";
import useScrollReset from "../../../hooks/useScrollReset";
import useScrollTo from "../../../hooks/useScrollTo";
import useScrollTopByDistance from "../../../hooks/useScrollTopByDistance";
import { LOG_MENU, panel_names } from "../../../utils/Config";
import { panel_names } from "../../../utils/Config";
import { $L, scaleW } from "../../../utils/helperMethods";
import css from "../PopularShow/PopularShow.module.less";
@@ -30,6 +29,7 @@ const PopularShow = ({
homeChk = true,
order,
scrollTopBody,
spotlightId,
handleItemFocus,
...rest
}) => {
@@ -38,7 +38,6 @@ const PopularShow = ({
scrollLeft,
true
);
const { scrollTopByDistance } = useScrollTopByDistance();
const dispatch = useDispatch();
@@ -101,20 +100,12 @@ const PopularShow = ({
if (cursorVisible) {
return;
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="homePopularShow"]`,
scrollTopBody,
36
);
},
[
cursorVisible,
_handleItemFocus,
handleScrollReset,
scrollTopBody,
scrollTopByDistance,
scrollTopBody
]
);
@@ -129,12 +120,12 @@ const PopularShow = ({
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.HOME_POPULAR_SHOWS);
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container className={css.popularShow} style={orderStyle}>
<Container className={css.popularShow} style={orderStyle} spotlightId={spotlightId}>
<SectionTitle
className={css.subTitle}
title={$L("POPULAR SHOW")}

View File

@@ -7,7 +7,6 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import useScrollReset from "../../../../hooks/useScrollReset";
import useScrollTo from "../../../../hooks/useScrollTo";
import useScrollTopByDistance from "../../../../hooks/useScrollTopByDistance";
import CategoryNavItem from "../CategoryNav/CategoryNavItem/CategoryNavItem";
import css from "./CategoryNav.module.less";
@@ -27,7 +26,6 @@ export default function CategoryNav({
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const { scrollLeft } = useScrollTo();
const { handleScrollReset } = useScrollReset(scrollLeft, true);
const { scrollTopByDistance } = useScrollTopByDistance();
const handleFocus = useCallback(
(index) => () => {
@@ -42,20 +40,12 @@ export default function CategoryNav({
if (cursorVisible) {
return;
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="subCategoryNav"]`,
scrollTopBody,
36
);
},
[
cursorVisible,
handleItemFocus,
handleScrollReset,
scrollTopBody,
scrollTopByDistance,
scrollTopBody
]
);

View File

@@ -21,8 +21,7 @@ import TScroller from "../../../components/TScroller/TScroller";
import useLogService from "../../../hooks/useLogService";
import useScrollReset from "../../../hooks/useScrollReset";
import useScrollTo from "../../../hooks/useScrollTo";
import useScrollTopByDistance from "../../../hooks/useScrollTopByDistance";
import { LOG_MENU, LOG_TP_NO, panel_names } from "../../../utils/Config";
import { LOG_TP_NO, panel_names } from "../../../utils/Config";
import CategoryNav from "../../HomePanel/SubCategory/CategoryNav/CategoryNav";
import css from "../../HomePanel/SubCategory/SubCategory.module.less";
@@ -50,13 +49,14 @@ const SubCategory = ({
scrollTopBody,
catCd,
cateNm,
spotlightId,
handleItemFocus,
}) => {
const dispatch = useDispatch();
const { sendLogCuration } = useLogService();
const { scrollTopByDistance } = useScrollTopByDistance();
const { getScrollTo, scrollLeft } = useScrollTo();
@@ -208,20 +208,12 @@ const SubCategory = ({
if (cursorVisible) {
return;
}
scrollTopByDistance(
`[data-marker="scroll-marker"]`,
`[data-title-index="subCategoryNav"]`,
scrollTopBody,
36
);
},
[
cursorVisible,
_handleItemFocus,
handleScrollReset,
scrollTopBody,
scrollTopByDistance,
scrollTopBody
]
);
@@ -235,11 +227,11 @@ const SubCategory = ({
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.HOME_CATEGORY);
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container style={orderStyle}>
<Container style={orderStyle} spotlightId={spotlightId}>
<ContainerBasic>
<CategoryNav
categoryInfos={categoryInfos}