Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e02863022 | |||
| 90c2134bbe |
+8
-42
@@ -108,8 +108,6 @@ export function App() {
|
|||||||
const loadVersionRef = useRef(0);
|
const loadVersionRef = useRef(0);
|
||||||
const themeSyncFrameRef = useRef<number | null>(null);
|
const themeSyncFrameRef = useRef<number | null>(null);
|
||||||
const toastTimeoutRef = useRef<number | null>(null);
|
const toastTimeoutRef = useRef<number | null>(null);
|
||||||
const loadedUpdatedAtRef = useRef<string | null>(null);
|
|
||||||
const inFlightTitleSaveRef = useRef<Promise<void> | null>(null);
|
|
||||||
|
|
||||||
const activeDrawing = useMemo(
|
const activeDrawing = useMemo(
|
||||||
() => drawings.find((drawing) => drawing.id === activeId) ?? null,
|
() => drawings.find((drawing) => drawing.id === activeId) ?? null,
|
||||||
@@ -143,7 +141,6 @@ export function App() {
|
|||||||
body: JSON.stringify(nextScene),
|
body: JSON.stringify(nextScene),
|
||||||
})
|
})
|
||||||
.then((body) => {
|
.then((body) => {
|
||||||
loadedUpdatedAtRef.current = body.drawing.updatedAt;
|
|
||||||
setDrawings((current) => replaceMeta(current, body.drawing));
|
setDrawings((current) => replaceMeta(current, body.drawing));
|
||||||
if (isManual) {
|
if (isManual) {
|
||||||
setToastMessage("Saved");
|
setToastMessage("Saved");
|
||||||
@@ -233,7 +230,6 @@ export function App() {
|
|||||||
currentIdRef.current = drawing.id;
|
currentIdRef.current = drawing.id;
|
||||||
currentTitleRef.current = drawing.title;
|
currentTitleRef.current = drawing.title;
|
||||||
latestSceneRef.current = nextScene;
|
latestSceneRef.current = nextScene;
|
||||||
loadedUpdatedAtRef.current = drawing.updatedAt;
|
|
||||||
|
|
||||||
setDrawings(sortDrawings(list));
|
setDrawings(sortDrawings(list));
|
||||||
setActiveId(drawing.id);
|
setActiveId(drawing.id);
|
||||||
@@ -327,22 +323,18 @@ export function App() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const promise = requestJson<{ ok: true; drawing: DrawingMeta }>(`/api/drawings/${drawingId}`, {
|
try {
|
||||||
|
const body = await requestJson<{ ok: true; drawing: DrawingMeta }>(`/api/drawings/${drawingId}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify({ title: currentTitleRef.current }),
|
body: JSON.stringify({ title: currentTitleRef.current }),
|
||||||
}).then((body) => {
|
|
||||||
currentTitleRef.current = body.drawing.title;
|
|
||||||
loadedUpdatedAtRef.current = body.drawing.updatedAt;
|
|
||||||
setActiveTitle(body.drawing.title);
|
|
||||||
setDrawings((current) => replaceMeta(current, body.drawing));
|
|
||||||
}).catch((renameError) => {
|
|
||||||
setError(renameError instanceof Error ? renameError.message : "Rename failed");
|
|
||||||
}).finally(() => {
|
|
||||||
inFlightTitleSaveRef.current = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inFlightTitleSaveRef.current = promise;
|
currentTitleRef.current = body.drawing.title;
|
||||||
await promise;
|
setActiveTitle(body.drawing.title);
|
||||||
|
setDrawings((current) => replaceMeta(current, body.drawing));
|
||||||
|
} catch (renameError) {
|
||||||
|
setError(renameError instanceof Error ? renameError.message : "Rename failed");
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const syncThemeTokens = useCallback(() => {
|
const syncThemeTokens = useCallback(() => {
|
||||||
@@ -419,32 +411,6 @@ export function App() {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const interval = window.setInterval(() => {
|
|
||||||
void refreshList();
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.clearInterval(interval);
|
|
||||||
};
|
|
||||||
}, [refreshList]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
activeDrawing &&
|
|
||||||
loadedUpdatedAtRef.current &&
|
|
||||||
activeDrawing.updatedAt !== loadedUpdatedAtRef.current &&
|
|
||||||
!inFlightSaveRef.current &&
|
|
||||||
!inFlightTitleSaveRef.current
|
|
||||||
) {
|
|
||||||
if (timeoutRef.current !== null) {
|
|
||||||
clearTimeout(timeoutRef.current);
|
|
||||||
timeoutRef.current = null;
|
|
||||||
}
|
|
||||||
void loadDrawing(activeDrawing.id);
|
|
||||||
}
|
|
||||||
}, [activeDrawing, loadDrawing]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!scene || loading) {
|
if (!scene || loading) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ function errorResponse(error: unknown): Response {
|
|||||||
return json({ ok: false, error: error.message }, { status: error.status });
|
return json({ ok: false, error: error.message }, { status: error.status });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error instanceof Error && error.name === "AbortError") {
|
||||||
|
return json({ ok: false, error: "Request aborted" }, { status: 499 });
|
||||||
|
}
|
||||||
|
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return json({ ok: false, error: "Internal server error" }, { status: 500 });
|
return json({ ok: false, error: "Internal server error" }, { status: 500 });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user