75b7d6d0fe
Mobile chat occasionally froze with the input disabled and nothing progressing — the underlying cause is SSE sockets dropping silently on mobile network handoffs / proxy idle timeouts. Dio never observes the close, so the send loop's `await for` hangs indefinitely with isStreaming=true. Three changes: - Wrap the SSE stream in a StreamIterator with a 45s per-event timeout as a stall watchdog. On timeout, break out and let the polling pass reconcile state from the server. - Add pull-to-refresh on the chat message list and an AppBar refresh button with inline spinner feedback. Works on both empty and populated states. - MessagesNotifier.refresh() now also clears isStreaming / streamingStatus when the server reports the latest assistant message as complete — so a stuck UI unfreezes the moment the user pulls down or taps refresh, even if the original SSE loop is still hanging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>