[251031] fix: SearchInputOverlay TurnBack Focus
🕐 커밋 시간: 2025. 10. 31. 10:44:59 📊 변경 통계: • 총 파일: 1개 • 추가: +132줄 • 삭제: -4줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.v2.jsx 🔧 주요 변경 내용: • 중간 규모 기능 개선
This commit is contained in:
@@ -226,6 +226,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
// 마이크 버튼 포커스 가능 여부 상태
|
||||
const [isMicFocusable, setIsMicFocusable] = useState(true);
|
||||
|
||||
// 🎯 SearchInputOverlay 닫힘 후 포커스 관리 - 명시적 플래그
|
||||
const [shouldFocusSearchInput, setShouldFocusSearchInput] = useState(false);
|
||||
|
||||
// 🐛 [DEBUG] shopperHouseData 상태 변경 추적 (DEBUG_MODE가 true일 경우에만)
|
||||
useEffect(() => {
|
||||
if (DEBUG_MODE) {
|
||||
@@ -645,7 +648,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG]-onCancel: closing SearchInputOverlay');
|
||||
}
|
||||
setIsSearchOverlayVisible(false);
|
||||
handleSearchOverlayClose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -949,9 +952,21 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
}
|
||||
|
||||
// Search Overlay가 닫힌 상황
|
||||
// - isSearchOverlayVisible이 true → false로 변경되고
|
||||
// - 검색이 수행되지 않았거나 SearchPanel이 SEARCH_RESULT 모드가 아닌 경우
|
||||
if (!isSearchOverlayVisible && isSearchOverlayVisibleRef.current) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED');
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED', {
|
||||
isSearchOverlayVisible,
|
||||
prevIsSearchOverlayVisible: isSearchOverlayVisibleRef.current,
|
||||
currentMode,
|
||||
searchPerformed,
|
||||
hasSearchResults: !!(
|
||||
searchDatas?.theme?.length > 0 ||
|
||||
searchDatas?.item?.length > 0 ||
|
||||
searchDatas?.show?.length > 0
|
||||
),
|
||||
});
|
||||
}
|
||||
return 'SEARCH_OVERLAY_CLOSED';
|
||||
}
|
||||
@@ -1035,13 +1050,21 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
return 'searchItemContents0';
|
||||
|
||||
case 'VOICE_OVERLAY_CLOSED':
|
||||
case 'SEARCH_OVERLAY_CLOSED':
|
||||
// Overlay 닫힘 → ShopperHouse 데이터 있으면 상품, 없으면 TInput
|
||||
// Voice Overlay 닫힘 → ShopperHouse 데이터 있으면 상품, 없으면 TInput
|
||||
if (shopperHouseData) {
|
||||
return 'searchItemContents0';
|
||||
}
|
||||
return SPOTLIGHT_IDS.SEARCH_INPUT_BOX;
|
||||
|
||||
case 'SEARCH_OVERLAY_CLOSED':
|
||||
// 🎯 SearchInputOverlay 닫힘 (ESC/Back) → 항상 TInputSimple으로 포커스
|
||||
// SearchInputOverlay에서 검색을 실행하면 isSearchOverlayVisible이 false로 설정되고
|
||||
// 동시에 검색 결과에 따라 모드가 변경되므로, 이 케이스는 검색어 선택 후 닫을 때만 발생
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 Scenario: SEARCH_OVERLAY_CLOSED - TInputSimple으로 포커스');
|
||||
}
|
||||
return SPOTLIGHT_IDS.SEARCH_INPUT_BOX;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -1070,6 +1093,10 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
* Search overlay close handler
|
||||
*/
|
||||
const handleSearchOverlayClose = useCallback(() => {
|
||||
console.log('[DEBUG] 🚪 handleSearchOverlayClose 호출됨 - 직접 확인!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[DEBUG] 🚪 SearchInputOverlay closing');
|
||||
}
|
||||
@@ -1079,6 +1106,15 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
(searchDatas?.item?.length || 0) > 0 ||
|
||||
(searchDatas?.show?.length || 0) > 0;
|
||||
|
||||
// 🎯 SearchInputOverlay 닫힘 후 TInputSimple으로 포커스 이동을 위한 플래그 설정
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(true) 설정 직전', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
setShouldFocusSearchInput(true);
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(true) 설정됨!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
// 🎯 [포커스 로직 통합] 포커스는 상태 변경(isSearchOverlayVisible)에 의해 자동으로 처리됨
|
||||
setIsSearchOverlayVisible(false);
|
||||
|
||||
@@ -1742,6 +1778,98 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
currentModeRef.current = currentMode;
|
||||
}, [shopperHouseData, searchDatas, isVoiceOverlayVisible, isSearchOverlayVisible, currentMode]);
|
||||
|
||||
/**
|
||||
* 🎯 SearchInputOverlay 닫힘 후 포커스 관리
|
||||
* shouldFocusSearchInput 플래그가 true로 설정되면 500ms 후 TInputSimple으로 포커스 이동
|
||||
* - 명시적 플래그를 통해 SearchInputOverlay 닫힘 시나리오 처리
|
||||
* - 다른 포커스 로직과 독립적으로 동작
|
||||
* - 자동으로 플래그 초기화
|
||||
*/
|
||||
useEffect(() => {
|
||||
console.log('[DEBUG] shouldFocusSearchInput useEffect 실행됨!', {
|
||||
shouldFocusSearchInput,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (shouldFocusSearchInput) {
|
||||
let focusTimer = null;
|
||||
|
||||
console.log('[DEBUG] shouldFocusSearchInput === true, 타이머 설정 중...', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🎯 SearchInputOverlay 닫힘 후 포커스 관리 useEffect 실행', {
|
||||
shouldFocusSearchInput,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
// 500ms 후 TInputSimple에 포커스 이동
|
||||
focusTimer = setTimeout(() => {
|
||||
console.log('[DEBUG] ⏰ 500ms 타이머 콜백 실행!', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ⏰ 500ms 타이머 콜백 실행 - TInputSimple으로 포커스 이동', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('[DEBUG] Spotlight.focus() 호출 직전', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
});
|
||||
|
||||
Spotlight.focus(SPOTLIGHT_IDS.SEARCH_INPUT_BOX);
|
||||
|
||||
console.log('[DEBUG] Spotlight.focus() 호출 완료!', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] ✅ Spotlight.focus() 호출 완료', {
|
||||
targetId: SPOTLIGHT_IDS.SEARCH_INPUT_BOX,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(false) 호출 직전', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
// 포커스 이동 완료 후 플래그 초기화
|
||||
setShouldFocusSearchInput(false);
|
||||
|
||||
console.log('[DEBUG] setShouldFocusSearchInput(false) 호출 완료!', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}, 500);
|
||||
|
||||
console.log('[DEBUG] 타이머 설정 완료 - 500ms 후 포커스 이동 예약됨', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
// Cleanup: 타이머 정리
|
||||
return () => {
|
||||
console.log('[DEBUG] shouldFocusSearchInput useEffect cleanup 실행', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
if (focusTimer) {
|
||||
if (DEBUG_MODE) {
|
||||
console.log('[FOCUS] 🧹 SearchInputOverlay 포커스 관리 useEffect cleanup - 타이머 정리', {
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
clearTimeout(focusTimer);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [shouldFocusSearchInput, DEBUG_MODE]);
|
||||
|
||||
/**
|
||||
* LOG 용도,
|
||||
* 현재 menu 위치를 설정하여, 로그를 보내는 용도
|
||||
|
||||
Reference in New Issue
Block a user