diff --git a/com.twin.app.shoptime/src/components/TVerticalPagenator/TVerticalPagenator.jsx b/com.twin.app.shoptime/src/components/TVerticalPagenator/TVerticalPagenator.jsx index f40b8d19..4b70e39c 100644 --- a/com.twin.app.shoptime/src/components/TVerticalPagenator/TVerticalPagenator.jsx +++ b/com.twin.app.shoptime/src/components/TVerticalPagenator/TVerticalPagenator.jsx @@ -213,12 +213,6 @@ const TVerticalPagenator = forwardRef( focus: focus || !currentSpot, align: "top", }); - // [2024.06.04] 베너 탑인 경우에는, LIVE,VOD 로 포커스 가도록 수정 - if (node.getAttribute("data-spotlight-id") !== "DSP00101") { - if (focus || !currentSpot) { - Spotlight.focus(node); - } - } if (onFocusedContainerIdRef.current) { if (!node.getAttribute("data-spotlight-id")) { console.warn("TVerticalPagenator should have spotlight id"); diff --git a/com.twin.app.shoptime/src/components/TVirtualGridList/TVirtualGridList.jsx b/com.twin.app.shoptime/src/components/TVirtualGridList/TVirtualGridList.jsx index ae88555d..e86fd0f7 100644 --- a/com.twin.app.shoptime/src/components/TVirtualGridList/TVirtualGridList.jsx +++ b/com.twin.app.shoptime/src/components/TVirtualGridList/TVirtualGridList.jsx @@ -16,8 +16,10 @@ import { } from '../../utils/helperMethods'; import AutoScrollArea, { POSITION } from '../AutoScrollArea/AutoScrollArea'; import css from './TVirtualGridList.module.less'; +import Spotlight from '@enact/spotlight'; export default function TVirtualGridList({ + defaultSpotlightId, dataSize, direction = "vertical", className, @@ -43,6 +45,7 @@ export default function TVirtualGridList({ const scrollPosition = useRef("top"); const scrollToRef = useRef(null); + const defaultFocusTargetRef = useRef(null); const scrollHorizontalPos = useRef(0); const scrollVerticalPos = useRef(0); const visibleIndexRef = useRef({firstVisibleIndex:0, lastVisibleIndex:0}); @@ -58,6 +61,13 @@ export default function TVirtualGridList({ useEffect(() => { const listRef = gridlistParentRef.current.childNodes[0]; + if(spotlightId &&defaultSpotlightId && defaultSpotlightId.indexOf(spotlightId) === 0){ + let matched = defaultSpotlightId.match(/\d+$/); //find index + if(matched){ + defaultFocusTargetRef.current = {spotlightId: defaultSpotlightId, index: matched[0]}; + scrollToRef.current({index: matched[0], animate: false, focus: true}); + } + } if(direction === 'vertical'){ listRef.addEventListener("wheel", handleWheel, true); } @@ -86,9 +96,14 @@ export default function TVirtualGridList({ if (onScrollStop) { onScrollStop(e); } - isScrolling.current = false; - + if(defaultFocusTargetRef.current){ + if(defaultFocusTargetRef.current.index >= e.moreInfo.firstVisibleIndex + && defaultFocusTargetRef.current.index <= e.moreInfo.lastVisibleIndex){ + Spotlight.focus(defaultFocusTargetRef.current.spotlightId); + defaultFocusTargetRef.current = null; + } + } if (e.reachedEdgeInfo) { if (e.reachedEdgeInfo.top) { scrollPosition.current = "top"; diff --git a/com.twin.app.shoptime/src/utils/SpotlightIds.js b/com.twin.app.shoptime/src/utils/SpotlightIds.js index 2d4cf20b..c6751e82 100644 --- a/com.twin.app.shoptime/src/utils/SpotlightIds.js +++ b/com.twin.app.shoptime/src/utils/SpotlightIds.js @@ -21,6 +21,12 @@ export const SpotlightIds = { LIST_PLAYER: "list_player", LIST_PLAYER2: "list_player2", + // SearchPanel + SEARCH_THEME: "search_theme", + SEARCH_SHOW: "search_show", + SEARCH_ITEM: "search_item", + SEARCH_BESTSELLER: "search_bestseller", + //pin Code Popup PINCODE_CONTAINER: "pincodeContainer", }; diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx index 474301ae..bde7b9b7 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/HomeBanner.jsx @@ -72,7 +72,7 @@ export default function HomeBanner({ } return "banner" + targetIndex; } - return "banner0"; + return null; }, [bannerDataList]); useEffect(() => { @@ -87,7 +87,7 @@ export default function HomeBanner({ (index, isHorizontal) => { const data = bannerDataList?.[index] ?? {}; return ( -
+
{data.shptmDspyTpNm === "Rolling" ? (

{$L("SORRY, NO RESULTS MATCHING YOUR SEARCH")}

- + {bestSellerDatas && diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx index 16d2e628..c0606ebb 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.jsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useRef, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; @@ -9,7 +9,6 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco import { popPanel, updatePanel } from "../../actions/panelActions"; import { getSearch, resetSearch } from "../../actions/searchActions"; import TBody from "../../components/TBody/TBody"; -import TButton from "../../components/TButton/TButton"; import TInput, { ICONS, KINDS } from "../../components/TInput/TInput"; import TPanel from "../../components/TPanel/TPanel"; import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator"; @@ -20,6 +19,8 @@ import NoSearchResults from "./NoSearchResults/NoSearchResults"; import RecommendedKeywords from "./RecommendedKeywords/RecommendedKeywords"; import css from "./SearchPanel.module.less"; import SearchResults from "./SearchResults/SearchResults"; +import { setContainerLastFocusedElement } from "@enact/spotlight/src/container"; +import { SpotlightIds } from "../../utils/SpotlightIds"; const ContainerBasic = SpotlightContainerDecorator( { enterTo: "last-focused" }, @@ -30,7 +31,7 @@ const ITEMS_PER_PAGE = 9; export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) { const { sendLogGNB } = useLogService(); const dispatch = useDispatch(); - + const [firstSpot, setFirstSpot] = useState(false); const recommandedKeywords = useSelector( (state) => state.myPage.recommandedKeywordData.data?.keywords ); @@ -96,10 +97,17 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) { } }, []); + const clearAllContainerHistory = useCallback(()=>{ + setContainerLastFocusedElement(null, [SpotlightIds.SEARCH_THEME]); + setContainerLastFocusedElement(null, [SpotlightIds.SEARCH_SHOW]); + setContainerLastFocusedElement(null, [SpotlightIds.SEARCH_ITEM]); + setContainerLastFocusedElement(null, [SpotlightIds.SEARCH_BESTSELLER]); + },[]); + const handleSearchSubmit = useCallback( (query) => { + clearAllContainerHistory(); if (!searchPerformed && !query) return; - if (query.trim()) { dispatch( getSearch({ @@ -137,14 +145,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) { currentPage * ITEMS_PER_PAGE < recommandedKeywords?.length; useEffect(() => { - const focusJobValue = focusJob.current; - if (panelInfo && isOnTop) { - if (panelInfo.currentSpot) { - console.log("chw", panelInfo.currentSpot); - Spotlight.focus(panelInfo.currentSpot); - focusJobValue.start(() => Spotlight.focus(panelInfo.currentSpot)); - const currentFocusedItem = Spotlight.getCurrent(); + if (panelInfo.currentSpot && firstSpot) { + Spotlight.focus(panel_names.SEARCH_PANEL); } } }, [panelInfo, isOnTop]); @@ -194,7 +197,25 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) { ); const onFocusedContainerId = useCallback((containerId) => { setFocusedContainerId(containerId); - }, []); + if (!firstSpot) { + setTimeout(() => { + Spotlight.resume(); + setFirstSpot(true); + if (panelInfo.currentSpot) { + Spotlight.focus(panelInfo.currentSpot); + } + }, 0); + } + }, [panelInfo, firstSpot]); + + const panelInfoFall = useMemo(()=>{ + const newPanelInfo = {...panelInfo}; + if(firstSpot){ + newPanelInfo.currentSpot = null; + } + return newPanelInfo; + },[panelInfo, firstSpot]); + return ( + - - handleSearchSubmit(searchQuery)} - onKeyDown={handleKeydown} - forcedSpotlight="first-keyword-button" - spotlightId={"search-input-box"} - /> - - - {searchPerformed && searchQuery !== null ? ( - Object.keys(searchDatas).length > 0 ? ( - - ) : ( - - ) - ) : ( - - + handleSearchSubmit(searchQuery)} + onKeyDown={handleKeydown} + forcedSpotlight="first-keyword-button" + spotlightId={"search-input-box"} /> - )} - + + {searchPerformed && searchQuery !== null ? ( + Object.keys(searchDatas).length > 0 ? ( + + ) : ( + + ) + ) : ( + + + + )} + + ); diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less index 6268f51c..e52d6fbd 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.module.less @@ -6,6 +6,10 @@ .tBody { height: 100%; + >div{ + width: 100%; + height: 100%; + } .focusedContainerId{ height: 100%; } diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx index 46c8ca24..91e9c551 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResults.jsx @@ -10,6 +10,7 @@ import useLogService from "../../../hooks/useLogService"; import { $L } from "../../../utils/helperMethods"; import css from "./SearchResults.module.less"; import SearchResultsType from "./SearchResultsType"; +import { SpotlightIds } from "../../../utils/SpotlightIds"; const Container = SpotlightContainerDecorator( { enterTo: "last-focused" }, @@ -55,11 +56,11 @@ export default memo(function SearchResults({ spotJobValue.start(() => { if (searchDatas) { if (searchDatas?.theme?.length > 0) { - Spotlight.focus("searchThemeItem0"); + Spotlight.focus(SpotlightIds.SEARCH_THEME); } else if (searchDatas?.show?.length > 0) { - Spotlight.focus("searchShowItem0"); + Spotlight.focus(SpotlightIds.SEARCH_SHOW); } else { - Spotlight.focus("searchItem0"); + Spotlight.focus(SpotlightIds.SEARCH_ITEM); } } }); @@ -99,7 +100,7 @@ export default memo(function SearchResults({ count={count} data={data} idx={index} - key={title + index} + key={category + "searchResult"} panelInfo={panelInfo} searchQueryRef={searchQueryRef} sectionTitle={title} diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.jsx b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.jsx index 46dd7608..700e5a82 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.jsx +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.jsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useRef } from "react"; +import React, { useCallback, useEffect, useMemo, useRef } from "react"; import classNames from "classnames"; import { useDispatch, useSelector } from "react-redux"; @@ -16,6 +16,7 @@ import SearchItemCard from "./SearchCard/SearchItemCard"; import SearchShowCard from "./SearchCard/SearchShowCard"; import SearchThemeCard from "./SearchCard/SearchThemeCard"; import css from "./SearchResultsType.module.less"; +import { SpotlightIds } from "../../../utils/SpotlightIds"; const Container = SpotlightContainerDecorator( { leaveFor: { right: "" }, enterTo: "last-focused" }, @@ -59,10 +60,10 @@ export default function SearchResultsType({ const dataRef = usePrevious(data); useEffect(() => { - if (initPerformed) { + if(data && !panelInfo.currentSpot){ scrollLeft(); } - }, [initPerformed]); + }, [data]); useEffect(() => { const scrollLeftJobValue = scrollLeftJob.current; @@ -83,7 +84,7 @@ export default function SearchResultsType({ const onScroll = useCallback( (ev) => { const { lastVisibleIndex } = ev.moreInfo; - if (dataRef.current.length >= SEARCH_DATA_MAX_RESULTS_LIMIT) { + if (dataRef.current && dataRef.current.length >= SEARCH_DATA_MAX_RESULTS_LIMIT) { const nextSearchIndex = (Math.floor(lastVisibleIndex / SEARCH_DATA_MAX_RESULTS_LIMIT) + 1) * SEARCH_DATA_MAX_RESULTS_LIMIT + @@ -117,11 +118,11 @@ export default function SearchResultsType({ { + switch(category){ + case 'theme': + return SpotlightIds.SEARCH_THEME; + case 'show': + return SpotlightIds.SEARCH_SHOW; + case 'item': + return SpotlightIds.SEARCH_ITEM; + } + },[category]); + const { itemWidth, itemHeight, spacing } = ITEM_SIZE[category] || {}; return ( - + - - ); } diff --git a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.module.less b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.module.less index 17adada8..f5bc3b6c 100644 --- a/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.module.less +++ b/com.twin.app.shoptime/src/views/SearchPanel/SearchResults/SearchResultsType.module.less @@ -5,18 +5,16 @@ padding-left: 60px; } .container { - > div { - .flex(); + .flex(); margin: 30px 0 50px; width: 100%; - } - .grid { + &.grid { padding-right: 60px; padding-left: 60px; } &.theme { - .grid { + &.grid { > div { height: 141px; } @@ -24,7 +22,7 @@ } &.show { - .grid { + &.grid { > div { height: 240px; } @@ -32,7 +30,7 @@ } &.item { - .grid { + &.grid { > div { height: 150px; }