Isolate drafts by conversation and thread
Persist a separate draft for each conversation and optional thread without leaking text when the active destination changes.Description
Requirements
Export ConversationDraftEditor from src/App.tsx.
Derive a collision-free storage key from both conversationId and the optional threadId.
Load the destination draft immediately when conversation or thread identity changes.
Write edits only to the currently active destination key.
Remove rather than store a draft after its value becomes empty.
Expose visible status and interactive controls with native semantics, accessible names, and keyboard operation appropriate to the workflow.
Do not mutate props, nested caller-owned values, or arrays supplied to the component.
Thread switch
Move from channel C1 root to thread T9
The T9 draft appears and the root draft remains stored
Derive a collision-free storage key from both conversationId and the optional threadId.
Clear draft
Delete the final character
remove is called for only the active draft key
Load the destination draft immediately when conversation or thread identity changes.
Constraints
Use React state and effects only where the observable component contract requires themUse injected adapters instead of accessing network, storage, timers, or browser globals directlyKeep one authoritative state transition for each user or adapter event
Hints
Hint 1
Start with the scoped-draft-key behavior and make its observable result deterministic.
Hint 2
Model switches-without-leak independently before combining it with the remaining states.
Hint 3
Verify the boundary described by removes-empty-draft without changing caller-owned input.