| import { useCallback, useState } from "react"; |
| import { API_BASE } from "../api/client"; |
|
|
| interface JobStatus { |
| status: "processing" | "done" | "failed" | "timeout"; |
| progress?: number; |
| stage?: string; |
| eta_seconds?: number; |
| filename?: string; |
| mask_count?: number; |
| message?: string; |
| } |
|
|
| async function pollJob( |
| jobId: string, |
| onProgress: (progress: number, message: string) => void, |
| intervalMs = 2000, |
| ): Promise<{ filename: string; mask_count: number }> { |
| while (true) { |
| const res = await fetch(`${API_BASE}/seg/jobs/${jobId}`); |
| if (!res.ok) throw new Error(`Error al consultar el job: ${res.status}`); |
| const job: JobStatus = await res.json(); |
|
|
| if (job.status === "done" && job.filename && job.mask_count != null) { |
| return { filename: job.filename, mask_count: job.mask_count }; |
| } |
| if (job.status === "failed" || job.status === "timeout") { |
| throw new Error(job.message ?? "La segmentaci贸n fall贸"); |
| } |
|
|
| onProgress(job.progress ?? 0, job.message ?? "Procesando..."); |
| await new Promise((r) => setTimeout(r, intervalMs)); |
| } |
| } |
|
|
| export function useSegmentUpload() { |
| const [isUploading, setIsUploading] = useState(false); |
| const [error, setError] = useState<string | null>(null); |
|
|
| const uploadAndSegment = useCallback( |
| async ( |
| file: File, |
| onProgress: (progress: number, message: string) => void, |
| ): Promise<{ filename: string; maskCount: number }> => { |
| setIsUploading(true); |
| setError(null); |
|
|
| try { |
| const form = new FormData(); |
| form.append("file", file); |
|
|
| onProgress(2, "Subiendo imagen..."); |
| const res = await fetch(`${API_BASE}/seg/upload_async`, { |
| method: "POST", |
| body: form, |
| }); |
|
|
| if (!res.ok) { |
| const text = await res.text(); |
| throw new Error(text || `Error al subir imagen: ${res.status}`); |
| } |
|
|
| const { job_id } = await res.json(); |
| onProgress(10, "Imagen recibida. Iniciando segmentaci贸n..."); |
|
|
| const result = await pollJob(job_id, onProgress); |
| return { filename: result.filename, maskCount: result.mask_count }; |
| } catch (err) { |
| const message = |
| err instanceof Error ? err.message : "Error en la segmentaci贸n"; |
| setError(message); |
| throw new Error(message); |
| } finally { |
| setIsUploading(false); |
| } |
| }, |
| [], |
| ); |
|
|
| return { uploadAndSegment, isUploading, error }; |
| } |
|
|