HomePilot / frontend /src /ui /avatar /useGenerateAvatars.js
HomePilot Deploy Bot
chore(hf): sync HomePilot to HF Space
921d377
Raw
History Blame Contribute Delete
2.45 kB
/**
* Hook: manage avatar generation state (loading, results, errors).
*
* Includes a 5-minute AbortController timeout so the frontend never
* hangs indefinitely waiting for the backend.
*/
import { useState, useCallback, useRef } from 'react';
import { generateAvatars } from './avatarApi';
/** Frontend-side timeout for a single generation request (5 min). */
const GENERATE_TIMEOUT_MS = 5 * 60 * 1000;
export function useGenerateAvatars(backendUrl, apiKey) {
const [loading, setLoading] = useState(false);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const abortRef = useRef(null);
const run = useCallback(async (req) => {
// Abort any in-flight request
abortRef.current?.abort();
const controller = new AbortController();
abortRef.current = controller;
const timer = setTimeout(() => controller.abort(), GENERATE_TIMEOUT_MS);
setLoading(true);
setError(null);
try {
const r = await generateAvatars(backendUrl, req, apiKey, controller.signal);
setResult(r);
return r;
}
catch (e) {
if (e?.name === 'AbortError') {
const msg = 'Generation timed out. Try reducing the count or switching models.';
setError(msg);
throw new Error(msg);
}
setError(e?.message || String(e));
throw e;
}
finally {
clearTimeout(timer);
setLoading(false);
if (abortRef.current === controller) {
abortRef.current = null;
}
}
}, [backendUrl, apiKey]);
const cancel = useCallback(() => {
abortRef.current?.abort();
abortRef.current = null;
setLoading(false);
}, []);
const reset = useCallback(() => {
setResult(null);
setError(null);
}, []);
/** Remove a single result by index (e.g. delete a face the user doesn't like). */
const removeResult = useCallback((index) => {
setResult((prev) => {
if (!prev?.results)
return prev;
const next = prev.results.filter((_, i) => i !== index);
if (next.length === 0)
return null;
return { ...prev, results: next };
});
}, []);
return { loading, result, error, run, reset, cancel, removeResult };
}