mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
feat: enhance login view with retry mechanism for server checks
- Added useRef to manage AbortController for retry requests in the LoginView component. - Implemented logic to abort any ongoing retry requests before initiating a new server check, improving error handling and user experience during login attempts.
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
* checking_setup → redirecting
|
* checking_setup → redirecting
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useReducer, useEffect } from 'react';
|
import { useReducer, useEffect, useRef } from 'react';
|
||||||
import { useNavigate } from '@tanstack/react-router';
|
import { useNavigate } from '@tanstack/react-router';
|
||||||
import { login, getHttpApiClient, getServerUrlSync } from '@/lib/http-api-client';
|
import { login, getHttpApiClient, getServerUrlSync } from '@/lib/http-api-client';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -176,12 +176,20 @@ async function checkServerAndSession(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkSetupStatus(dispatch: React.Dispatch<Action>): Promise<void> {
|
async function checkSetupStatus(
|
||||||
|
dispatch: React.Dispatch<Action>,
|
||||||
|
signal?: AbortSignal
|
||||||
|
): Promise<void> {
|
||||||
const httpClient = getHttpApiClient();
|
const httpClient = getHttpApiClient();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await httpClient.settings.getGlobal();
|
const result = await httpClient.settings.getGlobal();
|
||||||
|
|
||||||
|
// Return early if aborted
|
||||||
|
if (signal?.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success && result.settings) {
|
if (result.success && result.settings) {
|
||||||
// Check the setupComplete field from settings
|
// Check the setupComplete field from settings
|
||||||
// This is set to true when user completes the setup wizard
|
// This is set to true when user completes the setup wizard
|
||||||
@@ -199,6 +207,10 @@ async function checkSetupStatus(dispatch: React.Dispatch<Action>): Promise<void>
|
|||||||
dispatch({ type: 'REDIRECT', to: '/setup' });
|
dispatch({ type: 'REDIRECT', to: '/setup' });
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
// Return early if aborted
|
||||||
|
if (signal?.aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// If we can't get settings, go to setup to be safe
|
// If we can't get settings, go to setup to be safe
|
||||||
useSetupStore.getState().setSetupComplete(false);
|
useSetupStore.getState().setSetupComplete(false);
|
||||||
dispatch({ type: 'REDIRECT', to: '/setup' });
|
dispatch({ type: 'REDIRECT', to: '/setup' });
|
||||||
@@ -232,6 +244,7 @@ export function LoginView() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const setAuthState = useAuthStore((s) => s.setAuthState);
|
const setAuthState = useAuthStore((s) => s.setAuthState);
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
const retryControllerRef = useRef<AbortController | null>(null);
|
||||||
|
|
||||||
// Run initial server/session check on mount.
|
// Run initial server/session check on mount.
|
||||||
// IMPORTANT: Do not "run once" via a ref guard here.
|
// IMPORTANT: Do not "run once" via a ref guard here.
|
||||||
@@ -243,13 +256,19 @@ export function LoginView() {
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
|
retryControllerRef.current?.abort();
|
||||||
};
|
};
|
||||||
}, [setAuthState]);
|
}, [setAuthState]);
|
||||||
|
|
||||||
// When we enter checking_setup phase, check setup status
|
// When we enter checking_setup phase, check setup status
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.phase === 'checking_setup') {
|
if (state.phase === 'checking_setup') {
|
||||||
checkSetupStatus(dispatch);
|
const controller = new AbortController();
|
||||||
|
checkSetupStatus(dispatch, controller.signal);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
controller.abort();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}, [state.phase]);
|
}, [state.phase]);
|
||||||
|
|
||||||
@@ -271,8 +290,12 @@ export function LoginView() {
|
|||||||
|
|
||||||
// Handle retry button for server errors
|
// Handle retry button for server errors
|
||||||
const handleRetry = () => {
|
const handleRetry = () => {
|
||||||
|
// Abort any previous retry request
|
||||||
|
retryControllerRef.current?.abort();
|
||||||
|
|
||||||
dispatch({ type: 'RETRY_SERVER_CHECK' });
|
dispatch({ type: 'RETRY_SERVER_CHECK' });
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
retryControllerRef.current = controller;
|
||||||
checkServerAndSession(dispatch, setAuthState, controller.signal);
|
checkServerAndSession(dispatch, setAuthState, controller.signal);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user