feat: update app icons and refactor home top professionals section to display dynamic agent profiles.

This commit is contained in:
pradeepkumar
2026-03-18 11:42:46 +05:30
parent b52e356a04
commit a90f039b4b
30 changed files with 303 additions and 200 deletions

View File

@@ -97,7 +97,7 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
final currentMessages =
List<ChatMessage>.from(state.messages[convId] ?? []);
// Avoid duplicates
// Avoid duplicates (broadcast may arrive after ack for sender's own message)
if (currentMessages.any((m) => m.id == message.id)) return;
currentMessages.insert(0, message);
@@ -105,12 +105,22 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
Map<String, List<ChatMessage>>.from(state.messages)
..[convId] = currentMessages;
// Show friendly preview for non-text messages (matching web)
String previewText = message.content;
if (message.messageType == MessageType.image) {
previewText = 'Sent an image';
} else if (message.messageType == MessageType.file) {
previewText = 'Sent a file';
} else if (_isGifUrl(message.content)) {
previewText = 'GIF';
}
// Update conversation's last message and unread count
final updatedConversations = state.conversations.map((c) {
if (c.id == convId) {
final isActive = state.activeConversationId == convId;
return c.copyWith(
lastMessageText: message.content,
lastMessageText: previewText,
lastMessageAt: message.createdAt,
unreadCount: isActive ? c.unreadCount : c.unreadCount + 1,
);
@@ -155,6 +165,59 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
}).toList();
state = state.copyWith(conversations: updatedConversations);
}));
// Reconnection: re-join active conversation room and catch up missed messages
_subscriptions.add(_socket.onConnectionChange.listen((connected) {
if (!mounted || !connected) return;
final activeConvId = state.activeConversationId;
if (activeConvId != null) {
_rejoinAndCatchUp(activeConvId);
}
// Refresh conversation list to catch any missed updates
loadConversations();
}));
}
/// Re-join socket room and fetch missed messages after reconnection (matching web)
Future<void> _rejoinAndCatchUp(String conversationId, {int attempt = 1}) async {
try {
await _socket.joinConversation(conversationId);
} catch (_) {
if (attempt < 3 && mounted && state.activeConversationId == conversationId) {
await Future.delayed(Duration(seconds: attempt));
return _rejoinAndCatchUp(conversationId, attempt: attempt + 1);
}
return;
}
// Fetch recent messages to catch any missed during disconnect
if (!mounted || state.activeConversationId != conversationId) return;
try {
final result = await _repository.getMessages(conversationId, page: 1);
final recentMessages = result.messages.reversed.toList();
final currentMessages = List<ChatMessage>.from(state.messages[conversationId] ?? []);
final existingIds = currentMessages.map((m) => m.id).toSet();
final newMessages = recentMessages.where((m) => !existingIds.contains(m.id)).toList();
if (newMessages.isNotEmpty && mounted) {
currentMessages.insertAll(0, newMessages);
// Sort newest first
currentMessages.sort((a, b) => b.createdAt.compareTo(a.createdAt));
final updatedMessages = Map<String, List<ChatMessage>>.from(state.messages)
..[conversationId] = currentMessages;
state = state.copyWith(messages: updatedMessages);
}
} catch (e) {
_log.e('Failed to catch up messages after reconnect', error: e);
}
}
static bool _isGifUrl(String text) {
final lower = text.trim().toLowerCase();
return lower.endsWith('.gif') ||
lower.contains('giphy.com/') ||
lower.contains('giphy.gif') ||
lower.contains('tenor.com/');
}
/// Update online status for a user across all conversations (matching web)
@@ -320,12 +383,22 @@ class MessagingNotifier extends StateNotifier<MessagingState> {
Map<String, List<ChatMessage>>.from(state.messages)
..[conversationId] = messagesAfterSend;
// Update conversation's last message
// Update conversation's last message with friendly preview
final sent = realMessage;
String sentPreview = sent.content;
if (sent.messageType == MessageType.image) {
sentPreview = 'Sent an image';
} else if (sent.messageType == MessageType.file) {
sentPreview = 'Sent a file';
} else if (_isGifUrl(sent.content)) {
sentPreview = 'GIF';
}
final updatedConversations = state.conversations.map((c) {
if (c.id == conversationId) {
return c.copyWith(
lastMessageText: realMessage!.content,
lastMessageAt: realMessage.createdAt,
lastMessageText: sentPreview,
lastMessageAt: sent.createdAt,
);
}
return c;