feat: per-session input drafts preserved on session switch

This commit is contained in:
Nicolas Varrot
2026-02-12 17:15:26 +00:00
parent e9679091e7
commit 03eb9e6de2
2 changed files with 38 additions and 0 deletions

View File

@@ -344,3 +344,17 @@
7. The release.yml workflow handles the rest (Docker, GitHub Release)
- Accumulate doc/ci changes — only tag when there's a feat or fix to release
- This replaces the previous "Nicolas tags manually" approach
## Item #35
- **Date:** 2026-02-12
- **Priority:** high
- **Status:** pending
- **Description:** Markdown not rendering in long assistant messages — raw `**bold**` shown
- **Details:**
- Reported by Josh (external user) — screenshot shows `**Hypothèse :**` rendered as raw text instead of bold
- Happens on long responses with multiple sections
- The message content appears to bypass ReactMarkdown rendering
- Investigate: is it a blocks vs content fallback issue? Does the message have empty blocks array but content filled?
- Check if autoFormatText() is interfering with markdown syntax
- Verify that streaming → final transition properly re-renders with markdown
- Test with a long multi-section response to reproduce

View File

@@ -88,6 +88,28 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled, sessionKey
const textareaRef = useRef<HTMLTextAreaElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
// Per-session draft storage
const draftsRef = useRef<Map<string, string>>(new Map());
const prevSessionRef = useRef<string | undefined>(sessionKey);
// Save draft to previous session and restore draft for new session
useEffect(() => {
const prev = prevSessionRef.current;
// Save current text as draft for the previous session
if (prev && prev !== sessionKey) {
const currentText = textareaRef.current?.value ?? text;
if (currentText.trim()) {
draftsRef.current.set(prev, currentText);
} else {
draftsRef.current.delete(prev);
}
}
// Restore draft for the new session
const draft = sessionKey ? draftsRef.current.get(sessionKey) ?? '' : '';
setText(draft);
prevSessionRef.current = sessionKey;
}, [sessionKey]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height = 'auto';
@@ -146,6 +168,8 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled, sessionKey
onSend(trimmed || ' ', attachments);
setText('');
setFiles([]);
// Clear draft for this session after sending
if (sessionKey) draftsRef.current.delete(sessionKey);
};
const handleKeyDown = (e: React.KeyboardEvent) => {