fix(gif-mood): prevent SSE refresh from wiping in-progress note edits

Track textarea focus state and skip note sync from server while focused.
Fixes concurrent edit race condition where router.refresh() triggered by
another participant's SSE event would overwrite the current user's draft.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 16:46:37 +01:00
parent e7ce98320d
commit 4cc505c63d

View File

@@ -26,6 +26,7 @@ export const GifMoodCard = memo(function GifMoodCard({
const [itemVersion, setItemVersion] = useState(item); const [itemVersion, setItemVersion] = useState(item);
const [isPending, startTransition] = useTransition(); const [isPending, startTransition] = useTransition();
const [imgError, setImgError] = useState(false); const [imgError, setImgError] = useState(false);
const [isFocused, setIsFocused] = useState(false);
const textareaRef = useRef<HTMLTextAreaElement>(null); const textareaRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => { useEffect(() => {
@@ -35,10 +36,13 @@ export const GifMoodCard = memo(function GifMoodCard({
el.style.height = el.scrollHeight + 'px'; el.style.height = el.scrollHeight + 'px';
}, [note]); }, [note]);
// Sync from server only when not focused — prevents SSE refresh from wiping in-progress edits
if (itemVersion !== item) { if (itemVersion !== item) {
setItemVersion(item); setItemVersion(item);
if (!isFocused) {
setNote(item.note || ''); setNote(item.note || '');
} }
}
const isOwner = item.userId === currentUserId; const isOwner = item.userId === currentUserId;
const canEditThis = canEdit && isOwner; const canEditThis = canEdit && isOwner;
@@ -103,7 +107,8 @@ export const GifMoodCard = memo(function GifMoodCard({
ref={textareaRef} ref={textareaRef}
value={note} value={note}
onChange={(e) => setNote(e.target.value)} onChange={(e) => setNote(e.target.value)}
onBlur={handleNoteBlur} onFocus={() => setIsFocused(true)}
onBlur={() => { setIsFocused(false); handleNoteBlur(); }}
placeholder="Ajouter une note…" placeholder="Ajouter une note…"
rows={1} rows={1}
className="w-full text-foreground/70 bg-transparent resize-none outline-none placeholder:text-muted/40 leading-snug text-center overflow-hidden" className="w-full text-foreground/70 bg-transparent resize-none outline-none placeholder:text-muted/40 leading-snug text-center overflow-hidden"