fix: add tags optimistically on the detail page
submitTag now shows the chip immediately with the typed name and reconciles it with the server's (normalized) ref on success, rolling back on error — matching the already-optimistic tag removal instead of blocking on the round-trip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -257,18 +257,27 @@
|
||||
async function submitTag(name: string) {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed || !session.user || tagAddBusy) return;
|
||||
const snapshot = tags;
|
||||
// Show the chip immediately with the typed name; reconcile with the
|
||||
// server ref (which may normalize the name/id) on success. Drop any
|
||||
// existing same-name chip so a re-add doesn't duplicate.
|
||||
const tempId = `optimistic-${crypto.randomUUID()}`;
|
||||
tags = [
|
||||
...tags.filter((t) => t.name.toLowerCase() !== trimmed.toLowerCase()),
|
||||
{ id: tempId, name: trimmed, added_by: session.user.id }
|
||||
];
|
||||
tagDraft = '';
|
||||
suggestions = [];
|
||||
suggestHighlight = -1;
|
||||
tagAddBusy = true;
|
||||
tagError = null;
|
||||
try {
|
||||
const attached = await attachTag(manga.id, trimmed);
|
||||
// If the tag was already attached by someone else, the
|
||||
// server returns 200 + the existing ref — replace any
|
||||
// matching entry to keep local state coherent.
|
||||
tags = [...tags.filter((t) => t.id !== attached.id), attached];
|
||||
tagDraft = '';
|
||||
suggestions = [];
|
||||
suggestHighlight = -1;
|
||||
// Replace the placeholder (and any pre-existing entry the server
|
||||
// may have matched) with the authoritative ref.
|
||||
tags = [...tags.filter((t) => t.id !== tempId && t.id !== attached.id), attached];
|
||||
} catch (e) {
|
||||
tags = snapshot;
|
||||
tagError = (e as Error).message;
|
||||
} finally {
|
||||
tagAddBusy = false;
|
||||
|
||||
Reference in New Issue
Block a user