fix(catalog): keep Nitro editor stable during background polling
This commit is contained in:
1 parent
dcb5f46eed
commit
3c24df9b1d
1 file changed
+35
-32
@@ -16,7 +16,7 @@ import {
|
||||
Save,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useEffect, useEffectEvent, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { NitroQualityPanel } from "@/components/admin/studio/nitro-quality-panel";
|
||||
import { NitroScale32Generator } from "@/components/admin/studio/nitro-scale32-generator";
|
||||
@@ -188,40 +188,43 @@ export function NitroEditorDialog({
|
||||
);
|
||||
};
|
||||
|
||||
const fetchMetadata = useCallback(async () => {
|
||||
if (!classname) return;
|
||||
const closeAfterLoadError = useEffectEvent(() => onOpenChange(false));
|
||||
useEffect(() => {
|
||||
if (!open || !classname) return;
|
||||
const controller = new AbortController();
|
||||
setActiveTab("visual");
|
||||
setLoading(true);
|
||||
setJsonError(null);
|
||||
try {
|
||||
const res = await adminFetch(
|
||||
`/api/admin/import/furni/nitro-editor?classname=${encodeURIComponent(classname)}`,
|
||||
);
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
toast.error(err.error || "Failed to load .nitro metadata");
|
||||
onOpenChange(false);
|
||||
return;
|
||||
setAutoDetectResult(null);
|
||||
void (async () => {
|
||||
try {
|
||||
const res = await adminFetch(
|
||||
`/api/admin/import/furni/nitro-editor?classname=${encodeURIComponent(classname)}`,
|
||||
{ signal: controller.signal },
|
||||
);
|
||||
const data = await res.json();
|
||||
if (controller.signal.aborted) return;
|
||||
if (!res.ok) {
|
||||
toast.error(data.error || "Failed to load .nitro metadata");
|
||||
closeAfterLoadError();
|
||||
return;
|
||||
}
|
||||
setMetadata(data.metadata);
|
||||
setOriginalMetadata(structuredClone(data.metadata));
|
||||
setJsonText(JSON.stringify(data.metadata, null, 2));
|
||||
setFlags(data.flags);
|
||||
setOriginalFlags({ ...data.flags });
|
||||
} catch {
|
||||
if (!controller.signal.aborted) {
|
||||
toast.error("Network error loading .nitro metadata");
|
||||
closeAfterLoadError();
|
||||
}
|
||||
} finally {
|
||||
if (!controller.signal.aborted) setLoading(false);
|
||||
}
|
||||
const data = await res.json();
|
||||
setMetadata(data.metadata);
|
||||
setOriginalMetadata(JSON.parse(JSON.stringify(data.metadata)));
|
||||
setJsonText(JSON.stringify(data.metadata, null, 2));
|
||||
setFlags(data.flags);
|
||||
setOriginalFlags({ ...data.flags });
|
||||
} catch {
|
||||
toast.error("Network error loading .nitro metadata");
|
||||
onOpenChange(false);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [classname, onOpenChange]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open && classname) {
|
||||
setActiveTab("visual");
|
||||
fetchMetadata();
|
||||
}
|
||||
}, [open, classname, fetchMetadata]);
|
||||
})();
|
||||
return () => controller.abort();
|
||||
}, [open, classname]);
|
||||
|
||||
const handleTabChange = (newTab: string) => {
|
||||
if (activeTab === "json" && newTab !== "json") {
|
||||
|
||||
Reference in new issue
Block a user