[251124] fix: Log정리-4
🕐 커밋 시간: 2025. 11. 24. 12:19:40 📊 변경 통계: • 총 파일: 6개 • 추가: +283줄 • 삭제: -255줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/mainActions.js ~ com.twin.app.shoptime/src/reducers/mainReducer.js ~ com.twin.app.shoptime/src/reducers/searchReducer.js ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx ~ com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.v2.jsx ~ com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/actions/mainActions.js (javascript): 🔄 Modified: clearSubCategory() 📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx (javascript): 🔄 Modified: Spottable() 📄 com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx (javascript): ✅ Added: Spottable() 🔄 Modified: clearAllTimers() 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선
This commit is contained in:
@@ -1,37 +1,19 @@
|
||||
// src/views/SearchPanel/SearchPanel.new.jsx
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
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 micIcon from '../../../assets/images/searchpanel/image-mic.png';
|
||||
import hotPicksImage from '../../../assets/images/searchpanel/img-hotpicks.png';
|
||||
import hotPicksBrandImage
|
||||
from '../../../assets/images/searchpanel/img-search-hotpicks.png';
|
||||
import {
|
||||
sendLogGNB,
|
||||
sendLogTotalRecommend,
|
||||
} from '../../actions/logActions';
|
||||
import hotPicksBrandImage from '../../../assets/images/searchpanel/img-search-hotpicks.png';
|
||||
import { sendLogGNB, sendLogTotalRecommend } from '../../actions/logActions';
|
||||
import { getMyRecommandedKeyword } from '../../actions/myPageActions';
|
||||
import {
|
||||
popPanel,
|
||||
pushPanel,
|
||||
updatePanel,
|
||||
} from '../../actions/panelActions';
|
||||
import { popPanel, pushPanel, updatePanel } from '../../actions/panelActions';
|
||||
import {
|
||||
clearPanelCommand,
|
||||
clearShopperHouseData,
|
||||
@@ -51,36 +33,27 @@ import {
|
||||
// showWarningToast,
|
||||
// } from '../../actions/toastActions';
|
||||
import TBody from '../../components/TBody/TBody';
|
||||
import TItemCardNew, {
|
||||
removeDotAndColon,
|
||||
} from '../../components/TItemCard/TItemCard.new';
|
||||
import TItemCardNew, { removeDotAndColon } from '../../components/TItemCard/TItemCard.new';
|
||||
import TPanel from '../../components/TPanel/TPanel';
|
||||
import TVerticalPagenator
|
||||
from '../../components/TVerticalPagenator/TVerticalPagenator';
|
||||
import TVirtualGridList
|
||||
from '../../components/TVirtualGridList/TVirtualGridList';
|
||||
import TVerticalPagenator from '../../components/TVerticalPagenator/TVerticalPagenator';
|
||||
import TVirtualGridList from '../../components/TVirtualGridList/TVirtualGridList';
|
||||
import usePanelHistory from '../../hooks/usePanelHistory/usePanelHistory';
|
||||
// import VirtualKeyboardContainer from "../../components/TToast/VirtualKeyboardContainer";
|
||||
import usePrevious from '../../hooks/usePrevious';
|
||||
import { useSearchHistory } from '../../hooks/useSearchHistory';
|
||||
import {
|
||||
LOG_CONTEXT_NAME,
|
||||
LOG_MENU,
|
||||
LOG_MESSAGE_ID,
|
||||
panel_names,
|
||||
} from '../../utils/Config';
|
||||
import { LOG_CONTEXT_NAME, LOG_MENU, LOG_MESSAGE_ID, panel_names } from '../../utils/Config';
|
||||
import NoSearchResults from './NoSearchResults/NoSearchResults';
|
||||
// import NoSearchResults from './NoSearchResults/NoSearchResults';
|
||||
import SearchInputOverlay from './SearchInputOverlay';
|
||||
import css from './SearchPanel.new.module.less';
|
||||
import SearchResultsNew from './SearchResults.new.v2';
|
||||
import TInputSimple, {
|
||||
ICONS,
|
||||
KINDS,
|
||||
} from './TInput/TInputSimple';
|
||||
import VoiceInputOverlay, {
|
||||
VOICE_MODES,
|
||||
} from './VoiceInputOverlay/VoiceInputOverlay';
|
||||
import TInputSimple, { ICONS, KINDS } from './TInput/TInputSimple';
|
||||
import VoiceInputOverlay, { VOICE_MODES } from './VoiceInputOverlay/VoiceInputOverlay';
|
||||
import { createDebugHelpers } from '../../utils/debug';
|
||||
|
||||
// 디버그 헬퍼 설정
|
||||
const DEBUG_MODE = false;
|
||||
const { dlog, dwarn, derror } = createDebugHelpers(DEBUG_MODE);
|
||||
|
||||
/**
|
||||
* ✨ Mode-Based Architecture 도입
|
||||
@@ -240,7 +213,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 🐛 [DEBUG] shopperHouseData 상태 변경 추적 (DEBUG_MODE가 true일 경우에만)
|
||||
useEffect(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 📊 SearchPanel shopperHouseData 상태 변경:', {
|
||||
dlog('[DEBUG] 📊 SearchPanel shopperHouseData 상태 변경:', {
|
||||
hasData: !!shopperHouseData,
|
||||
dataLength: shopperHouseData?.results?.[0]?.docs?.length || 0,
|
||||
searchId: shopperHouseData?.results?.[0]?.searchId || '(없음)',
|
||||
@@ -256,7 +229,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 🐛 [DEBUG] SearchPanel 마운트/언마운트 추적 (DEBUG_MODE가 true일 경우에만)
|
||||
useEffect(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 🚀 SearchPanel 마운트됨 - 초기 shopperHouseData 상태:', {
|
||||
dlog('[DEBUG] 🚀 SearchPanel 마운트됨 - 초기 shopperHouseData 상태:', {
|
||||
hasData: !!shopperHouseData,
|
||||
dataLength: shopperHouseData?.results?.[0]?.docs?.length || 0,
|
||||
currentMode,
|
||||
@@ -266,7 +239,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
return () => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 🔚 SearchPanel 언마운트됨 - shopperHouseData 상태:', {
|
||||
dlog('[DEBUG] 🔚 SearchPanel 언마운트됨 - shopperHouseData 상태:', {
|
||||
hasData: !!shopperHouseData,
|
||||
dataLength: shopperHouseData?.results?.[0]?.docs?.length || 0,
|
||||
timestamp: new Date().toISOString(),
|
||||
@@ -278,7 +251,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 🐛 [DEBUG] isOnTop 상태 변경 추적 (DetailPanel <-> SearchPanel 전환, DEBUG_MODE가 true일 경우에만)
|
||||
useEffect(() => {
|
||||
if (isOnTopRef.current !== isOnTop && DEBUG_MODE) {
|
||||
console.log('[DEBUG] 🔄 SearchPanel isOnTop 상태 변경:', {
|
||||
dlog('[DEBUG] 🔄 SearchPanel isOnTop 상태 변경:', {
|
||||
from: isOnTopRef.current,
|
||||
to: isOnTop,
|
||||
shopperHouseData_preserved: !!shopperHouseData,
|
||||
@@ -317,7 +290,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// API 실패 시 fallback reference 초기화
|
||||
useEffect(() => {
|
||||
if (shopperHouseErrorPopup?.visible && shopperHouseErrorPopup?.type === 'API_FAILURE') {
|
||||
console.log('[SearchPanel] 🧹 API 실패 감지 - fallbackShopperHouseData 초기화');
|
||||
dlog('[SearchPanel] 🧹 API 실패 감지 - fallbackShopperHouseData 초기화');
|
||||
shopperHouseDataRef.current = null;
|
||||
}
|
||||
}, [shopperHouseErrorPopup?.visible, shopperHouseErrorPopup?.type]);
|
||||
@@ -356,7 +329,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
currentPanel?.panelInfo?.currentSpot;
|
||||
|
||||
if (DEBUG_MODE && isReturning) {
|
||||
console.log('[FOCUS] 🎯 DetailPanel 복귀 감지:', {
|
||||
dlog('[FOCUS] 🎯 DetailPanel 복귀 감지:', {
|
||||
current: currentPanel?.panelName,
|
||||
previous: previousPanel?.panelName,
|
||||
action: currentPanel?.action,
|
||||
@@ -449,9 +422,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
// ✨ [Phase 4] Enter/OK 키 처리 - SearchInputOverlay 표시
|
||||
if (e.key === 'Enter' || e.keyCode === 13) {
|
||||
console.log(
|
||||
'[DEBUG] [SearchPanel] TInputSimple에서 Enter/OK 키 감지 → SearchInputOverlay 오픈'
|
||||
);
|
||||
dlog('[DEBUG] [SearchPanel] TInputSimple에서 Enter/OK 키 감지 → SearchInputOverlay 오픈');
|
||||
e.preventDefault();
|
||||
|
||||
// ✨ [Phase 6] SearchInputOverlay 오픈 후 자동으로 입력 준비 완료
|
||||
@@ -525,7 +496,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// * 0hun: input에 포커스 발생하여 가상 키보드 활성 시, `isInputModeActive` 상태 Boolean 값 설정
|
||||
// */
|
||||
// const handleInputModeChange = useCallback((isActive) => {
|
||||
// console.log(
|
||||
// dlog(
|
||||
// "[SearchPanel] TInput 입력 모드:",
|
||||
// isActive ? "활성화 (키보드 표시)" : "비활성화 (키보드 숨김)"
|
||||
// );
|
||||
@@ -613,7 +584,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
}
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
dlog(
|
||||
'🎤 [DEBUG][SearchPanel] openVoiceOverlay called, current isVoiceOverlayVisible:',
|
||||
isVoiceOverlayVisible
|
||||
);
|
||||
@@ -636,7 +607,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
*/
|
||||
const onCancel = useCallback(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel called', {
|
||||
dlog('[DEBUG]-onCancel called', {
|
||||
isOnTop: isOnTopRef.current,
|
||||
isVoiceOverlayVisible,
|
||||
isSearchOverlayVisible,
|
||||
@@ -649,7 +620,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
if (!isOnTopRef.current) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: isOnTopRef is false, returning');
|
||||
dlog('[DEBUG]-onCancel: isOnTopRef is false, returning');
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -657,7 +628,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// VoiceInputOverlay가 열려있으면 먼저 닫기
|
||||
if (isVoiceOverlayVisible) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: closing VoiceInputOverlay');
|
||||
dlog('[DEBUG]-onCancel: closing VoiceInputOverlay');
|
||||
}
|
||||
setIsVoiceOverlayVisible(false);
|
||||
return;
|
||||
@@ -666,7 +637,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// SearchInputOverlay가 열려있으면 먼저 닫기
|
||||
if (isSearchOverlayVisible) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: closing SearchInputOverlay');
|
||||
dlog('[DEBUG]-onCancel: closing SearchInputOverlay');
|
||||
}
|
||||
handleSearchOverlayClose();
|
||||
return;
|
||||
@@ -674,7 +645,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
// ✨ [Phase 5] VOICE_RESULT 모드에서 ESC/뒤로가기 누르면 INITIAL 모드로 돌아가기
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-VOICE_RESULT check:', {
|
||||
dlog('[DEBUG]-VOICE_RESULT check:', {
|
||||
currentMode,
|
||||
isVoiceResultMode: currentMode === SEARCH_PANEL_MODES.VOICE_RESULT,
|
||||
VOICE_RESULT_value: SEARCH_PANEL_MODES.VOICE_RESULT,
|
||||
@@ -683,11 +654,11 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
if (currentMode === SEARCH_PANEL_MODES.VOICE_RESULT) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
dlog(
|
||||
'[DEBUG]-VOICE_RESULT: Clearing ShopperHouse data (searchId will be preserved for 2nd search)'
|
||||
);
|
||||
console.log('[VoiceInput]-SearchPanel-onCancel-VOICE_RESULT');
|
||||
console.log('[VoiceInput] 🧹 VOICE_RESULT 모드에서 ESC 누름 - clearShopperHouseData 호출');
|
||||
dlog('[VoiceInput]-SearchPanel-onCancel-VOICE_RESULT');
|
||||
dlog('[VoiceInput] 🧹 VOICE_RESULT 모드에서 ESC 누름 - clearShopperHouseData 호출');
|
||||
}
|
||||
// 🎯 [포커스 로직 통합] 포커스는 상태 변경에 의해 자동으로 처리됨
|
||||
setIsShopperHousePending(false);
|
||||
@@ -696,17 +667,17 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
}
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: normal cancel logic', { searchQuery });
|
||||
dlog('[DEBUG]-onCancel: normal cancel logic', { searchQuery });
|
||||
}
|
||||
|
||||
if (searchQuery === null || searchQuery === '') {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: popping panel');
|
||||
dlog('[DEBUG]-onCancel: popping panel');
|
||||
}
|
||||
dispatch(popPanel(panel_names.SEARCH_PANEL));
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: resetting search query');
|
||||
dlog('[DEBUG]-onCancel: resetting search query');
|
||||
}
|
||||
setSearchQuery('');
|
||||
// 🎯 [포커스 로직 통합] 포커스는 상태 변경(searchQuery)에 의해 자동으로 처리됨
|
||||
@@ -820,7 +791,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
const analyzeCurrentScenario = useCallback(() => {
|
||||
// DEBUG: 모든 기본 상태값 출력
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] analyzeCurrentScenario 호출됨:', {
|
||||
dlog('[DEBUG] analyzeCurrentScenario 호출됨:', {
|
||||
// 🎯 기존 isOnTop과 usePanelHistory의 isOnTop 비교
|
||||
propIsOnTop: isOnTop,
|
||||
historyIsOnTop: currentIsOnTop,
|
||||
@@ -845,8 +816,8 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (isReturningFromDetailPanel) {
|
||||
const currentSpot = currentPanel?.panelInfo?.currentSpot;
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[Focus] usePanelHistory로 DetailPanel 복귀 감지 - 이전 상품으로 포커스 이동');
|
||||
console.log('[FOCUS] 🎯 Scenario: DETAIL_PANEL_RETURN (usePanelHistory)', {
|
||||
dlog('[Focus] usePanelHistory로 DetailPanel 복귀 감지 - 이전 상품으로 포커스 이동');
|
||||
dlog('[FOCUS] 🎯 Scenario: DETAIL_PANEL_RETURN (usePanelHistory)', {
|
||||
currentSpot,
|
||||
mode: currentMode,
|
||||
fromSearchResult: currentMode === SEARCH_PANEL_MODES.SEARCH_RESULT,
|
||||
@@ -862,7 +833,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 🎯 [개선된 fallback] usePanelHistory의 isOnTop 정보 활용
|
||||
// DetailPanel에서 방금 복귀한 상황 (usePanelHistory가 없을 경우를 대비)
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 개선된 DETAIL_PANEL_RETURN 조건 확인 (fallback):', {
|
||||
dlog('[DEBUG] 개선된 DETAIL_PANEL_RETURN 조건 확인 (fallback):', {
|
||||
// 🎯 여러 isOnTop 소스 비교
|
||||
propIsOnTop: isOnTop,
|
||||
historyIsOnTop: currentIsOnTop,
|
||||
@@ -889,8 +860,8 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
) {
|
||||
const usedHistoryOnTop = currentIsOnTop && isOnTopChange?.becameOnTop;
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[Focus] 개선된 방식으로 DetailPanel 복귀 감지 - 이전 상품으로 포커스 이동');
|
||||
console.log('[FOCUS] 🎯 Scenario: DETAIL_PANEL_RETURN (improved fallback)', {
|
||||
dlog('[Focus] 개선된 방식으로 DetailPanel 복귀 감지 - 이전 상품으로 포커스 이동');
|
||||
dlog('[FOCUS] 🎯 Scenario: DETAIL_PANEL_RETURN (improved fallback)', {
|
||||
currentSpot: panelInfo.currentSpot,
|
||||
mode: currentMode,
|
||||
fromSearchResult: currentMode === SEARCH_PANEL_MODES.SEARCH_RESULT,
|
||||
@@ -908,7 +879,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// - 위의 DETAIL_PANEL_RETURN이 아닌 경우 (= currentSpot이 없거나 모드가 검색 결과 아님)
|
||||
if (isOnTop && !isOnTopRef.current) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: INITIAL_OPEN', {
|
||||
dlog('[FOCUS] 🎯 Scenario: INITIAL_OPEN', {
|
||||
currentSpot: panelInfo?.currentSpot,
|
||||
mode: currentMode,
|
||||
});
|
||||
@@ -927,7 +898,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
currentModeRef.current !== SEARCH_PANEL_MODES.SEARCH_RESULT
|
||||
) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_RESULT_LOADED (Mode Changed)', {
|
||||
dlog('[FOCUS] 🎯 Scenario: SEARCH_RESULT_LOADED (Mode Changed)', {
|
||||
themeCount: searchDatas?.theme?.length || 0,
|
||||
itemCount: searchDatas?.item?.length || 0,
|
||||
showCount: searchDatas?.show?.length || 0,
|
||||
@@ -948,10 +919,11 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
currentMode === SEARCH_PANEL_MODES.VOICE_RESULT &&
|
||||
shopperHouseData &&
|
||||
// 🎯 [개선] 모드 변경 OR 새로운 데이터 도착 감지
|
||||
(currentModeRef.current !== SEARCH_PANEL_MODES.VOICE_RESULT || shopperHouseDataRef.current !== shopperHouseData)
|
||||
(currentModeRef.current !== SEARCH_PANEL_MODES.VOICE_RESULT ||
|
||||
shopperHouseDataRef.current !== shopperHouseData)
|
||||
) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: NEW_SEARCH_LOADED (Voice Result Mode)', {
|
||||
dlog('[FOCUS] 🎯 Scenario: NEW_SEARCH_LOADED (Voice Result Mode)', {
|
||||
itemCount: shopperHouseData?.results?.[0]?.docs?.length || 0,
|
||||
prevMode: currentModeRef.current,
|
||||
nextMode: currentMode,
|
||||
@@ -966,7 +938,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// Voice Overlay가 닫힌 상황
|
||||
if (!isVoiceOverlayVisible && isVoiceOverlayVisibleRef.current) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: VOICE_OVERLAY_CLOSED', {
|
||||
dlog('[FOCUS] 🎯 Scenario: VOICE_OVERLAY_CLOSED', {
|
||||
hasShopperHouseData: !!shopperHouseData,
|
||||
});
|
||||
}
|
||||
@@ -974,7 +946,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 이렇게 하면 VOICE_OVERLAY_CLOSED 시나리오에서 TInput으로 가는 것을 방지
|
||||
if (shopperHouseData && currentMode === SEARCH_PANEL_MODES.VOICE_RESULT) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🔄 VOICE_OVERLAY_CLOSED + new data → NEW_SEARCH_LOADED 우선 처리');
|
||||
dlog('[FOCUS] 🔄 VOICE_OVERLAY_CLOSED + new data → NEW_SEARCH_LOADED 우선 처리');
|
||||
}
|
||||
return 'NEW_SEARCH_LOADED';
|
||||
}
|
||||
@@ -986,7 +958,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// - 검색이 수행되지 않았거나 SearchPanel이 SEARCH_RESULT 모드가 아닌 경우
|
||||
if (!isSearchOverlayVisible && isSearchOverlayVisibleRef.current) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED', {
|
||||
dlog('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED', {
|
||||
isSearchOverlayVisible,
|
||||
prevIsSearchOverlayVisible: isSearchOverlayVisibleRef.current,
|
||||
currentMode,
|
||||
@@ -1040,25 +1012,25 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (isReturningFromDetailPanel && currentPanel?.panelInfo?.currentSpot) {
|
||||
currentSpot = currentPanel.panelInfo.currentSpot;
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 usePanelHistory currentSpot 사용:', currentSpot);
|
||||
dlog('[FOCUS] 🎯 usePanelHistory currentSpot 사용:', currentSpot);
|
||||
}
|
||||
}
|
||||
// 2. fallback: 기존 panelInfo.currentSpot 사용
|
||||
else if (panelInfo?.currentSpot) {
|
||||
currentSpot = panelInfo.currentSpot;
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🔄 fallback으로 panelInfo.currentSpot 사용:', currentSpot);
|
||||
dlog('[FOCUS] 🔄 fallback으로 panelInfo.currentSpot 사용:', currentSpot);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSpot && currentSpot.startsWith('searchItemContents')) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 DETAIL_PANEL_RETURN: 이전 상품으로 포커스 복원:', currentSpot);
|
||||
dlog('[FOCUS] 🎯 DETAIL_PANEL_RETURN: 이전 상품으로 포커스 복원:', currentSpot);
|
||||
}
|
||||
return currentSpot;
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
dlog(
|
||||
'[FOCUS] ⚠️ DETAIL_PANEL_RETURN: currentSpot이 유효하지 않음, fallback으로 이동:',
|
||||
{
|
||||
currentSpot,
|
||||
@@ -1094,7 +1066,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// SearchInputOverlay에서 검색을 실행하면 isSearchOverlayVisible이 false로 설정되고
|
||||
// 동시에 검색 결과에 따라 모드가 변경되므로, 이 케이스는 검색어 선택 후 닫을 때만 발생
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED - TInputSimple으로 포커스');
|
||||
dlog('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED - TInputSimple으로 포커스');
|
||||
}
|
||||
return SPOTLIGHT_IDS.SEARCH_INPUT_BOX;
|
||||
|
||||
@@ -1118,7 +1090,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
*/
|
||||
const handleTransitionToSearchInput = useCallback(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[SearchPanel] 🔄 handleTransitionToSearchInput 호출');
|
||||
dlog('[SearchPanel] 🔄 handleTransitionToSearchInput 호출');
|
||||
}
|
||||
|
||||
// Redux Thunk 액션으로 모든 전환 로직 처리
|
||||
@@ -1135,12 +1107,12 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
* Search overlay close handler
|
||||
*/
|
||||
const handleSearchOverlayClose = useCallback(() => {
|
||||
console.log('[DEBUG] 🚪 handleSearchOverlayClose 호출됨 - 직접 확인!', {
|
||||
dlog('[DEBUG] 🚪 handleSearchOverlayClose 호출됨 - 직접 확인!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 🚪 SearchInputOverlay closing');
|
||||
dlog('[DEBUG] 🚪 SearchInputOverlay closing');
|
||||
}
|
||||
|
||||
const hasSearchResults =
|
||||
@@ -1149,11 +1121,11 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
(searchDatas?.show?.length || 0) > 0;
|
||||
|
||||
// 🎯 SearchInputOverlay 닫힘 후 TInputSimple으로 포커스 이동을 위한 플래그 설정
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(true) 설정 직전', {
|
||||
dlog('[DEBUG] setShouldFocusSearchInput(true) 설정 직전', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
setShouldFocusSearchInput(true);
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(true) 설정됨!', {
|
||||
dlog('[DEBUG] setShouldFocusSearchInput(true) 설정됨!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
@@ -1171,7 +1143,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
*/
|
||||
const handleVoiceOverlayClose = useCallback(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
dlog(
|
||||
'🚪 [DEBUG][SearchPanel] handleVoiceOverlayClose called, setting isVoiceOverlayVisible to FALSE'
|
||||
);
|
||||
}
|
||||
@@ -1213,7 +1185,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
// Redux state 업데이트를 위해 약간의 지연 후 API 호출
|
||||
setTimeout(() => {
|
||||
console.log('[HowAboutThese] 🔄 Redux 업데이트 후 API 호출');
|
||||
dlog('[HowAboutThese] 🔄 Redux 업데이트 후 API 호출');
|
||||
dispatch(getShopperHouseSearch(trimmedQuery, shopperHouseSearchId));
|
||||
}, 50); // 50ms 지연
|
||||
|
||||
@@ -1337,40 +1309,40 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
[hotPicksForYou, dispatch, SafeImage]
|
||||
);
|
||||
|
||||
const handleClick = useCallback((patnrId, prdtId) => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
},[dispatch])
|
||||
|
||||
const handleClick = useCallback(
|
||||
(patnrId, prdtId) => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const renderTsvItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { offerInfo, prdtId, imgUrl, patnrId, prdtNm, priceInfo } =
|
||||
tsvInfo[index];
|
||||
|
||||
return (
|
||||
<TItemCardNew
|
||||
imageAlt={prdtNm}
|
||||
imageSource={imgUrl}
|
||||
onClick={()=>{handleClick(patnrId,prdtId)}}
|
||||
offerInfo={offerInfo}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
spotlightId={
|
||||
"searchMain-tsvInfo-spotlightId-" + removeDotAndColon(prdtId)
|
||||
}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[tsvInfo,handleClick]
|
||||
);
|
||||
({ index, ...rest }) => {
|
||||
const { offerInfo, prdtId, imgUrl, patnrId, prdtNm, priceInfo } = tsvInfo[index];
|
||||
|
||||
return (
|
||||
<TItemCardNew
|
||||
imageAlt={prdtNm}
|
||||
imageSource={imgUrl}
|
||||
onClick={() => {
|
||||
handleClick(patnrId, prdtId);
|
||||
}}
|
||||
offerInfo={offerInfo}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
spotlightId={'searchMain-tsvInfo-spotlightId-' + removeDotAndColon(prdtId)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[tsvInfo, handleClick]
|
||||
);
|
||||
|
||||
/**
|
||||
* ✨ [Phase 2] 모드별 콘텐츠 렌더링 (VoiceInputOverlay의 renderModeContent와 동일한 패턴)
|
||||
@@ -1553,7 +1525,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
</div>
|
||||
<div className={css.itemList}>
|
||||
<TVirtualGridList
|
||||
dataSize={tsvInfo.length}
|
||||
dataSize={tsvInfo.length}
|
||||
direction="horizontal"
|
||||
renderItem={renderTsvItem}
|
||||
itemWidth={324}
|
||||
@@ -1561,11 +1533,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
spacing={18}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</SectionContainer>
|
||||
</>
|
||||
)}
|
||||
|
||||
</ContainerBasic>
|
||||
);
|
||||
}
|
||||
@@ -1606,7 +1576,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
let nextMode = SEARCH_PANEL_MODES.INITIAL;
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE DECISION useEffect running', {
|
||||
dlog('[DEBUG]-MODE DECISION useEffect running', {
|
||||
isVoiceOverlayVisible,
|
||||
hasShopperHouseData: !!shopperHouseData,
|
||||
shopperHouseData_detail: shopperHouseData ? 'EXISTS' : 'NULL',
|
||||
@@ -1626,14 +1596,14 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 우선순위 1: 음성 입력 오버레이가 열려있으면 VOICE_INPUT 모드
|
||||
if (isVoiceOverlayVisible) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: isVoiceOverlayVisible is TRUE → VOICE_INPUT');
|
||||
dlog('[DEBUG]-MODE: isVoiceOverlayVisible is TRUE → VOICE_INPUT');
|
||||
}
|
||||
nextMode = SEARCH_PANEL_MODES.VOICE_INPUT;
|
||||
}
|
||||
// 우선순위 2: 음성 검색 결과가 있으면 VOICE_RESULT 모드
|
||||
else if (shopperHouseData || isShopperHousePending) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: shopperHouseData EXISTS or pending → VOICE_RESULT', {
|
||||
dlog('[DEBUG]-MODE: shopperHouseData EXISTS or pending → VOICE_RESULT', {
|
||||
hasData: !!shopperHouseData,
|
||||
isPending: isShopperHousePending,
|
||||
});
|
||||
@@ -1648,21 +1618,21 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
searchDatas?.show?.length > 0
|
||||
) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: searchResults EXISTS → SEARCH_RESULT');
|
||||
dlog('[DEBUG]-MODE: searchResults EXISTS → SEARCH_RESULT');
|
||||
}
|
||||
nextMode = SEARCH_PANEL_MODES.SEARCH_RESULT;
|
||||
}
|
||||
// 우선순위 4: 검색 입력 오버레이가 열려있으면 SEARCH_INPUT 모드
|
||||
else if (isSearchOverlayVisible) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: isSearchOverlayVisible is TRUE → SEARCH_INPUT');
|
||||
dlog('[DEBUG]-MODE: isSearchOverlayVisible is TRUE → SEARCH_INPUT');
|
||||
}
|
||||
nextMode = SEARCH_PANEL_MODES.SEARCH_INPUT;
|
||||
}
|
||||
// 우선순위 5: 초기 상태 (기본값)
|
||||
else {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: No condition met → INITIAL');
|
||||
dlog('[DEBUG]-MODE: No condition met → INITIAL');
|
||||
}
|
||||
nextMode = SEARCH_PANEL_MODES.INITIAL;
|
||||
}
|
||||
@@ -1670,7 +1640,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 모드가 변경되었을 때만 업데이트
|
||||
if (nextMode !== currentMode) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(`[DEBUG]-VOICE_RESULT 🔀 Mode changed: ${currentMode} → ${nextMode}`, {
|
||||
dlog(`[DEBUG]-VOICE_RESULT 🔀 Mode changed: ${currentMode} → ${nextMode}`, {
|
||||
isVoiceOverlayVisible,
|
||||
shopperHouseData: !!shopperHouseData,
|
||||
isShopperHousePending,
|
||||
@@ -1688,7 +1658,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
setCurrentMode(nextMode);
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-MODE: Mode unchanged -', currentMode);
|
||||
dlog('[DEBUG]-MODE: Mode unchanged -', currentMode);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
@@ -1711,11 +1681,11 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-searchQuery useEffect:', { searchQuery });
|
||||
dlog('[DEBUG]-searchQuery useEffect:', { searchQuery });
|
||||
}
|
||||
if (!searchQuery) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-VOICE_RESULT: searchQuery is empty, calling resetSearch');
|
||||
dlog('[DEBUG]-VOICE_RESULT: searchQuery is empty, calling resetSearch');
|
||||
}
|
||||
dispatch(resetSearch());
|
||||
}
|
||||
@@ -1757,7 +1727,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG][Focus] Focus useEffect 호출됨 - 상태값 확인:', {
|
||||
dlog('[DEBUG][Focus] Focus useEffect 호출됨 - 상태값 확인:', {
|
||||
isOnTop,
|
||||
panelInfo: panelInfo,
|
||||
currentMode,
|
||||
@@ -1809,9 +1779,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// NEW_SEARCH_LOADED: 음성 검색 결과 로드 시 VoiceInputOverlay와 충돌 방지
|
||||
// 다른 시나리오에서는 기존과 같은 지연 시간 (100ms)
|
||||
const focusDelay =
|
||||
scenario === 'DETAIL_PANEL_RETURN' || scenario === 'NEW_SEARCH_LOADED'
|
||||
? 50
|
||||
: 100;
|
||||
scenario === 'DETAIL_PANEL_RETURN' || scenario === 'NEW_SEARCH_LOADED' ? 50 : 100;
|
||||
|
||||
unifiedFocusTimerRef.current = setTimeout(() => {
|
||||
const targetElement = document.querySelector(`[data-spotlight-id="${targetId}"]`);
|
||||
@@ -1819,7 +1787,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (targetElement || targetId === SPOTLIGHT_IDS.SEARCH_INPUT_BOX) {
|
||||
Spotlight.focus(targetId);
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ✅ 포커스 이동 완료:', {
|
||||
dlog('[FOCUS] ✅ 포커스 이동 완료:', {
|
||||
targetId,
|
||||
scenario,
|
||||
hasElement: !!targetElement,
|
||||
@@ -1829,7 +1797,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
}
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ⚠️ 포커스 대상 요소를 찾지 못했습니다:', {
|
||||
dlog('[FOCUS] ⚠️ 포커스 대상 요소를 찾지 못했습니다:', {
|
||||
targetId,
|
||||
scenario,
|
||||
timestamp: new Date().toISOString(),
|
||||
@@ -1842,7 +1810,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
const fallbackElement = document.querySelector(`[data-spotlight-id="${fallbackTarget}"]`);
|
||||
if (fallbackElement) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
dlog(
|
||||
'[FOCUS] 🔄 DETAIL_PANEL_RETURN fallback: 첫 번째 상품으로 포커스:',
|
||||
fallbackTarget
|
||||
);
|
||||
@@ -1860,7 +1828,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (scenario === 'NEW_SEARCH_LOADED' && targetId === 'searchItemContents0') {
|
||||
setTimeout(() => {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🔄 NEW_SEARCH_LOADED: 1초 후 첫 번째 상품으로 다시 포커스 이동');
|
||||
dlog('[FOCUS] 🔄 NEW_SEARCH_LOADED: 1초 후 첫 번째 상품으로 다시 포커스 이동');
|
||||
}
|
||||
Spotlight.focus('searchItemContents0');
|
||||
}, 500); // 0.5초 후
|
||||
@@ -1908,7 +1876,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
* - 자동으로 플래그 초기화
|
||||
*/
|
||||
useEffect(() => {
|
||||
console.log('[DEBUG] shouldFocusSearchInput useEffect 실행됨!', {
|
||||
dlog('[DEBUG] shouldFocusSearchInput useEffect 실행됨!', {
|
||||
shouldFocusSearchInput,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
@@ -1916,12 +1884,12 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (shouldFocusSearchInput) {
|
||||
let focusTimer = null;
|
||||
|
||||
console.log('[DEBUG] shouldFocusSearchInput === true, 타이머 설정 중...', {
|
||||
dlog('[DEBUG] shouldFocusSearchInput === true, 타이머 설정 중...', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 SearchInputOverlay 닫힘 후 포커스 관리 useEffect 실행', {
|
||||
dlog('[FOCUS] 🎯 SearchInputOverlay 닫힘 후 포커스 관리 useEffect 실행', {
|
||||
shouldFocusSearchInput,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
@@ -1929,65 +1897,62 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
|
||||
// 500ms 후 TInputSimple에 포커스 이동
|
||||
focusTimer = setTimeout(() => {
|
||||
console.log('[DEBUG] ⏰ 500ms 타이머 콜백 실행!', {
|
||||
dlog('[DEBUG] ⏰ 500ms 타이머 콜백 실행!', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ⏰ 500ms 타이머 콜백 실행 - TInputSimple으로 포커스 이동', {
|
||||
dlog('[FOCUS] ⏰ 500ms 타이머 콜백 실행 - TInputSimple으로 포커스 이동', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('[DEBUG] Spotlight.focus() 호출 직전', {
|
||||
dlog('[DEBUG] Spotlight.focus() 호출 직전', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
});
|
||||
|
||||
Spotlight.focus(SPOTLIGHT_IDS.SEARCH_INPUT_BOX);
|
||||
|
||||
console.log('[DEBUG] Spotlight.focus() 호출 완료!', {
|
||||
dlog('[DEBUG] Spotlight.focus() 호출 완료!', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ✅ Spotlight.focus() 호출 완료', {
|
||||
dlog('[FOCUS] ✅ Spotlight.focus() 호출 완료', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(false) 호출 직전', {
|
||||
dlog('[DEBUG] setShouldFocusSearchInput(false) 호출 직전', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
// 포커스 이동 완료 후 플래그 초기화
|
||||
setShouldFocusSearchInput(false);
|
||||
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(false) 호출 완료!', {
|
||||
dlog('[DEBUG] setShouldFocusSearchInput(false) 호출 완료!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}, 500);
|
||||
|
||||
console.log('[DEBUG] 타이머 설정 완료 - 500ms 후 포커스 이동 예약됨', {
|
||||
dlog('[DEBUG] 타이머 설정 완료 - 500ms 후 포커스 이동 예약됨', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
// Cleanup: 타이머 정리
|
||||
return () => {
|
||||
console.log('[DEBUG] shouldFocusSearchInput useEffect cleanup 실행', {
|
||||
dlog('[DEBUG] shouldFocusSearchInput useEffect cleanup 실행', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
if (focusTimer) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
'[FOCUS] 🧹 SearchInputOverlay 포커스 관리 useEffect cleanup - 타이머 정리',
|
||||
{
|
||||
timestamp: new Date().toISOString(),
|
||||
}
|
||||
);
|
||||
dlog('[FOCUS] 🧹 SearchInputOverlay 포커스 관리 useEffect cleanup - 타이머 정리', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
clearTimeout(focusTimer);
|
||||
}
|
||||
@@ -2149,7 +2114,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
} // ✅ INITIAL, VOICE_RESULT & SEARCH_RESULT 모드에서 TInputSimple 내부 포커스 활성화
|
||||
onKeyDown={handleKeydown}
|
||||
onMouseDown={() => {
|
||||
console.log(
|
||||
dlog(
|
||||
'[DEBUG] [SearchPanel] TInputSimple에서 마우스 클릭 감지 → SearchInputOverlay 오픈'
|
||||
);
|
||||
setIsSearchOverlayVisible(true);
|
||||
|
||||
Reference in New Issue
Block a user