Show loading placeholder while waiting for assistant response (#2270)
* perf(chat): avoid microtask delay before user bubble paints
The await on Promise.all((files ?? []).map(file2base64)) in writeMessage
always yielded a microtask before addChildren inserted the user message
into the reactive tree — even on text-only sends where the array is
empty. Short-circuit to [] when there are no files so the bubble can
render in the same task as the Enter keydown. Also drop a dead
unawaited tick() in ChatInput's submit handler.
* Revert "perf(chat): avoid microtask delay before user bubble paints"
This reverts commit a83a5d92b1d07574c559321ab95cbaadc0c0bf7e.
* feat(chat): show assistant loader instantly on Enter
`pending = true` is set synchronously at the top of writeMessage, but
ChatWindow only renders its loader placeholder when messages.length === 0
(i.e. only on the first send of a fresh conversation). For an existing
conversation, the user has no visual feedback until writeMessage finishes
its async work (file base64 encoding, MCP store hydration) and addChildren
inserts the blank assistant node.
Render an extra bouncing-dots assistant placeholder at the end of the
message list whenever `pending` is true and the in-tree last message
isn't already an empty assistant. Once writeMessage gets through to
addChildren, that condition flips and the in-tree empty assistant takes
over the loader visual — same dots, no double-loader.
---------
Co-authored-by: Claude <noreply@anthropic.com>