feat: Implement expandable expertise tags on the agent detail screen and adjust chat screen lifecycle to clear active conversation in deactivate.

This commit is contained in:
pradeepkumar
2026-03-20 02:42:01 +05:30
parent 38423d1586
commit cbb9034424
4 changed files with 101 additions and 37 deletions

View File

@@ -742,33 +742,7 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
// Expertise tags (matching web ProfileCard) // Expertise tags (matching web ProfileCard)
if (state.expertiseTags.isNotEmpty) ...[ if (state.expertiseTags.isNotEmpty) ...[
const SizedBox(height: 14), const SizedBox(height: 14),
Wrap( _ExpandableTagsWrap(tags: state.expertiseTags),
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(),
),
], ],
// Bio with Show More / Show Less // Bio with Show More / Show Less
if (state.descriptionText.isNotEmpty) ...[ if (state.descriptionText.isNotEmpty) ...[
@@ -1225,6 +1199,81 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
// ── Expandable Chips Section ── // ── Expandable Chips Section ──
class _ExpandableTagsWrap extends StatefulWidget {
final List<String> 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 { class _ExpandableChipsSection extends StatefulWidget {
final String title; final String title;
final List<String> items; final List<String> items;

View File

@@ -675,10 +675,11 @@ class _AgentCardState extends State<_AgentCard> {
// Specialization tags // Specialization tags
if (specializations.isNotEmpty) ...[ if (specializations.isNotEmpty) ...[
Wrap( Wrap(
spacing: 8, alignment: WrapAlignment.start,
runSpacing: 8, spacing: 6,
runSpacing: 6,
children: specializations children: specializations
.take(8) .take(6)
.map((tag) => _buildTag(tag)) .map((tag) => _buildTag(tag))
.toList(), .toList(),
), ),
@@ -797,18 +798,21 @@ class _AgentCardState extends State<_AgentCard> {
Widget _buildTag(String label) { Widget _buildTag(String label) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), height: 28,
padding: const EdgeInsets.symmetric(horizontal: 10),
alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColors.primaryDark, width: 0.7), border: Border.all(color: AppColors.primaryDark, width: 0.7),
), ),
child: Text( child: Text(
label, label,
style: const TextStyle( style: const TextStyle(
fontFamily: 'SourceSerif4', fontFamily: 'SourceSerif4',
fontSize: 14, fontSize: 13,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: AppColors.primaryDark, color: AppColors.primaryDark,
height: 1,
), ),
), ),
); );

View File

@@ -441,7 +441,8 @@ class _TopProfessionalsSectionState
), ),
const SizedBox(height: 6), const SizedBox(height: 6),
Wrap( Wrap(
spacing: 8, alignment: WrapAlignment.start,
spacing: 6,
runSpacing: 6, runSpacing: 6,
children: expertiseTags children: expertiseTags
.take(6) .take(6)
@@ -594,9 +595,11 @@ class _TopProfessionalsSectionState
Widget _buildTag(String label) { Widget _buildTag(String label) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), height: 28,
padding: const EdgeInsets.symmetric(horizontal: 10),
alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColors.primaryDark, width: 0.7), border: Border.all(color: AppColors.primaryDark, width: 0.7),
), ),
child: Text( child: Text(
@@ -606,6 +609,7 @@ class _TopProfessionalsSectionState
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: AppColors.primaryDark, color: AppColors.primaryDark,
height: 1,
), ),
), ),
); );

View File

@@ -90,6 +90,14 @@ class _ChatScreenState extends ConsumerState<ChatScreen>
} }
} }
@override
@override
void deactivate() {
// Clear active conversation while ref is still valid (before dispose)
ref.read(messagingProvider.notifier).setActiveConversation(null);
super.deactivate();
}
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
@@ -99,7 +107,6 @@ class _ChatScreenState extends ConsumerState<ChatScreen>
_socket.stopTyping(widget.conversationId); _socket.stopTyping(widget.conversationId);
} }
_socket.leaveConversation(widget.conversationId); _socket.leaveConversation(widget.conversationId);
ref.read(messagingProvider.notifier).setActiveConversation(null);
PushNotificationService().activeConversationId = null; PushNotificationService().activeConversationId = null;
_messageController.dispose(); _messageController.dispose();
_scrollController.dispose(); _scrollController.dispose();