Fix React Strict Mode double fetchProject causing WebGL Context Lost
Build and Deploy / build-and-push (push) Successful in 41s

This commit is contained in:
AI Bot
2026-09-02 18:03:42 +05:30
parent a89efe1f7b
commit e30d9e9869
+25 -24
View File
@@ -323,9 +323,11 @@ export default function Editor() {
// Fetch cloud project // Fetch cloud project
useEffect(() => { useEffect(() => {
let ignore = false;
const fetchProject = async () => { const fetchProject = async () => {
if (!projectId || projectId === 'new' || !user) return; if (!projectId || projectId === 'new' || !user) return;
if (ignore) return;
setIsLoading(true); setIsLoading(true);
try { try {
const data = await api.getProject(projectId); const data = await api.getProject(projectId);
@@ -393,11 +395,12 @@ export default function Editor() {
console.error("Failed to fetch project", error); console.error("Failed to fetch project", error);
navigate('/dashboard', { replace: true }); navigate('/dashboard', { replace: true });
} finally { } finally {
setIsLoading(false); if (!ignore) setIsLoading(false);
} }
}; };
fetchProject(); fetchProject();
return () => { ignore = true; };
}, [projectId, user]); }, [projectId, user]);
// History State // History State
@@ -706,16 +709,22 @@ export default function Editor() {
const zipObj: Record<string, Uint8Array> = {}; const zipObj: Record<string, Uint8Array> = {};
if (sceneData.modelData && sceneData.modelData.data && typeof sceneData.modelData.data === 'string') { if (sceneData.modelData && sceneData.modelData.data && typeof sceneData.modelData.data === 'string') {
if (sceneData.modelData.data.startsWith('data:') || sceneData.modelData.data.startsWith('blob:') || sceneData.modelData.data.startsWith('http')) { if (sceneData.modelData.data.startsWith('data:')) {
try { const dataUrl = sceneData.modelData.data;
const res = await fetch(sceneData.modelData.data); const base64 = dataUrl.split(',')[1];
const buf = await res.arrayBuffer(); const binaryStr = atob(base64);
zipObj['model.glb'] = new Uint8Array(buf); const len = binaryStr.length;
sceneData.modelData.data = 'model.glb'; const bytes = new Uint8Array(len);
} catch (fetchErr) { for (let i = 0; i < len; i++) {
console.error("Failed to fetch modelData for zipping", fetchErr); bytes[i] = binaryStr.charCodeAt(i);
throw fetchErr; }
} zipObj['model.glb'] = bytes;
sceneData.modelData.data = 'model.glb';
} else if (sceneData.modelData.data.startsWith('blob:') || sceneData.modelData.data.startsWith('http')) {
const res = await fetch(sceneData.modelData.data);
const buf = await res.arrayBuffer();
zipObj['model.glb'] = new Uint8Array(buf);
sceneData.modelData.data = 'model.glb';
} }
} }
@@ -983,14 +992,7 @@ export default function Editor() {
setIsLoading(true); setIsLoading(true);
setImportStatus("Restoring model..."); setImportStatus("Restoring model...");
try { try {
if (modelInfo.data === 'model.glb') {
throw new Error("Model data is missing from the project file.");
}
const response = await fetch(modelInfo.data); const response = await fetch(modelInfo.data);
if (!response.ok) {
throw new Error(`Failed to fetch model: ${response.statusText}`);
}
const blob = await response.blob(); const blob = await response.blob();
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
@@ -1075,12 +1077,11 @@ export default function Editor() {
setLoadedModel(object); setLoadedModel(object);
setBlobURLs(prev => [...prev, url]); setBlobURLs(prev => [...prev, url]);
} }
setIsLoading(false); setIsLoading(false);
} catch (error: any) { } catch (error) {
console.error('Error re-importing model:', error); console.error('Error re-importing model:', error);
setImportError(error.message || "Failed to load model from project file."); setIsLoading(false);
setIsLoading(false); }
}
}; };
const handleTextureUpload = (event: React.ChangeEvent<HTMLInputElement>, type: 'map' | 'normalMap' | 'specularMap' | 'alphaMap' = 'map') => { const handleTextureUpload = (event: React.ChangeEvent<HTMLInputElement>, type: 'map' | 'normalMap' | 'specularMap' | 'alphaMap' = 'map') => {