Skip to content

refactor(client): adopt EmptyState at inline empty-state sites#1114

Open
NC1107 wants to merge 1 commit into
mainfrom
refactor/empty-state-adoption
Open

refactor(client): adopt EmptyState at inline empty-state sites#1114
NC1107 wants to merge 1 commit into
mainfrom
refactor/empty-state-adoption

Conversation

@NC1107
Copy link
Copy Markdown
Owner

@NC1107 NC1107 commented May 22, 2026

Summary

The componentization audit (2026-05-22) listed 11+ sites where inline Center > Column > Icon + Text empty-state trees should be migrated to the canonical EmptyState widget in apps/client/lib/src/widgets/empty_state.dart. After auditing each site, two needed migration; the rest were already migrated or are intentionally compact placeholders that wouldn't fit the illustrated EmptyState's 64 px badge.

Refs #1100.

Migrated

  • apps/client/lib/src/screens/new_message_screen.dart:558 — the autocomplete empty-state in the chip-based new-message composer. Title varies by query (No contacts yet vs No contacts match "$_query"), no body. Replaced the bespoke Center > Padding > Column > Icon + Text with EmptyState(icon: Icons.person_search_outlined, title: ...).
  • apps/client/lib/src/screens/create_group_screen.dart:272 — the contacts-list empty-state in the create-group member picker. Previous text was 'No contacts available.\nAdd contacts first.' split across two visual lines; now title = No contacts available., body = Add contacts first., icon = Icons.person_outline to match the contacts-screen empty-state. (The original pattern had no icon — adding one is unavoidable because EmptyState requires it. Picked the icon already used on the sibling contacts screen for consistency.)

EmptyState API tweak

EmptyState.body is now optional (String? instead of required String). The new-message composer empty-state has only a title in its dropdown, and forcing callers to invent body copy just to satisfy the signature would be worse than allowing the title-only layout. When body is null the body text and its 8 px gap are skipped; all existing call sites pass a body and render unchanged.

Skipped (with reasons)

  • apps/client/lib/src/screens/contacts_screen.dart:538 — already uses EmptyState (no migration needed).
  • apps/client/lib/src/screens/admin/admin_dashboard_screen.dart:101 — already uses EmptyState.
  • apps/client/lib/src/screens/discover_groups_screen.dart:486 — already uses EmptyState.
  • apps/client/lib/src/screens/home_screen/parts/listeners.dart:110 — already uses EmptyState.
  • apps/client/lib/src/screens/saved_messages_screen.dart:72 — already uses EmptyState.
  • apps/client/lib/src/widgets/quick_switcher_overlay.dart:244 — single Text('No results') inside the cmd-K overlay's result-list area. The overlay is intentionally tight (~480 px wide, list flexes to remaining space); a 64 px illustrated badge would dominate the surface and feel like a different component. Kept as a compact inline placeholder.
  • apps/client/lib/src/widgets/emoji_picker_config.dart:32 — the noRecents slot of the third-party emoji_picker_flutter Config. Plugin expects a small inline widget for the recents tab; an illustrated EmptyState would be out of scale and visually break the tab. Kept as a small Text.
  • apps/client/lib/src/screens/voice_lounge/participant_grid.dart:76_buildPlaceholder is a shared helper also used for the transient 'Connecting to voice...' message and for narrow compact-grid layouts. Migrating only the empty case would fork the helper, and EmptyState's badge is the wrong scale for the compact voice-grid tile. Kept as a compact centered text.
  • apps/client/lib/src/widgets/channel_bar.dart:190_channelStatusLabel returns a String for the channel-bar status row (loading vs empty); it isn't a widget tree at all. Not an empty-state surface in the widget sense.
  • apps/client/lib/src/widgets/channel_bar.dart:1141 — a single italicised Text('No one in voice yet') inside the voice-channel peek popover (small floating panel anchored to a channel row). An illustrated EmptyState would balloon the popover. Kept as inline copy.

Test plan

  • dart format on the three changed files
  • flutter analyze --fatal-infos on the three changed files — no issues
  • flutter test test/screens/new_message_screen_test.dart test/widgets/create_group_screen_test.dart — 9/9 pass
  • flutter test test/screens/home_screen_test.dart test/screens/admin/admin_dashboard_screen_test.dart — 23/23 pass (verifies the body-optional change doesn't break existing EmptyState callers)
  • CI: lint, dev-build (web + linux) on push

Replace the bespoke Center > Column > Icon + Text placeholders in the
new-message composer and the create-group member picker with the shared
EmptyState widget so future tweaks (badge size, copy treatment) only
need to change one widget. Loosens EmptyState.body to optional so the
new-message dropdown can keep its title-only layout.

Refs #1100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant