fix(rsplat): use queue API for Hunyuan3D + fix controls z-index
Also fix canvas.html null reference crash when share-badge is stripped by extractCanvasContent() header removal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
077bcf260a
commit
2eb9ca2d8f
|
|
@ -571,10 +571,14 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ image_url: imageUrl, title }),
|
body: JSON.stringify({ image_url: imageUrl, title }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stopTicker = () => {
|
||||||
clearInterval(ticker);
|
clearInterval(ticker);
|
||||||
document.removeEventListener("visibilitychange", onVisChange);
|
document.removeEventListener("visibilitychange", onVisChange);
|
||||||
|
};
|
||||||
|
|
||||||
if (res.status === 524 || res.status === 504) {
|
if (res.status === 524 || res.status === 504) {
|
||||||
|
stopTicker();
|
||||||
status.textContent = "Generation timed out — try a simpler image.";
|
status.textContent = "Generation timed out — try a simpler image.";
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
actions.style.display = "flex";
|
actions.style.display = "flex";
|
||||||
|
|
@ -583,6 +587,7 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.status === 503) {
|
if (res.status === 503) {
|
||||||
|
stopTicker();
|
||||||
status.textContent = "AI generation not available — FAL_KEY not configured";
|
status.textContent = "AI generation not available — FAL_KEY not configured";
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
actions.style.display = "flex";
|
actions.style.display = "flex";
|
||||||
|
|
@ -591,6 +596,7 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
stopTicker();
|
||||||
const err = await res.json().catch(() => ({ error: "Generation failed" }));
|
const err = await res.json().catch(() => ({ error: "Generation failed" }));
|
||||||
status.textContent = (err as any).error || "Generation failed";
|
status.textContent = (err as any).error || "Generation failed";
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
|
|
@ -600,7 +606,7 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { job_id } = await res.json() as { job_id: string };
|
const { job_id } = await res.json() as { job_id: string };
|
||||||
status.textContent = "Generating 3D model — you'll get an email when it's ready...";
|
// Ticker keeps running — progress bar continues advancing during polling
|
||||||
|
|
||||||
// Poll for completion
|
// Poll for completion
|
||||||
const pollInterval = setInterval(async () => {
|
const pollInterval = setInterval(async () => {
|
||||||
|
|
@ -610,6 +616,7 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
const job = await pollRes.json() as any;
|
const job = await pollRes.json() as any;
|
||||||
|
|
||||||
if (job.status === "complete") {
|
if (job.status === "complete") {
|
||||||
|
stopTicker();
|
||||||
clearInterval(pollInterval);
|
clearInterval(pollInterval);
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
|
|
||||||
|
|
@ -683,6 +690,7 @@ export class FolkSplatViewer extends HTMLElement {
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if (job.status === "failed") {
|
} else if (job.status === "failed") {
|
||||||
|
stopTicker();
|
||||||
clearInterval(pollInterval);
|
clearInterval(pollInterval);
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
status.textContent = job.error || "Generation failed";
|
status.textContent = job.error || "Generation failed";
|
||||||
|
|
|
||||||
|
|
@ -2931,24 +2931,18 @@
|
||||||
}
|
}
|
||||||
layers = sync.getLayers?.() || [];
|
layers = sync.getLayers?.() || [];
|
||||||
tabBar.setLayers(layers);
|
tabBar.setLayers(layers);
|
||||||
const activeId = sync.doc?.activeLayerId;
|
|
||||||
if (activeId) tabBar.setAttribute('active', activeId);
|
|
||||||
if (sync.getFlows) tabBar.setFlows(sync.getFlows());
|
if (sync.getFlows) tabBar.setFlows(sync.getFlows());
|
||||||
} else {
|
} else {
|
||||||
// First connection: push all localStorage tabs into Automerge
|
// First connection: push all localStorage tabs into Automerge
|
||||||
for (const l of layers) {
|
for (const l of layers) {
|
||||||
sync.addLayer?.(l);
|
sync.addLayer?.(l);
|
||||||
}
|
}
|
||||||
sync.setActiveLayer?.('layer-' + currentModuleId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep localStorage in sync
|
// Keep localStorage in sync
|
||||||
saveTabs();
|
saveTabs();
|
||||||
|
|
||||||
// Sync layer changes back to Automerge
|
// Sync layer changes back to Automerge
|
||||||
tabBar.addEventListener('layer-switch', (e) => {
|
|
||||||
sync.setActiveLayer?.(e.detail.layerId);
|
|
||||||
});
|
|
||||||
tabBar.addEventListener('layer-add', (e) => {
|
tabBar.addEventListener('layer-add', (e) => {
|
||||||
const { moduleId } = e.detail;
|
const { moduleId } = e.detail;
|
||||||
const newLayer = makeLayer(moduleId, sync.getLayers?.().length || 0);
|
const newLayer = makeLayer(moduleId, sync.getLayers?.().length || 0);
|
||||||
|
|
@ -2975,8 +2969,6 @@
|
||||||
layers = sync.getLayers?.() || [];
|
layers = sync.getLayers?.() || [];
|
||||||
tabBar.setLayers(layers);
|
tabBar.setLayers(layers);
|
||||||
if (sync.getFlows) tabBar.setFlows(sync.getFlows());
|
if (sync.getFlows) tabBar.setFlows(sync.getFlows());
|
||||||
const activeId = sync.doc?.activeLayerId;
|
|
||||||
if (activeId) tabBar.setAttribute('active', activeId);
|
|
||||||
const viewMode = sync.doc?.layerViewMode;
|
const viewMode = sync.doc?.layerViewMode;
|
||||||
if (viewMode) tabBar.setAttribute('view-mode', viewMode);
|
if (viewMode) tabBar.setAttribute('view-mode', viewMode);
|
||||||
saveTabs(); // keep localStorage in sync
|
saveTabs(); // keep localStorage in sync
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue