Skip to content

refactor(ui): unify conversation headers and split oversized widgets - #17

Merged
ForeverInLaw merged 2 commits into
mainfrom
simplify/ui-simplify
Sep 22, 2026
Merged

ForeverInLaw merged 2 commits into
mainfrom
simplify/ui-simplify

Conversation

@ForeverInLaw

@ForeverInLaw ForeverInLaw commented Sep 21, 2026 •

Copy link
Copy Markdown

User description

Problem

Three conversation headers repeated the same AppBar skeleton (rail-back leading, mobile search toggle, kebab menu, peer-status, leave); several widgets blew past the 400-line file budget (media_viewer 709, attachment_card 468, onboard_menu 362); conversation_controller drove 21 raw if-sites and three copies of the same attachment download/cancel flow.

Change

  • One shared ConversationAppBar carries the skeleton; each kind passes its specifics. group 302→223, dm 168→123, channel 94→35 lines. Action order, tooltips, l10n, and Semantics trees are byte-identical.
  • media_viewer 709→393 + stages part file; attachment_card 468→321 + branches part file. Pure widget moves.
  • conversation_controller: exhaustive sealed-switch on the target types replaces if-chains; download/cancel deduped to one site; every method ≤50 LOC.
  • onboard_menu 362→241 + part file; org_section's two offer rows merged into one switch-driven row.
  • voice_composer/voice_message_card share formatVoiceClock and the waveform bucket helper instead of two copies.

No handwritten lib file over 400 LOC remains (generated bridge files exempt).

Verification

  • flutter analyze clean, all 838 widget/unit tests pass
  • dart format lib test clean

Stack: PR 4/6 (on #16).


CodeAnt-AI Description

Unify conversation headers and fix media, voice, invite, and session-rail behavior

What Changed

  • DM, group, and channel headers now use one consistent layout while preserving their kind-specific actions, including search, filters, status, calling, invites, and leave controls.
  • Conversation headers now occupy their full height at both compact and desktop breakpoints instead of leaving gaps or clipping content.
  • Malformed attachment thumbnails render a broken-image fallback instead of preventing the conversation from loading.
  • Voice playback tapped before a download completes now starts automatically when the file becomes available; recording cleanup also avoids conflicts between stop, discard, and auto-stop.
  • Pull-to-refresh now updates DMs, groups, channels, pending offers, and organizations together.
  • Invite detection routes DM, group, and organization invites to their matching join flow and destination.
  • Media and onboarding widgets retain the same behavior while being split into smaller UI sections.

Impact

✅ Consistent conversation controls across DM, group, and channel screens
✅ No clipped or misaligned conversation headers
✅ Conversations survive invalid attachment thumbnails
✅ Voice playback starts after downloads complete
✅ Refreshes show current groups, channels, offers, and organizations

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 662f5a1 Sep 22, 2026 · 01:33 01:34
✅ Reviewed your PR 28a49ff Sep 21, 2026 · 23:04 23:07

@codeant-ai

codeant-ai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Comment thread lib/src/features/conversation/attachment_card_branches.dart Outdated
Comment thread lib/src/features/conversation/conversation_app_bar.dart
Comment thread lib/src/features/conversation/voice_message_card.dart
Comment thread lib/src/features/sessions/sessions_screen.dart Outdated
Comment thread lib/src/features/shared/media_viewer_stages.dart Outdated
Comment thread lib/src/features/shared/voice_composer.dart
@ForeverInLaw
ForeverInLaw force-pushed the simplify/ui-simplify branch 2 times, most recently from 7a12881 to 2178b6d Compare September 21, 2026 23:42
Behavior-preserving UI consolidation:

- One shared ConversationAppBar now carries the AppBar skeleton all
  three conversation kinds repeated (rail-back leading, mobile search
  toggle, kebab menu with the attachments filter, peer-status button,
  desktop leave). group 302→223, dm 168→123, channel 94→35 lines;
  action order, tooltips, l10n, and Semantics trees byte-identical.
- media_viewer 709→393 + media_viewer_stages.dart part (video/audio/
  placeholder stages); attachment_card 468→321 + branches part file.
  Pure widget moves, zero tree changes.
- onboard_menu 362→241 + part file for the leaf tiles; the two offer
  rows in org_section merged into one switch-driven row.
- conversation_controller: exhaustive sealed-switch on the target
  types replaces if-chains; download/cancel attachment sites deduped;
  every method ≤50 LOC.
- voice_composer/voice_message_card share formatVoiceClock and the
  waveform bucket helper instead of carrying two copies.

No handwritten lib file over 400 LOC remains. flutter analyze clean,
all 838 widget/unit tests pass.
Six review findings, each validated before fixing:

- attachment thumbnail: base64Decode threw during build, escaping
  Image.memory's errorBuilder and killing the conversation render.
  Defensive decode now falls through to the broken-image fallback.
- conversation header: kind headers reported kToolbarHeight (56) as
  preferredSize while drawing 54/70px toolbars; Scaffold clamped its
  slot to the reported height. A PreferredSize wrapper now re-reports
  the height the AppBar actually draws, rebuilt on breakpoint change.
- voice message card: a play tapped during download only queued a
  file load, never playback. The card now queues the play itself and
  opens with play:false so the queue is the single autoplay source.
- sessions rail: pull-to-refresh only re-read the DM list while the
  rail renders all kinds plus orgs; it now refreshes every slice
  (same envelope org_actions uses).
- media viewer stages: unawaited player.open rejections escaped the
  initState try block as unhandled async errors; opens are now
  awaited inside the stage with a fallback-to-placeholder catch.
- voice composer: manual stop, the auto-stop timer and discard could
  race the recorder teardown; a single-flight guard makes them
  mutually exclusive.

Four focused regression tests added (thumbnail fallback, header slot
height at both breakpoints, queued play flow, all-slices refresh).
Gates: flutter analyze clean, dart format clean, flutter test
842 passed / 0 failed.
@ForeverInLaw
ForeverInLaw changed the base branch from simplify/core-split to main September 22, 2026 01:55
@ForeverInLaw
ForeverInLaw merged commit b8022f0 into main Sep 22, 2026
13 of 20 checks passed
@ForeverInLaw
ForeverInLaw deleted the simplify/ui-simplify branch September 22, 2026 01:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant