diff --git a/src/components/ConfigModal.tsx b/src/components/ConfigModal.tsx index 7033309..6043bf8 100644 --- a/src/components/ConfigModal.tsx +++ b/src/components/ConfigModal.tsx @@ -13,7 +13,6 @@ import { App, } from "antd"; import { PlusOutlined, DeleteOutlined } from "@ant-design/icons"; -import { useDebouncedCallback } from "use-debounce"; import { createConfig, updateConfig } from "@/services/config"; import { getModrinthLoaders, @@ -25,6 +24,8 @@ import { readProjectVersion, checkArtifactFiles, checkSourceFiles, + lookupModrinthProject, + lookupCurseforgeProject, } from "@/services/project"; import { useFieldValidations, @@ -137,6 +138,32 @@ const STATIC_DEFS: StaticValidationDef[] = [ : { status: "error", help: r.error }; }, }, + // 5. Modrinth 项目 ID + { + target: ["modrinth", "project_id"], + deps: [["modrinth", "project_id"]], + async validate(getVal) { + const id = getVal(["modrinth", "project_id"]) as string | undefined; + if (!id) return null; + const r = await lookupModrinthProject(id); + return r.ok + ? { status: "success", help: `项目:${r.name}` } + : { status: "error", help: r.error }; + }, + }, + // 6. CurseForge 项目 ID + { + target: ["curseforge", "project_id"], + deps: [["curseforge", "project_id"]], + async validate(getVal) { + const id = getVal(["curseforge", "project_id"]) as number | undefined; + if (id == null || id === 0) return null; + const r = await lookupCurseforgeProject(id); + return r.ok + ? { status: "success", help: `项目:${r.name}` } + : { status: "error", help: r.error }; + }, + }, ]; const LIST_DEFS: ListValidationDef[] = []; @@ -299,29 +326,6 @@ export function ConfigModal({ [mode, initialName, onSaved, message], ); - // --------------- Debounced project name lookup --------------- - - const [modrinthProjectName, setModrinthProjectName] = useState(null); - const [curseforgeProjectName, setCurseforgeProjectName] = useState(null); - - const lookupModrinthProject = useDebouncedCallback(async (projectId: string) => { - if (!projectId) { - setModrinthProjectName(null); - return; - } - // TODO: call Modrinth API to get project name - setModrinthProjectName(null); - }, 800); - - const lookupCurseforgeProject = useDebouncedCallback(async (projectId: number | null) => { - if (projectId == null) { - setCurseforgeProjectName(null); - return; - } - // TODO: call CurseForge API to get project name - setCurseforgeProjectName(null); - }, 800); - // --------------- Render --------------- return ( @@ -351,10 +355,6 @@ export function ConfigModal({ @@ -368,20 +368,12 @@ export function ConfigModal({ interface ConfigModalFormProps { mode: "add" | "edit"; initialConfig: Config | null; - modrinthProjectName: string | null; - curseforgeProjectName: string | null; - lookupModrinthProject: (projectId: string) => void; - lookupCurseforgeProject: (projectId: number | null) => void; onSave: (values: ConfigValues) => void; } function ConfigModalForm({ mode, initialConfig, - modrinthProjectName, - curseforgeProjectName, - lookupModrinthProject, - lookupCurseforgeProject, onSave, }: ConfigModalFormProps) { const [form] = Form.useForm(); @@ -527,23 +519,15 @@ function ConfigModalForm({ label: "Modrinth", children: ( <> - - lookupModrinthProject(e.target.value)} - /> - + + - - lookupCurseforgeProject( - typeof val === "number" ? val : null, - ) - } /> - + | ErrResult> { + try { + const project = await getProject(modrinthClient, projectId); + return { ok: true, name: project.title }; + } catch (err) { + return { ok: false, error: err instanceof Error ? err.message : "查询 Modrinth 项目失败" }; + } +} + +export async function lookupCurseforgeProject( + projectId: number, +): Promise | ErrResult> { + try { + const mod = await getMod(curseforgeClient, projectId); + return { ok: true, name: mod.data.name }; + } catch (err) { + return { ok: false, error: err instanceof Error ? err.message : "查询 CurseForge 项目失败" }; + } +}