diff --git a/src/pages/Editor.tsx b/src/pages/Editor.tsx index 2ad0f69..b921e1d 100644 --- a/src/pages/Editor.tsx +++ b/src/pages/Editor.tsx @@ -323,9 +323,11 @@ export default function Editor() { // Fetch cloud project useEffect(() => { + let ignore = false; const fetchProject = async () => { if (!projectId || projectId === 'new' || !user) return; + if (ignore) return; setIsLoading(true); try { const data = await api.getProject(projectId); @@ -393,11 +395,12 @@ export default function Editor() { console.error("Failed to fetch project", error); navigate('/dashboard', { replace: true }); } finally { - setIsLoading(false); + if (!ignore) setIsLoading(false); } }; fetchProject(); + return () => { ignore = true; }; }, [projectId, user]); // History State @@ -706,16 +709,22 @@ export default function Editor() { const zipObj: Record = {}; 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')) { - try { - const res = await fetch(sceneData.modelData.data); - const buf = await res.arrayBuffer(); - zipObj['model.glb'] = new Uint8Array(buf); - sceneData.modelData.data = 'model.glb'; - } catch (fetchErr) { - console.error("Failed to fetch modelData for zipping", fetchErr); - throw fetchErr; - } + if (sceneData.modelData.data.startsWith('data:')) { + const dataUrl = sceneData.modelData.data; + const base64 = dataUrl.split(',')[1]; + const binaryStr = atob(base64); + const len = binaryStr.length; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; i++) { + bytes[i] = binaryStr.charCodeAt(i); + } + 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); setImportStatus("Restoring model..."); try { - if (modelInfo.data === 'model.glb') { - throw new Error("Model data is missing from the project file."); - } - const response = await fetch(modelInfo.data); - if (!response.ok) { - throw new Error(`Failed to fetch model: ${response.statusText}`); - } const blob = await response.blob(); const url = URL.createObjectURL(blob); @@ -1075,12 +1077,11 @@ export default function Editor() { setLoadedModel(object); setBlobURLs(prev => [...prev, url]); } - setIsLoading(false); - } catch (error: any) { - console.error('Error re-importing model:', error); - setImportError(error.message || "Failed to load model from project file."); - setIsLoading(false); - } + setIsLoading(false); + } catch (error) { + console.error('Error re-importing model:', error); + setIsLoading(false); + } }; const handleTextureUpload = (event: React.ChangeEvent, type: 'map' | 'normalMap' | 'specularMap' | 'alphaMap' = 'map') => {