[251023] fix: ShopperHouse API relativeQurues구현
🕐 커밋 시간: 2025. 10. 23. 17:39:17 📊 변경 통계: • 총 파일: 5개 • 추가: +94줄 • 삭제: -18줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/searchActions.js ~ com.twin.app.shoptime/src/reducers/searchReducer.js ~ 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/actions/searchActions.js (javascript): 🔄 Modified: setShopperHouseError() 📄 com.twin.app.shoptime/src/views/SearchPanel/VoiceInputOverlay/VoiceInputOverlay.jsx (javascript): 🔄 Modified: clearAllTimers() 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선
This commit is contained in:
@@ -15,13 +15,11 @@ export const getSearch =
|
||||
lastSearchedParams = params;
|
||||
}
|
||||
const maxResults =
|
||||
startIndex === 1
|
||||
? SEARCH_DATA_MAX_RESULTS_LIMIT * 2
|
||||
: SEARCH_DATA_MAX_RESULTS_LIMIT;
|
||||
startIndex === 1 ? SEARCH_DATA_MAX_RESULTS_LIMIT * 2 : SEARCH_DATA_MAX_RESULTS_LIMIT;
|
||||
|
||||
let currentKey = key;
|
||||
const onSuccess = (response) => {
|
||||
console.log("getSearch onSuccess: ", response.data);
|
||||
console.log('getSearch onSuccess: ', response.data);
|
||||
|
||||
if (startIndex === 1) {
|
||||
getSearchKey = new Date();
|
||||
@@ -44,13 +42,13 @@ export const getSearch =
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("getSearch onFail: ", error);
|
||||
console.error('getSearch onFail: ', error);
|
||||
};
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
"post",
|
||||
'post',
|
||||
URLS.GET_SEARCH,
|
||||
{},
|
||||
{ service, query, startIndex, maxResults, domain },
|
||||
@@ -73,13 +71,7 @@ export const continueSearch =
|
||||
//ignore search
|
||||
return;
|
||||
}
|
||||
dispatch(
|
||||
getSearch(
|
||||
{ ...lastSearchedParams, domain: key },
|
||||
startIndex,
|
||||
getSearchKey
|
||||
)
|
||||
);
|
||||
dispatch(getSearch({ ...lastSearchedParams, domain: key }, startIndex, getSearchKey));
|
||||
};
|
||||
|
||||
export const resetSearch = (status) => {
|
||||
@@ -112,27 +104,21 @@ export const getShopperHouseSearch =
|
||||
getShopperHouseSearchKey = currentSearchKey;
|
||||
|
||||
console.log(
|
||||
"[ShopperHouse] 🔍 [DEBUG] API 호출 시작 - key:",
|
||||
'[ShopperHouse] 🔍 [DEBUG] API 호출 시작 - key:',
|
||||
currentSearchKey,
|
||||
"query:",
|
||||
'query:',
|
||||
query
|
||||
);
|
||||
|
||||
const onSuccess = (response) => {
|
||||
console.log(
|
||||
"[ShopperHouse] 📥 [DEBUG] API 응답 도착 - key:",
|
||||
currentSearchKey
|
||||
);
|
||||
console.log(
|
||||
"[ShopperHouse] 🔑 [DEBUG] 현재 유효한 key:",
|
||||
getShopperHouseSearchKey
|
||||
);
|
||||
console.log('[ShopperHouse] 📥 [DEBUG] API 응답 도착 - key:', currentSearchKey);
|
||||
console.log('[ShopperHouse] 🔑 [DEBUG] 현재 유효한 key:', getShopperHouseSearchKey);
|
||||
|
||||
// ✨ 현재 요청이 최신 요청인지 확인
|
||||
if (currentSearchKey === getShopperHouseSearchKey) {
|
||||
console.log("[ShopperHouse] ✅ [DEBUG] 유효한 응답 - Redux 업데이트");
|
||||
console.log('[ShopperHouse] ✅ [DEBUG] 유효한 응답 - Redux 업데이트');
|
||||
console.log(
|
||||
"[ShopperHouse] getShopperHouseSearch onSuccess: ",
|
||||
'[ShopperHouse] getShopperHouseSearch onSuccess: ',
|
||||
JSON.stringify(response.data)
|
||||
);
|
||||
|
||||
@@ -140,9 +126,9 @@ export const getShopperHouseSearch =
|
||||
const retCode = response.data?.retCode;
|
||||
if (retCode !== 0) {
|
||||
console.error(
|
||||
"[ShopperHouse] ❌ API 실패 - retCode:",
|
||||
'[ShopperHouse] ❌ API 실패 - retCode:',
|
||||
retCode,
|
||||
"retMsg:",
|
||||
'retMsg:',
|
||||
response.data?.retMsg
|
||||
);
|
||||
console.log('[VoiceInput] 📥 API 응답 실패');
|
||||
@@ -150,7 +136,8 @@ export const getShopperHouseSearch =
|
||||
console.log('[VoiceInput] └─ retMsg:', response.data?.retMsg);
|
||||
|
||||
// ✨ API 실패 응답을 Redux 에러 상태에 저장
|
||||
dispatch(setShopperHouseError({
|
||||
dispatch(
|
||||
setShopperHouseError({
|
||||
message: `API 실패: ${response.data?.retMsg || '알 수 없는 오류'}`,
|
||||
status: 'API_ERROR',
|
||||
retCode: retCode,
|
||||
@@ -159,8 +146,9 @@ export const getShopperHouseSearch =
|
||||
endpoint: URLS.GET_SHOPPERHOUSE_SEARCH,
|
||||
query: query,
|
||||
searchId: searchId,
|
||||
response: response.data
|
||||
}));
|
||||
response: response.data,
|
||||
})
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -171,15 +159,17 @@ export const getShopperHouseSearch =
|
||||
console.log('[VoiceInput] 📥 API 응답 실패 (result 데이터 없음)');
|
||||
|
||||
// ✨ result 데이터 없음 에러를 Redux 에러 상태에 저장
|
||||
dispatch(setShopperHouseError({
|
||||
dispatch(
|
||||
setShopperHouseError({
|
||||
message: 'API 응답에 result 데이터가 없습니다',
|
||||
status: 'NO_RESULT_DATA',
|
||||
timestamp: Date.now(),
|
||||
endpoint: URLS.GET_SHOPPERHOUSE_SEARCH,
|
||||
query: query,
|
||||
searchId: searchId,
|
||||
response: response.data
|
||||
}));
|
||||
response: response.data,
|
||||
})
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -187,15 +177,13 @@ export const getShopperHouseSearch =
|
||||
// 📥 [VoiceInput] API 응답 성공 로그
|
||||
const resultData = response.data.data.result;
|
||||
const results = resultData.results || [];
|
||||
const receivedSearchId =
|
||||
results.length > 0 ? results[0].searchId : null;
|
||||
const receivedSearchId = results.length > 0 ? results[0].searchId : null;
|
||||
const relativeQueries = results.length > 0 ? results[0].relativeQueries : null;
|
||||
|
||||
console.log("[VoiceInput] 📥 API 응답 성공");
|
||||
console.log(
|
||||
"[VoiceInput] ├─ searchId:",
|
||||
receivedSearchId || "(없음)"
|
||||
);
|
||||
console.log("[VoiceInput] └─ 결과 수:", results.length);
|
||||
console.log('[VoiceInput] 📥 API 응답 성공');
|
||||
console.log('[VoiceInput] ├─ searchId:', receivedSearchId || '(없음)');
|
||||
console.log('[VoiceInput] ├─ 결과 수:', results.length);
|
||||
console.log('[VoiceInput] └─ relativeQueries:', relativeQueries || '(없음)');
|
||||
|
||||
dispatch({
|
||||
type: types.GET_SHOPPERHOUSE_SEARCH,
|
||||
@@ -204,18 +192,12 @@ export const getShopperHouseSearch =
|
||||
|
||||
dispatch(updateSearchTimestamp());
|
||||
} else {
|
||||
console.log(
|
||||
"[ShopperHouse] ❌ [DEBUG] 오래된 응답 무시 - Redux 업데이트 안함"
|
||||
);
|
||||
console.log('[ShopperHouse] ❌ [DEBUG] 오래된 응답 무시 - Redux 업데이트 안함');
|
||||
}
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error(
|
||||
"[ShopperHouse] getShopperHouseSearch onFail: ",
|
||||
JSON.stringify(error)
|
||||
);
|
||||
|
||||
console.error('[ShopperHouse] getShopperHouseSearch onFail: ', JSON.stringify(error));
|
||||
|
||||
// ✨ 현재 요청이 최신 요청인지 확인
|
||||
if (currentSearchKey === getShopperHouseSearchKey) {
|
||||
@@ -241,7 +223,11 @@ export const getShopperHouseSearch =
|
||||
}
|
||||
|
||||
// ✅ 네트워크 연결 관련 오류 중 일시적인 오류 필터링
|
||||
if (status === 0 || errorMessage?.includes('Network Error') || errorMessage?.includes('timeout')) {
|
||||
if (
|
||||
status === 0 ||
|
||||
errorMessage?.includes('Network Error') ||
|
||||
errorMessage?.includes('timeout')
|
||||
) {
|
||||
console.log('[VoiceInput] ⚠️ 일시적인 네트워크 오류 - 재시도 필요');
|
||||
console.log('[VoiceInput] └─ TAxios 큐에 의해 자동 재시도될 수 있습니다');
|
||||
// 일시적인 네트워크 오류는 Redux에 저장하지 않음
|
||||
@@ -254,7 +240,8 @@ export const getShopperHouseSearch =
|
||||
console.log('[VoiceInput] ├─ status:', status);
|
||||
console.log('[VoiceInput] └─ error:', errorMessage || JSON.stringify(error));
|
||||
|
||||
dispatch(setShopperHouseError({
|
||||
dispatch(
|
||||
setShopperHouseError({
|
||||
message: errorMessage || 'Unknown API error',
|
||||
status: status,
|
||||
statusText: error?.statusText,
|
||||
@@ -264,8 +251,9 @@ export const getShopperHouseSearch =
|
||||
endpoint: URLS.GET_SHOPPERHOUSE_SEARCH,
|
||||
query: query,
|
||||
searchId: searchId,
|
||||
originalError: error
|
||||
}));
|
||||
originalError: error,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
console.log('[ShopperHouse] ❌ [DEBUG] 오래된 에러 응답 무시 - Redux 업데이트 안함');
|
||||
}
|
||||
@@ -275,21 +263,9 @@ export const getShopperHouseSearch =
|
||||
if (searchId) {
|
||||
params.searchid = searchId;
|
||||
}
|
||||
console.log(
|
||||
"[ShopperHouse] getShopperHouseSearch params: ",
|
||||
JSON.stringify(params)
|
||||
);
|
||||
console.log('[ShopperHouse] getShopperHouseSearch params: ', JSON.stringify(params));
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
"post",
|
||||
URLS.GET_SHOPPERHOUSE_SEARCH,
|
||||
{},
|
||||
params,
|
||||
onSuccess,
|
||||
onFail
|
||||
);
|
||||
TAxios(dispatch, getState, 'post', URLS.GET_SHOPPERHOUSE_SEARCH, {}, params, onSuccess, onFail);
|
||||
};
|
||||
|
||||
// ShopperHouse API 에러 처리 액션
|
||||
@@ -306,9 +282,7 @@ export const setShopperHouseError = (error) => {
|
||||
// ShopperHouse 검색 데이터 초기화
|
||||
export const clearShopperHouseData = () => {
|
||||
// ✨ 검색 키 초기화 - 진행 중인 요청의 응답을 무시하도록
|
||||
console.log(
|
||||
"[ShopperHouse] 🧹 [DEBUG] clearShopperHouseData - 이전 요청 무효화"
|
||||
);
|
||||
console.log('[ShopperHouse] 🧹 [DEBUG] clearShopperHouseData - 이전 요청 무효화');
|
||||
getShopperHouseSearchKey = null;
|
||||
|
||||
return {
|
||||
@@ -320,7 +294,7 @@ export const clearShopperHouseData = () => {
|
||||
// Search Main 조회 IF-LGSP-097
|
||||
export const getSearchMain = () => (dispatch, getState) => {
|
||||
const onSuccess = (response) => {
|
||||
console.log("getSearchMain onSuccess: ", response.data);
|
||||
console.log('getSearchMain onSuccess: ', response.data);
|
||||
|
||||
dispatch({
|
||||
type: types.GET_SEARCH_MAIN,
|
||||
@@ -329,19 +303,10 @@ export const getSearchMain = () => (dispatch, getState) => {
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error("getSearchMain onFail: ", error);
|
||||
console.error('getSearchMain onFail: ', error);
|
||||
};
|
||||
|
||||
TAxios(
|
||||
dispatch,
|
||||
getState,
|
||||
"post",
|
||||
URLS.GET_SEARCH_MAIN,
|
||||
{},
|
||||
{},
|
||||
onSuccess,
|
||||
onFail
|
||||
);
|
||||
TAxios(dispatch, getState, 'post', URLS.GET_SEARCH_MAIN, {}, {}, onSuccess, onFail);
|
||||
};
|
||||
|
||||
// 검색 메인 데이터 초기화
|
||||
|
||||
@@ -8,6 +8,7 @@ const initialState = {
|
||||
searchTimestamp: null,
|
||||
shopperHouseData: null,
|
||||
shopperHouseSearchId: null,
|
||||
shopperHouseRelativeQueries: null, // ✨ relativeQueries는 독립적으로 저장 (searchId와 별개)
|
||||
|
||||
// 🔽 검색 메인 데이터 추가
|
||||
searchMainData: {
|
||||
@@ -62,10 +63,25 @@ export const searchReducer = (state = initialState, action) => {
|
||||
};
|
||||
|
||||
case types.RESET_VOICE_SEARCH:
|
||||
console.log('[VoiceInput]-searchReducer-RESET_VOICE_SEARCH');
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
action: 'RESET_VOICE_SEARCH',
|
||||
shopperHouseData_cleared: true,
|
||||
shopperHouseSearchId_cleared: true,
|
||||
shopperHouseRelativeQueries_preserved: state.shopperHouseRelativeQueries || '(없음)',
|
||||
relativeQueries_length: state.shopperHouseRelativeQueries?.length || 0,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
return {
|
||||
...state,
|
||||
shopperHouseData: null,
|
||||
shopperHouseSearchId: null,
|
||||
// ✨ relativeQueries는 유지 (다음 PROMPT 모드에서 표시하기 위해)
|
||||
};
|
||||
|
||||
case types.SET_SEARCH_INIT_PERFORMED:
|
||||
@@ -91,17 +107,36 @@ export const searchReducer = (state = initialState, action) => {
|
||||
|
||||
const results = resultData.results || [];
|
||||
|
||||
// searchId 추출 (첫 번째 result에서)
|
||||
// searchId와 relativeQueries 추출 (첫 번째 result에서)
|
||||
const searchId = results.length > 0 ? results[0].searchId : null;
|
||||
const relativeQueries = results.length > 0 ? results[0].relativeQueries : null;
|
||||
|
||||
// [VoiceInput] Redux에 searchId 저장 로그
|
||||
console.log('[VoiceInput] 💾 Redux에 searchId 저장');
|
||||
console.log('[VoiceInput] └─ searchId:', searchId || '(없음)');
|
||||
// [VoiceInput] Redux에 저장 로그
|
||||
console.log('[VoiceInput] 💾 Redux에 저장');
|
||||
console.log('[VoiceInput] ├─ searchId:', searchId || '(없음)');
|
||||
console.log('[VoiceInput] ├─ relativeQueries:', relativeQueries || '(없음)');
|
||||
console.log('[VoiceInput]-searchReducer-GET_SHOPPERHOUSE_SEARCH');
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
searchId: searchId,
|
||||
relativeQueries: relativeQueries,
|
||||
relativeQueries_type: typeof relativeQueries,
|
||||
relativeQueries_isArray: Array.isArray(relativeQueries),
|
||||
relativeQueries_length: relativeQueries?.length || 0,
|
||||
results_length: results.length,
|
||||
firstResult_keys: results.length > 0 ? Object.keys(results[0]) : [],
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
...state,
|
||||
shopperHouseData: resultData,
|
||||
shopperHouseSearchId: searchId,
|
||||
shopperHouseRelativeQueries: relativeQueries, // ✨ relativeQueries 별도 저장
|
||||
// ShopperHouse 검색 시 일반 검색 데이터 초기화
|
||||
searchDatas: {},
|
||||
totalCount: {},
|
||||
@@ -120,12 +155,29 @@ export const searchReducer = (state = initialState, action) => {
|
||||
};
|
||||
|
||||
case types.CLEAR_SHOPPERHOUSE_DATA:
|
||||
console.log('[VoiceInput] 🧹 Redux shopperHouseData 초기화 (searchId는 유지)');
|
||||
console.log(
|
||||
'[VoiceInput] 🧹 Redux shopperHouseData 초기화 (searchId & relativeQueries는 유지)'
|
||||
);
|
||||
console.log('[VoiceInput]-searchReducer-CLEAR_SHOPPERHOUSE_DATA');
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
shopperHouseData_cleared: true,
|
||||
shopperHouseSearchId_preserved: state.shopperHouseSearchId || '(없음)',
|
||||
shopperHouseRelativeQueries_preserved: state.shopperHouseRelativeQueries || '(없음)',
|
||||
relativeQueries_length: state.shopperHouseRelativeQueries?.length || 0,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
return {
|
||||
...state,
|
||||
shopperHouseData: null,
|
||||
// ✅ searchId는 2번째 발화에서 필요하므로 유지!
|
||||
// shopperHouseSearchId: null, // ❌ 제거됨 - searchId를 유지해야 2차 발화에서 searchId 포함 가능
|
||||
// ✨ relativeQueries도 PROMPT 모드에서 표시하기 위해 유지!
|
||||
// shopperHouseRelativeQueries는 유지
|
||||
shopperHouseError: null, // 데이터 초기화 시 오류도 초기화
|
||||
};
|
||||
|
||||
|
||||
@@ -353,7 +353,9 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
|
||||
console.log(
|
||||
'[DEBUG]-VOICE_RESULT: Clearing ShopperHouse data (searchId will be preserved for 2nd search)'
|
||||
);
|
||||
dispatch(clearShopperHouseData()); // ✨ shopperHouseData만 초기화, searchId 유지
|
||||
console.log('[VoiceInput]-SearchPanel-onCancel-VOICE_RESULT');
|
||||
console.log('[VoiceInput] 🧹 VOICE_RESULT 모드에서 ESC 누름 - clearShopperHouseData 호출');
|
||||
dispatch(clearShopperHouseData()); // ✨ shopperHouseData만 초기화, searchId & relativeQuerys 유지
|
||||
Spotlight.focus(SPOTLIGHT_IDS.SEARCH_INPUT_BOX);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -226,10 +226,12 @@ const SearchResultsNew = ({ itemInfo, showInfo, themeInfo, shopperHouseInfo, key
|
||||
[themeInfo]
|
||||
);
|
||||
|
||||
// relativeQuerys 가져오기 (ShopperHouse API 응답)
|
||||
const relativeQuerys = useMemo(() => {
|
||||
if (shopperHouseInfo?.results?.[0]?.relativeQuerys) {
|
||||
return shopperHouseInfo.results[0].relativeQuerys;
|
||||
// relativeQueries 가져오기 (Redux에서 제공)
|
||||
// Redux의 shopperHouseRelativeQueries를 사용하여 데이터 유지
|
||||
const relativeQueries = useMemo(() => {
|
||||
if (shopperHouseInfo?.results?.[0]?.relativeQueries) {
|
||||
// Redux에서 받은 relativeQueries 사용
|
||||
return shopperHouseInfo.results[0].relativeQueries;
|
||||
}
|
||||
// 기본값
|
||||
return ['Puppy food', 'Dog toy', 'Fitness'];
|
||||
@@ -239,7 +241,7 @@ const SearchResultsNew = ({ itemInfo, showInfo, themeInfo, shopperHouseInfo, key
|
||||
<div className={css.searchBox}>
|
||||
{/* HowAboutThese Small 버전 - 기본 인라인 표시 */}
|
||||
<HowAboutTheseSmall
|
||||
relativeQueries={relativeQuerys}
|
||||
relativeQueries={relativeQueries}
|
||||
onQueryClick={handleSmallQueryClick}
|
||||
onSeeMoreClick={handleShowFullHowAboutThese}
|
||||
/>
|
||||
@@ -248,7 +250,7 @@ const SearchResultsNew = ({ itemInfo, showInfo, themeInfo, shopperHouseInfo, key
|
||||
{howAboutTheseMode === HOW_ABOUT_THESE_MODES.FULL && (
|
||||
<div className={css.howAboutTheseOverlay}>
|
||||
<HowAboutThese
|
||||
relativeQueries={relativeQuerys}
|
||||
relativeQueries={relativeQueries}
|
||||
onQueryClick={handleFullQueryClick}
|
||||
onClose={handleCloseHowAboutThese}
|
||||
/>
|
||||
|
||||
@@ -314,6 +314,9 @@ const VoiceInputOverlay = ({
|
||||
// Redux에서 shopperHouse 검색 결과 및 에러 가져오기 (simplified ref usage)
|
||||
const shopperHouseData = useSelector((state) => state.search.shopperHouseData);
|
||||
const shopperHouseSearchId = useSelector((state) => state.search.shopperHouseSearchId); // 2차 발화용 searchId
|
||||
const shopperHouseRelativeQueries = useSelector(
|
||||
(state) => state.search.shopperHouseRelativeQueries
|
||||
); // ✨ 관련 검색어
|
||||
const shopperHouseError = useSelector((state) => state.search.shopperHouseError); // API 에러 정보
|
||||
const shopperHouseDataRef = useRef(null);
|
||||
const isInitializingRef = useRef(false); // overlay 초기화 중 플래그
|
||||
@@ -1218,20 +1221,62 @@ const VoiceInputOverlay = ({
|
||||
}
|
||||
|
||||
switch (currentMode) {
|
||||
case VOICE_MODES.PROMPT:
|
||||
case VOICE_MODES.PROMPT: {
|
||||
// ✨ relativeQueries가 있으면 'How about these ?' 표시, 없으면 'Try saying' 표시
|
||||
const hasRelativeQueries = !!shopperHouseRelativeQueries;
|
||||
const promptTitle = hasRelativeQueries ? 'How about these ?' : 'Try saying';
|
||||
// relativeQueries가 있으면 사용, 없으면 searchHistory 사용
|
||||
const promptSuggestions = hasRelativeQueries ? shopperHouseRelativeQueries : searchHistory;
|
||||
|
||||
// ✨ [DEBUG] Redux 상태 확인 로그
|
||||
console.log('[VoiceInput]-shopperHouseRelativeQueries');
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
hasRelativeQueries: hasRelativeQueries,
|
||||
relativeQueries: shopperHouseRelativeQueries,
|
||||
relativeQueries_type: typeof shopperHouseRelativeQueries,
|
||||
relativeQueries_isArray: Array.isArray(shopperHouseRelativeQueries),
|
||||
relativeQueries_length: shopperHouseRelativeQueries?.length || 0,
|
||||
promptTitle: promptTitle,
|
||||
promptSuggestions: promptSuggestions,
|
||||
promptSuggestions_length: promptSuggestions?.length || 0,
|
||||
searchHistory_length: searchHistory?.length || 0,
|
||||
shopperHouseSearchId: shopperHouseSearchId || '(없음)',
|
||||
shopperHouseData_exists: !!shopperHouseData,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
'✅ [DEBUG][VoiceInputOverlay] MODE = PROMPT | Rendering VoicePromptScreen with',
|
||||
searchHistory.length,
|
||||
'✅ [DEBUG][VoiceInputOverlay] MODE = PROMPT | Rendering VoicePromptScreen',
|
||||
hasRelativeQueries ? '(with relativeQueries)' : '(with searchHistory)',
|
||||
promptSuggestions.length,
|
||||
'suggestions'
|
||||
);
|
||||
if (hasRelativeQueries) {
|
||||
console.log(
|
||||
'[DEBUG][VoiceInputOverlay] ├─ searchId:',
|
||||
shopperHouseSearchId || '(없음)'
|
||||
);
|
||||
console.log('[DEBUG][VoiceInputOverlay] ├─ relativeQueries:', promptSuggestions);
|
||||
console.log('[DEBUG][VoiceInputOverlay] └─ promptTitle:', promptTitle);
|
||||
} else {
|
||||
console.log('[DEBUG][VoiceInputOverlay] ├─ relativeQueries가 없음');
|
||||
console.log('[DEBUG][VoiceInputOverlay] └─ searchHistory 사용:', promptSuggestions);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<VoicePromptScreen
|
||||
suggestions={searchHistory}
|
||||
title={promptTitle}
|
||||
suggestions={promptSuggestions}
|
||||
onSuggestionClick={handleSuggestionClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case VOICE_MODES.LISTENING:
|
||||
if (DEBUG_MODE) {
|
||||
console.log(
|
||||
@@ -1318,6 +1363,7 @@ const VoiceInputOverlay = ({
|
||||
restartWebSpeech,
|
||||
shopperHouseError,
|
||||
shopperHouseSearchId,
|
||||
shopperHouseRelativeQueries, // ✨ relativeQueries 변경 감지
|
||||
handleApiErrorRetry,
|
||||
handleApiErrorRestart,
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user