[251024] [251025] feat: Voice검색 후 포커스 문제

🕐 커밋 시간: 2025. 10. 24. 21:16:53

📊 변경 통계:
  • 총 파일: 2개
  • 추가: +76줄
  • 삭제: -21줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/views/SearchPanel/SearchPanel.new.v2.jsx
  ~ com.twin.app.shoptime/src/views/SearchPanel/SearchResults.new.v2.jsx

🔧 주요 변경 내용:
  • 소규모 기능 개선
This commit is contained in:
2025-10-24 21:16:53 +00:00
parent 587acbd2ee
commit 2838e4b8ec
2 changed files with 76 additions and 21 deletions

View File

@@ -183,6 +183,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
const [voiceOverlayMode, setVoiceOverlayMode] = useState(VOICE_MODES.PROMPT);
const [voiceOverlayResponseText, setVoiceOverlayResponseText] = useState('');
const [isVoiceOverlayBubbleSearch, setIsVoiceOverlayBubbleSearch] = useState(false);
const [shouldFocusVoiceResult, setShouldFocusVoiceResult] = useState(false);
// 🐛 [DEBUG] shopperHouseData 상태 변경 추적 (DEBUG_MODE가 true일 경우에만)
useEffect(() => {
@@ -657,11 +658,15 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
setVoiceOverlayResponseText('');
setIsVoiceOverlayBubbleSearch(false);
setIsVoiceOverlayVisible(false);
// ✅ VoiceOverlay가 닫힐 때 항상 TInput으로 포커스 이동
setTimeout(() => {
Spotlight.focus(SPOTLIGHT_IDS.SEARCH_INPUT_BOX);
}, 150); // Overlay 닫히는 시간을 고려한 지연
}, []);
setShouldFocusVoiceResult(false);
// ShopperHouse 데이터가 없을 때만 검색 인풋으로 포커스 복원
if (!shopperHouseData) {
setTimeout(() => {
Spotlight.focus(SPOTLIGHT_IDS.SEARCH_INPUT_BOX);
}, 150); // Overlay 닫히는 시간을 고려한 지연
}
}, [shopperHouseData]);
const handleHowAboutTheseQueryClick = useCallback(
(rawQuery) => {
@@ -678,6 +683,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
setVoiceOverlayMode(VOICE_MODES.RESPONSE);
setIsVoiceOverlayBubbleSearch(true);
setIsVoiceOverlayVisible(true);
setShouldFocusVoiceResult(false);
dispatch(getShopperHouseSearch(trimmedQuery, shopperHouseSearchId));
},
@@ -1161,7 +1167,47 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
clearTimeout(focusTimer);
};
}
}, [shopperHouseData, isOnTop, currentMode]);
}, [shopperHouseData, isOnTop, currentMode, DEBUG_MODE]);
useEffect(() => {
if (
isOnTop &&
currentMode === SEARCH_PANEL_MODES.VOICE_RESULT &&
shopperHouseData?.results?.[0]?.docs?.length > 0 &&
!isVoiceOverlayVisible
) {
if (DEBUG_MODE) {
console.log('[DEBUG] 🎯 ShopperHouse 데이터 감지 - 상품 포커스 예약');
}
setShouldFocusVoiceResult(true);
}
}, [isOnTop, currentMode, shopperHouseData, isVoiceOverlayVisible, DEBUG_MODE]);
useEffect(() => {
if (!shouldFocusVoiceResult) {
return;
}
const focusTimer = setTimeout(() => {
const targetId = 'searchItemContents0';
const targetElement = document.querySelector(`[data-spotlight-id="${targetId}"]`);
if (targetElement) {
Spotlight.focus(targetId);
if (DEBUG_MODE) {
console.log('[DEBUG] 🎯 ShopperHouse 첫 상품으로 포커스 이동:', targetId);
}
} else if (DEBUG_MODE) {
console.log('[DEBUG] ⚠️ ShopperHouse 첫 상품을 찾지 못했습니다');
}
setShouldFocusVoiceResult(false);
}, 200);
return () => {
clearTimeout(focusTimer);
};
}, [shouldFocusVoiceResult, DEBUG_MODE]);
/**
* LOG 용도,