Summary

Full redesign of lib/features/search/screens/search_screen.dart. The discovery state (shown when no query is typed) now fits on screen without scrolling and is 100% personalized by user interests.


Files Changed

  • lib/features/search/screens/search_screen.dart — complete redesign

Key Design Decisions

White background

Scaffold.backgroundColor: AppTheme.pureWhite (was scaffoldBackgroundColor). Aligns with the rest of the app’s white-canvas direction.

AnimatedContainer (not a pill — radius14) transitions between two distinct states:

  • Rest: 1.5px inkBlack/14% border, soft drop shadow
  • Focused: 2px electricCoral border, coral glow (blurRadius: 18, alpha: 0.14)

The sharp coral border snap on focus is the “punchy” moment. Icon color also animates: textSecondaryelectricCoral. Uses AppIcons.navSearch and AppIcons.close (Lucide line icons).

No-scroll discovery state

Previous implementation used SingleChildScrollView → required scrolling on smaller phones. New pattern:

Column(
  children: [
    Expanded(child: _buildBentoGrid(items)),   // fills residual height
    SizedBox(height: 36, child: _buildChipsRow(chips)),
    if (tabIndex == 0) _buildBrowseRow(),       // only on All tab
  ],
)

_buildBentoGrid wraps a LayoutBuilder that reads constraints.maxHeight from Expanded, then computes childAspectRatio = cellW / cellH so the 2×2 GridView.count fills the space exactly on every screen size. NeverScrollableScrollPhysics prevents any overflow escape.

Personalized bento items

_buildBentoItems(interests, l10n) builds the 4 cards from API event types (or fallback), then stable-sorts them: cards whose title substring-matches any user interest bubble to position 0–1. Top-left slot (highest attention in LTR layout) shows the user’s preferred category.

Personalized chips

Horizontal chips row: user.interests.take(4) first, then trending tags fill remaining slots up to 8. Users with no interests see pure trending.

Per-item recent search delete

_removeRecentSearch(String query) added alongside the existing _clearRecentSearches. Each recent search row gets a trailing IconButton(AppIcons.close) so users can prune specific items without clearing all.

Browse row

Tab-0 only. Three colored pills (Crew | Persone | Locali) jump directly to tabs 2/3/4 via _tabController.animateTo(tabIndex). Colors match the bento palette (violet / teal / blue).

Icon migration complete

All Icons.* nav/top-bar chrome replaced with AppIcons.* in this screen:

  • Icons.search_roundedAppIcons.navSearch
  • Icons.close_roundedAppIcons.close
  • Icons.history_roundedAppIcons.history
  • Icons.location_on_roundedAppIcons.mapPin
  • Empty-state icons → AppIcons.navSearch, AppIcons.calendar, AppIcons.users, AppIcons.navProfile, AppIcons.mapPin

Body-content icons in tile builders (chevron_right_rounded, whatshot_rounded, etc.) are intentionally kept as Material icons per the body-content exclusion rule.

Removed dependency

flutter_staggered_grid_view is no longer imported in this file. The old StaggeredGrid + StaggeredGridTile.count with alternating 1.2/1.0 heights is replaced by the LayoutBuilder-computed fixed grid.


Architecture Notes

The _KeepAliveWrapper (ConsumerStateful + AutomaticKeepAliveClientMixin) preserves each tab’s scroll/state across tab switches — unchanged from before.

_SearchScreenState watches authNotifierProvider for user interests and mixedTrendingProvider / trendingTagsProvider(TagCategory.vibe) for trending tags. Both are Riverpod providers, so discovery content updates reactively if the user’s interests change mid-session.


refactor-theme-tokens — AppIcons contract, icon migration rules