diff --git a/frontend/components/FoodSearchPlaceholder.tsx b/frontend/components/FoodSearchPlaceholder.tsx index e1fe0ba..667364c 100644 --- a/frontend/components/FoodSearchPlaceholder.tsx +++ b/frontend/components/FoodSearchPlaceholder.tsx @@ -206,7 +206,7 @@ export function FoodSearchPlaceholder() { const [isClearingAll, setIsClearingAll] = useState(false); const [selectedLogId, setSelectedLogId] = useState(null); const [error, setError] = useState(null); - const [logError, setLogError] = useState(null); + const [logError, setLogError] = useState(SIGN_IN_REQUIRED_LOG_MESSAGE); const [didSearch, setDidSearch] = useState(false); const [searchStatus, setSearchStatus] = useState(null); @@ -303,6 +303,7 @@ export function FoodSearchPlaceholder() { const requestId = ++logsRequestIdRef.current; setIsLogsLoading(true); + setLogError(null); try { const response = await backendRequest(`${BACKEND_BASE_URL}/logs`); if (requestId !== logsRequestIdRef.current) { @@ -337,10 +338,6 @@ export function FoodSearchPlaceholder() { } }, [clearPrivateLogState]); - useEffect(() => { - fetchLogs(); - }, [fetchLogs]); - useEffect(() => { return () => { searchAbortControllerRef.current?.abort(); diff --git a/frontend/components/XamanLoginPanel.tsx b/frontend/components/XamanLoginPanel.tsx index 24705e5..0289a25 100644 --- a/frontend/components/XamanLoginPanel.tsx +++ b/frontend/components/XamanLoginPanel.tsx @@ -350,10 +350,11 @@ export function XamanLoginPanel() { const embeddedRequestId = useRef(""); const embeddedLoginStart = useRef(null); - const refreshCurrentUser = useCallback(async (): Promise => { + const refreshCurrentUser = useCallback(async (signal?: AbortSignal): Promise => { try { const response = await backendRequest( - `${BACKEND_BASE_URL}/api/identity/me` + `${BACKEND_BASE_URL}/api/identity/me`, + { signal } ); if (!response.ok) { setCurrentUser(null); @@ -364,8 +365,12 @@ export function XamanLoginPanel() { } const data = (await response.json()) as MeResponse; setCurrentUser(data); + announceAuthState(true); return data; } catch { + if (signal?.aborted) { + return null; + } setCurrentUser(null); return null; } @@ -377,7 +382,7 @@ export function XamanLoginPanel() { loginAbortController.current = controller; async function restoreLogin() { - const user = await refreshCurrentUser(); + const user = await refreshCurrentUser(controller.signal); if (cancelled || controller.signal.aborted) { return; } @@ -411,15 +416,13 @@ export function XamanLoginPanel() { ); clearPendingLogin(); - const restoredUser = await refreshCurrentUser(); + const restoredUser = await refreshCurrentUser(controller.signal); if (!restoredUser) { throw new Error("Restored session was unavailable"); } if (cancelled) { return; } - - announceAuthState(true); setSuccessNotice( "Sign-in completed. Your session was restored in this browser." ); @@ -448,6 +451,7 @@ export function XamanLoginPanel() { }, [refreshCurrentUser]); useEffect(() => { + const bridgeController = new AbortController(); let origin = trustedParentOrigin(); parentOrigin.current = origin; setIsEmbedded(origin !== null); @@ -546,13 +550,12 @@ export function XamanLoginPanel() { throw new Error(`Callback failed with ${response.status}`); } - const restoredUser = await refreshCurrentUser(); + const restoredUser = await refreshCurrentUser(bridgeController.signal); if (!restoredUser) { throw new Error("CalorieApp session was unavailable"); } embeddedLoginStart.current = null; - announceAuthState(true); setError(null); setLoginStatus(null); setIsLoading(false); @@ -588,6 +591,7 @@ export function XamanLoginPanel() { window.addEventListener("message", handleParentMessage); window.parent.postMessage({ type: "calorieapp:bridge:ready" }, "*"); return () => { + bridgeController.abort(); resizeObserver?.disconnect(); window.removeEventListener("message", handleParentMessage); }; @@ -743,12 +747,10 @@ export function XamanLoginPanel() { ); clearPendingLogin(); - const restoredUser = await refreshCurrentUser(); + const restoredUser = await refreshCurrentUser(controller.signal); if (!restoredUser) { throw new Error("Restored session was unavailable"); } - - announceAuthState(true); setSuccessNotice( "Sign-in completed. This original CalorieApp tab is signed in too." );