Oracle re-review on PR #30 flagged that _ChatDetailViewState only
called onDraftChanged when _textCtl.text was non-empty. The empty
case is load-bearing: if the user restored a saved draft, deleted
the text, then switched target (or closed the panel), the parent's
draft map kept the stale entry and resurrected it on the next swap.
Fix: call onDraftChanged unconditionally in both didUpdateWidget
(target change) and dispose (tear-down), so the parent map learns
when a draft is now empty.
Adds a regression test exercising the restore-clear-swap sequence.