[251024] [251025] feat: SearchPanel.new.v2 HowAboutThese 검색 대기화면

🕐 커밋 시간: 2025. 10. 24. 20:45:45

📊 변경 통계:
  • 총 파일: 3개
  • 추가: +67줄
  • 삭제: -1줄

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

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx (javascript):
     Added: clearAllTimers()
This commit is contained in:
2025-10-24 20:45:45 +00:00
parent 8fe080f343
commit 587acbd2ee
3 changed files with 79 additions and 45 deletions

View File

@@ -20,6 +20,7 @@ import {
resetSearch,
resetVoiceSearch,
clearShopperHouseData,
getShopperHouseSearch,
} from '../../actions/searchActions';
// import {
// showErrorToast,
@@ -179,6 +180,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
// ✨ [Phase 1] SearchPanel의 현재 모드 상태 (VoiceInputOverlay의 VOICE_MODES와 동일한 개념)
const [currentMode, setCurrentMode] = useState(SEARCH_PANEL_MODES.INITIAL);
const [voiceOverlayMode, setVoiceOverlayMode] = useState(VOICE_MODES.PROMPT);
const [voiceOverlayResponseText, setVoiceOverlayResponseText] = useState('');
const [isVoiceOverlayBubbleSearch, setIsVoiceOverlayBubbleSearch] = useState(false);
// 🐛 [DEBUG] shopperHouseData 상태 변경 추적 (DEBUG_MODE가 true일 경우에만)
useEffect(() => {
@@ -438,6 +442,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
isVoiceOverlayVisible
);
}
setVoiceOverlayMode(VOICE_MODES.PROMPT);
setVoiceOverlayResponseText('');
setIsVoiceOverlayBubbleSearch(false);
setIsVoiceOverlayVisible(true);
// setIsVoiceOverlayVisible((prev) => !prev);
}, [isVoiceOverlayVisible]);
@@ -646,6 +653,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
// VoiceInputOverlay가 닫히는 순간 clearShopperHouseData()를 호출하면,
// SearchPanel에서 shopperHouseData를 표시할 수 없으므로 여기서는 정리하지 않음
setVoiceOverlayMode(VOICE_MODES.PROMPT);
setVoiceOverlayResponseText('');
setIsVoiceOverlayBubbleSearch(false);
setIsVoiceOverlayVisible(false);
// ✅ VoiceOverlay가 닫힐 때 항상 TInput으로 포커스 이동
setTimeout(() => {
@@ -653,6 +663,27 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
}, 150); // Overlay 닫히는 시간을 고려한 지연
}, []);
const handleHowAboutTheseQueryClick = useCallback(
(rawQuery) => {
if (!rawQuery) return;
const trimmedQuery = typeof rawQuery === 'string' ? rawQuery.trim() : '';
if (!trimmedQuery) return;
// 검색 입력 필드에도 동일한 쿼리를 표시
setSearchQuery(trimmedQuery);
// Voice overlay를 RESPONSE 모드로 전환하여 대기 화면 표시
setVoiceOverlayResponseText(trimmedQuery);
setVoiceOverlayMode(VOICE_MODES.RESPONSE);
setIsVoiceOverlayBubbleSearch(true);
setIsVoiceOverlayVisible(true);
dispatch(getShopperHouseSearch(trimmedQuery, shopperHouseSearchId));
},
[dispatch, shopperHouseSearchId]
);
// ✨ [Phase 3] handleInputIconClick 제거 (돋보기 아이콘 기능 비활성화)
// /**
// * ✨ [Phase 3] TInput icon click handler (showVirtualKeyboard 제거)
@@ -770,6 +801,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
shopperHouseRelativeQueries={shopperHouseRelativeQueries}
keywordClick={handleKeywordClick}
panelInfo={panelInfo}
onRelativeQueryClick={handleHowAboutTheseQueryClick}
/>
);
@@ -1331,12 +1363,14 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
<VoiceInputOverlay
isVisible={isVoiceOverlayVisible}
onClose={handleVoiceOverlayClose}
mode={VOICE_MODES.PROMPT}
mode={voiceOverlayMode}
suggestions={voiceSuggestions}
searchQuery={searchQuery}
onSearchChange={handleSearchChange}
onSearchSubmit={handleSearchSubmit}
isVoiceResultMode={currentMode === SEARCH_PANEL_MODES.VOICE_RESULT}
externalResponseText={voiceOverlayResponseText}
isExternalBubbleSearch={isVoiceOverlayBubbleSearch}
/>
{/* ✨ [Phase 1] Search Input Overlay - currentMode로 visibility 제어 */}