auto-sync: 2026-05-17 06:14:58

This commit is contained in:
cfdaily
2026-05-17 06:14:58 +08:00
parent 7d6af07adb
commit 1036d74676
+84
View File
@@ -0,0 +1,84 @@
// 自定义 hooks
import { useState, useEffect, useCallback, useRef } from 'react';
import * as api from '../api';
import type { Task, Project, DaemonStatus } from '../types';
export function useProjects() {
const [projects, setProjects] = useState<Project[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const refresh = useCallback(async () => {
try {
setLoading(true);
const data = await api.listProjects();
setProjects(data);
setError(null);
} catch (e) {
setError(String(e));
} finally {
setLoading(false);
}
}, []);
useEffect(() => { refresh(); }, [refresh]);
return { projects, loading, error, refresh };
}
export function useTasks(projectId: string | null) {
const [tasks, setTasks] = useState<Task[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const refresh = useCallback(async () => {
if (!projectId) return;
try {
setLoading(true);
const data = await api.listTasks(projectId);
setTasks(data);
setError(null);
} catch (e) {
setError(String(e));
} finally {
setLoading(false);
}
}, [projectId]);
useEffect(() => { refresh(); }, [refresh]);
return { tasks, loading, error, refresh };
}
export function useDaemonStatus() {
const [status, setStatus] = useState<DaemonStatus | null>(null);
const refresh = useCallback(async () => {
try {
const data = await api.getDaemonStatus();
setStatus(data);
} catch {
// Daemon may not be running
}
}, []);
useEffect(() => {
refresh();
const interval = setInterval(refresh, 10000);
return () => clearInterval(interval);
}, [refresh]);
return { status, refresh };
}
export function useSSE(onEvent: (data: unknown) => void) {
const esRef = useRef<EventSource | null>(null);
useEffect(() => {
esRef.current = api.createEventSource(onEvent, () => {
// Auto-reconnect is handled by EventSource
});
return () => {
esRef.current?.close();
};
}, [onEvent]);
}