Shell: move Projects/News/Calendar into ShellRoute so the NavigationRail
persists across all screens. Show all 6 nav destinations on tablet
instead of 3+More overflow. Phone bottom nav unchanged.
Chat: master-detail layout on tablet — conversations list (320px) with
inline chat panel. Tapping a conversation updates state instead of
pushing a new route.
Knowledge: responsive grid (2 cols portrait, 3 cols landscape) with
card layout showing icon, title, body preview, and tags. Fix snippet
data — read json['snippet'] which the API actually sends. Bump snippet
length from 120 to 200 chars. Tasks now show description as snippet.
News: responsive grid with the same breakpoints. Larger snippet
(5 lines) in grid mode via snippetMaxLines parameter.
Briefing: centered reading column (maxWidth 700) on wide screens,
matching the web UI layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VoiceState now carries a normalized mic amplitude (0..1) updated
from the existing onAmplitudeChanged subscription, with a 0.02
change threshold so we don't spam rebuilds.
VoiceMicButton swaps the constant-rate AnimationController for an
AnimatedScale + animated glow driven by the live amplitude. 0.1
floor keeps the button breathing on silence; 120ms ease-out smooths
between 200ms samples.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Briefing chat now uses the same StreamIterator + 45s per-event timeout
as the main chat provider, so a dropped SSE socket no longer leaves
isBriefingStreaming stuck true. Adds refreshMessages() that unfreezes
state when the server-side message is complete, wired to a new
pull-to-refresh gesture and the app lifecycle-resume hook.
Chat provider gains attachToGeneration() — safe to call unconditionally
on screen init, so landing on a conversation that's already mid-stream
(e.g. the /news discuss button, which now creates a conv and auto-kicks
generation server-side) picks up live tokens instead of freezing on the
placeholder.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds discussArticle() to BriefingApi and wires it through to the
RSS news cards in BriefingScreen so tapping Discuss opens a chat
conversation seeded with the article. Also caps RSS cards per
message at 3 to avoid overly long briefing threads.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces bare Story-N reaction rows with full NewsCard widgets: source label,
relative timestamp, linked headline, 2-line snippet, and 👍/👎 reactions.
Reads rss_items from message metadata (requires backend ≥ this sprint).
Adds url_launcher ^6.3.1 for opening article links in the browser.
Adds https/http <queries> entries to AndroidManifest for Android 11+.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Timer.periodic every 60s calls silentRefresh() on BriefingNotifier.
silentRefresh() patches AsyncData directly — never triggers AsyncLoading —
so existing content stays on screen while the fetch is in flight.
WidgetsBindingObserver pauses polling when app is backgrounded.
Polling is also skipped while a reply is actively streaming.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The summary card duplicated the first assistant message and consumed
screen real estate without benefit on small screens. Replaced with:
- Full message list via ChatMessageBubble from the top
- SliverFillRemaining empty state ("No briefing yet today" + generate button)
when no messages exist
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update dialog no longer re-appears on every shell re-mount; check()
is skipped if status is already available/upToDate/downloading
- Offline queue dequeue now happens before the mounted check, preventing
ghost items when the widget disposes mid-drain
- Briefing digest card and messages now share a CustomScrollView so
expanding the card doesn't trap the user without scroll access
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>