From cbb903442468a33946eb2fcc1d73af7ba3de068c Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Fri, 20 Mar 2026 02:42:01 +0530 Subject: [PATCH] feat: Implement expandable expertise tags on the agent detail screen and adjust chat screen lifecycle to clear active conversation in `deactivate`. --- .../screens/agent_detail_screen.dart | 103 +++++++++++++----- .../screens/agent_search_screen.dart | 16 ++- .../widgets/top_professionals_section.dart | 10 +- .../presentation/screens/chat_screen.dart | 9 +- 4 files changed, 101 insertions(+), 37 deletions(-) diff --git a/lib/features/agents/presentation/screens/agent_detail_screen.dart b/lib/features/agents/presentation/screens/agent_detail_screen.dart index 96c8fca..978a0be 100644 --- a/lib/features/agents/presentation/screens/agent_detail_screen.dart +++ b/lib/features/agents/presentation/screens/agent_detail_screen.dart @@ -742,33 +742,7 @@ class _AgentDetailScreenState extends ConsumerState { // Expertise tags (matching web ProfileCard) if (state.expertiseTags.isNotEmpty) ...[ const SizedBox(height: 14), - Wrap( - alignment: WrapAlignment.center, - spacing: 8, - runSpacing: 8, - children: state.expertiseTags - .map((tag) => Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 5), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: AppColors.primaryDark, - width: 0.7, - ), - ), - child: Text( - tag, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w400, - color: AppColors.primaryDark, - ), - ), - )) - .toList(), - ), + _ExpandableTagsWrap(tags: state.expertiseTags), ], // Bio with Show More / Show Less if (state.descriptionText.isNotEmpty) ...[ @@ -1225,6 +1199,81 @@ class _AgentDetailScreenState extends ConsumerState { // ── Expandable Chips Section ── +class _ExpandableTagsWrap extends StatefulWidget { + final List tags; + final int initialCount; + + const _ExpandableTagsWrap({required this.tags, this.initialCount = 6}); + + @override + State<_ExpandableTagsWrap> createState() => _ExpandableTagsWrapState(); +} + +class _ExpandableTagsWrapState extends State<_ExpandableTagsWrap> { + bool _expanded = false; + + @override + Widget build(BuildContext context) { + final displayTags = + _expanded ? widget.tags : widget.tags.take(widget.initialCount).toList(); + final hasMore = widget.tags.length > widget.initialCount; + + return Column( + children: [ + Wrap( + alignment: WrapAlignment.center, + spacing: 8, + runSpacing: 8, + children: displayTags + .map((tag) => Container( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 5), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: AppColors.primaryDark, + width: 0.7, + ), + ), + child: Text( + tag, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w400, + color: AppColors.primaryDark, + ), + ), + )) + .toList(), + ), + if (hasMore) ...[ + const SizedBox(height: 10), + GestureDetector( + onTap: () => setState(() => _expanded = !_expanded), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all(color: AppColors.accentOrange, width: 0.7), + ), + child: Text( + _expanded ? 'Show Less' : 'Show More', + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 10, + fontWeight: FontWeight.w700, + color: AppColors.accentOrange, + ), + ), + ), + ), + ], + ], + ); + } +} + class _ExpandableChipsSection extends StatefulWidget { final String title; final List items; diff --git a/lib/features/agents/presentation/screens/agent_search_screen.dart b/lib/features/agents/presentation/screens/agent_search_screen.dart index c8c19f5..9d357d4 100644 --- a/lib/features/agents/presentation/screens/agent_search_screen.dart +++ b/lib/features/agents/presentation/screens/agent_search_screen.dart @@ -675,10 +675,11 @@ class _AgentCardState extends State<_AgentCard> { // Specialization tags if (specializations.isNotEmpty) ...[ Wrap( - spacing: 8, - runSpacing: 8, + alignment: WrapAlignment.start, + spacing: 6, + runSpacing: 6, children: specializations - .take(8) + .take(6) .map((tag) => _buildTag(tag)) .toList(), ), @@ -797,18 +798,21 @@ class _AgentCardState extends State<_AgentCard> { Widget _buildTag(String label) { return Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + height: 28, + padding: const EdgeInsets.symmetric(horizontal: 10), + alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), + borderRadius: BorderRadius.circular(14), border: Border.all(color: AppColors.primaryDark, width: 0.7), ), child: Text( label, style: const TextStyle( fontFamily: 'SourceSerif4', - fontSize: 14, + fontSize: 13, fontWeight: FontWeight.w400, color: AppColors.primaryDark, + height: 1, ), ), ); diff --git a/lib/features/home/presentation/widgets/top_professionals_section.dart b/lib/features/home/presentation/widgets/top_professionals_section.dart index 6f13032..a22abb7 100644 --- a/lib/features/home/presentation/widgets/top_professionals_section.dart +++ b/lib/features/home/presentation/widgets/top_professionals_section.dart @@ -441,7 +441,8 @@ class _TopProfessionalsSectionState ), const SizedBox(height: 6), Wrap( - spacing: 8, + alignment: WrapAlignment.start, + spacing: 6, runSpacing: 6, children: expertiseTags .take(6) @@ -594,9 +595,11 @@ class _TopProfessionalsSectionState Widget _buildTag(String label) { return Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), + height: 28, + padding: const EdgeInsets.symmetric(horizontal: 10), + alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), + borderRadius: BorderRadius.circular(14), border: Border.all(color: AppColors.primaryDark, width: 0.7), ), child: Text( @@ -606,6 +609,7 @@ class _TopProfessionalsSectionState fontSize: 13, fontWeight: FontWeight.w400, color: AppColors.primaryDark, + height: 1, ), ), ); diff --git a/lib/features/messaging/presentation/screens/chat_screen.dart b/lib/features/messaging/presentation/screens/chat_screen.dart index debd13a..eae01fc 100644 --- a/lib/features/messaging/presentation/screens/chat_screen.dart +++ b/lib/features/messaging/presentation/screens/chat_screen.dart @@ -90,6 +90,14 @@ class _ChatScreenState extends ConsumerState } } + @override + @override + void deactivate() { + // Clear active conversation while ref is still valid (before dispose) + ref.read(messagingProvider.notifier).setActiveConversation(null); + super.deactivate(); + } + @override void dispose() { WidgetsBinding.instance.removeObserver(this); @@ -99,7 +107,6 @@ class _ChatScreenState extends ConsumerState _socket.stopTyping(widget.conversationId); } _socket.leaveConversation(widget.conversationId); - ref.read(messagingProvider.notifier).setActiveConversation(null); PushNotificationService().activeConversationId = null; _messageController.dispose(); _scrollController.dispose();