diff --git a/src/components/like-button.tsx b/src/components/like-button.tsx index 0bdf6f9..9bfbb86 100644 --- a/src/components/like-button.tsx +++ b/src/components/like-button.tsx @@ -105,12 +105,19 @@ export function LikeButton({ reactionUriRef.current = result.uri } } catch (err) { - // Revert optimistic update - setLiked(wasLiked) - setCount(previousCount) - reactionUriRef.current = previousUri const message = err instanceof Error ? err.message : 'Failed to update reaction' - toast({ title: 'Error', description: message, variant: 'destructive' }) + const isNotFound = message === 'Not Found' || message.includes('not found') + + if (wasLiked && isNotFound) { + // Reaction was already deleted server-side -- accept the unliked state + reactionUriRef.current = null + } else { + // Revert optimistic update + setLiked(wasLiked) + setCount(previousCount) + reactionUriRef.current = previousUri + toast({ title: 'Error', description: message, variant: 'destructive' }) + } } finally { setPending(false) } diff --git a/src/lib/api/client.ts b/src/lib/api/client.ts index 3e225ac..a4a799b 100644 --- a/src/lib/api/client.ts +++ b/src/lib/api/client.ts @@ -139,11 +139,17 @@ async function apiFetch(path: string, options: FetchOptions = {}): Promise await throwApiError(response) } - if (response.status === 204) { + const contentLength = response.headers.get('content-length') + if (response.status === 204 || contentLength === '0') { return undefined as T } - return response.json() as Promise + const text = await response.text() + if (!text) { + return undefined as T + } + + return JSON.parse(text) as T } function buildQuery(params: Record): string {