fix: prevent duplicate messages and update support chat UI styling
This commit is contained in:
@@ -80,14 +80,20 @@ class SupportChatNotifier extends StateNotifier<SupportChatState> {
|
|||||||
Future<void> sendMessage(String content) async {
|
Future<void> sendMessage(String content) async {
|
||||||
final chat = state.chat;
|
final chat = state.chat;
|
||||||
if (chat == null || content.trim().isEmpty) return;
|
if (chat == null || content.trim().isEmpty) return;
|
||||||
|
if (state.isSending) return; // Prevent double-send
|
||||||
|
|
||||||
state = state.copyWith(isSending: true);
|
state = state.copyWith(isSending: true);
|
||||||
try {
|
try {
|
||||||
final message = await _repo.sendMessage(chat.id, content.trim());
|
final message = await _repo.sendMessage(chat.id, content.trim());
|
||||||
|
// Dedup — socket broadcast may have already added this message
|
||||||
|
if (!state.messages.any((m) => m.id == message.id)) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
messages: [...state.messages, message],
|
messages: [...state.messages, message],
|
||||||
isSending: false,
|
isSending: false,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
state = state.copyWith(isSending: false);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state = state.copyWith(isSending: false);
|
state = state.copyWith(isSending: false);
|
||||||
rethrow;
|
rethrow;
|
||||||
|
|||||||
@@ -55,9 +55,14 @@ class _SupportChatScreenState extends ConsumerState<SupportChatScreen> {
|
|||||||
socket.emitRaw('support_join', {'chatId': chatId});
|
socket.emitRaw('support_join', {'chatId': chatId});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for new support messages
|
// Listen for new support messages — skip own (added via REST)
|
||||||
_messageSub?.cancel();
|
_messageSub?.cancel();
|
||||||
_messageSub = socket.onSupportMessage.listen((message) {
|
_messageSub = socket.onSupportMessage.listen((message) {
|
||||||
|
// Get fresh userId — currentUserId from build() may have been empty at capture time
|
||||||
|
final myId = currentUserId.isNotEmpty
|
||||||
|
? currentUserId
|
||||||
|
: ref.read(authProvider).user?.id ?? '';
|
||||||
|
if (message.senderId == myId) return;
|
||||||
ref.read(supportChatProvider.notifier).addIncomingMessage(message);
|
ref.read(supportChatProvider.notifier).addIncomingMessage(message);
|
||||||
_scrollToBottom();
|
_scrollToBottom();
|
||||||
});
|
});
|
||||||
@@ -199,9 +204,7 @@ class _SupportChatScreenState extends ConsumerState<SupportChatScreen> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return Column(
|
||||||
body: SafeArea(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
children: [
|
||||||
// Chat header
|
// Chat header
|
||||||
_buildHeader(context, state.chat),
|
_buildHeader(context, state.chat),
|
||||||
@@ -223,8 +226,6 @@ class _SupportChatScreenState extends ConsumerState<SupportChatScreen> {
|
|||||||
if (!state.isLoading && state.error == null)
|
if (!state.isLoading && state.error == null)
|
||||||
_buildInputArea(state),
|
_buildInputArea(state),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +233,7 @@ class _SupportChatScreenState extends ConsumerState<SupportChatScreen> {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: AppColors.primaryDark,
|
color: Color(0xFF648188),
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(0)),
|
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -457,7 +457,7 @@ class _SupportChatScreenState extends ConsumerState<SupportChatScreen> {
|
|||||||
maxWidth: MediaQuery.of(context).size.width * 0.75,
|
maxWidth: MediaQuery.of(context).size.width * 0.75,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isOwn ? AppColors.primaryDark : Colors.white,
|
color: isOwn ? const Color(0xFF648188) : Colors.white,
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: const Radius.circular(15),
|
topLeft: const Radius.circular(15),
|
||||||
topRight: const Radius.circular(15),
|
topRight: const Radius.circular(15),
|
||||||
|
|||||||
Reference in New Issue
Block a user