feat(chat): add plan order message widget and enhance chat bubble to support message types

This commit is contained in:
mso7nueh
2025-12-19 15:08:11 +03:00
parent 5c9a9c22ba
commit 22b2e5f249
42 changed files with 611 additions and 37 deletions

View File

@@ -12,6 +12,7 @@ import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cub
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/about_order_button.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chat_bubble_widget.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/plan_order_message_widget.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.dart';
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_state.dart';
@@ -221,14 +222,36 @@ class _ChatScreenState extends State<ChatScreen> {
state.chatMessages[index].updatedAt.day != state.chatMessages[index + 1].updatedAt.day) ||
index + 1 == state.chatMessages.length) {
final isCurrentUserAuthor = state.chatRoom.users.receiver.id != state.chatMessages[index].authorId;
final message = state.chatMessages[index];
final isPlanOrderMessage = message.type == 'plan_order';
PacketOptions? messageOption;
if (isPlanOrderMessage && chosenPlan != null) {
if (chosenPlan.optionType == 'options1') {
messageOption = chosenPlan.plan.packet1Options;
} else if (chosenPlan.optionType == 'options2') {
messageOption = chosenPlan.plan.packet2Options;
} else if (chosenPlan.optionType == 'options3') {
messageOption = chosenPlan.plan.packet3Options;
}
}
return Column(
children: [
_messageDate(state.chatMessages[index].updatedAt),
_messageDate(message.updatedAt),
if (isPlanOrderMessage && chosenPlan != null && messageOption != null)
PlanOrderMessageWidget(
planName: chosenPlan.plan.name,
planSlug: chosenPlan.plan.slug,
price: messageOption.price,
sendTime: message.updatedAt,
isCurrentUser: isCurrentUserAuthor,
),
VisibilityDetector(
key: Key(state.chatMessages[index].id.toString()),
key: Key(message.id.toString()),
onVisibilityChanged: (VisibilityInfo info) {
if (!state.chatMessages[index].isRead && !isCurrentUserAuthor && info.visibleFraction > 0) {
unreadMessagesIdsCopy.add((id: state.chatMessages[index].id, index: index));
if (!message.isRead && !isCurrentUserAuthor && info.visibleFraction > 0) {
unreadMessagesIdsCopy.add((id: message.id, index: index));
EasyDebounce.debounce('mark_as_read', const Duration(milliseconds: 500), () async {
final result = await context.read<ChatRoomCubit>().markMessagesAsRead(state.chatRoom.id, unreadMessagesIdsCopy);
if (!result) return;
@@ -242,44 +265,74 @@ class _ChatScreenState extends State<ChatScreen> {
}
},
child: ChatBubbleWidget(
isRead: state.chatMessages[index].isRead,
sendTime: state.chatMessages[index].updatedAt,
text: state.chatMessages[index].data.trim(),
isRead: message.isRead,
sendTime: message.updatedAt,
text: message.data.trim(),
isCurrentUser: isCurrentUserAuthor,
mediaData: state.chatMessages[index].mediaData ?? [],
messageState: state.chatMessages[index].messageState,
messageUuid: state.chatMessages[index].uuid ?? '',
mediaData: message.mediaData ?? [],
messageState: message.messageState,
messageUuid: message.uuid ?? '',
userSlug: state.chatRoom.users.receiver.slug,
messageType: message.type,
isConsultant: amIConsultant,
),
),
],
);
}
final isCurrentUserAuthor = state.chatRoom.users.receiver.id != state.chatMessages[index].authorId;
return VisibilityDetector(
key: Key(state.chatMessages[index].id.toString()),
onVisibilityChanged: (VisibilityInfo info) {
if (!state.chatMessages[index].isRead && !isCurrentUserAuthor && info.visibleFraction > 0) {
unreadMessagesIds.add((id: state.chatMessages[index].id, index: index));
EasyDebounce.debounce('mark_as_read', const Duration(milliseconds: 500), () async {
final result = await context.read<ChatRoomCubit>().markMessagesAsRead(state.chatRoom.id, unreadMessagesIds);
if (!result) return;
if (!context.mounted) return;
context.read<ChatsCubit>().reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length);
unreadMessagesIds.clear();
});
}
},
child: ChatBubbleWidget(
isRead: state.chatMessages[index].isRead,
sendTime: state.chatMessages[index].updatedAt,
text: state.chatMessages[index].data.trim(),
isCurrentUser: isCurrentUserAuthor,
mediaData: state.chatMessages[index].mediaData ?? [],
messageState: state.chatMessages[index].messageState,
messageUuid: state.chatMessages[index].uuid ?? '',
userSlug: state.chatRoom.users.receiver.slug,
),
final message = state.chatMessages[index];
final isPlanOrderMessage = message.type == 'plan_order';
PacketOptions? messageOption;
if (isPlanOrderMessage && chosenPlan != null) {
if (chosenPlan.optionType == 'options1') {
messageOption = chosenPlan.plan.packet1Options;
} else if (chosenPlan.optionType == 'options2') {
messageOption = chosenPlan.plan.packet2Options;
} else if (chosenPlan.optionType == 'options3') {
messageOption = chosenPlan.plan.packet3Options;
}
}
return Column(
children: [
if (isPlanOrderMessage && chosenPlan != null && messageOption != null)
PlanOrderMessageWidget(
planName: chosenPlan.plan.name,
planSlug: chosenPlan.plan.slug,
price: messageOption.price,
sendTime: message.updatedAt,
isCurrentUser: isCurrentUserAuthor,
),
VisibilityDetector(
key: Key(message.id.toString()),
onVisibilityChanged: (VisibilityInfo info) {
if (!message.isRead && !isCurrentUserAuthor && info.visibleFraction > 0) {
unreadMessagesIds.add((id: message.id, index: index));
EasyDebounce.debounce('mark_as_read', const Duration(milliseconds: 500), () async {
final result = await context.read<ChatRoomCubit>().markMessagesAsRead(state.chatRoom.id, unreadMessagesIds);
if (!result) return;
if (!context.mounted) return;
context.read<ChatsCubit>().reduceUnreadMessagesCount(chatId: state.chatRoom.id, count: unreadMessagesIds.length);
unreadMessagesIds.clear();
});
}
},
child: ChatBubbleWidget(
isRead: message.isRead,
sendTime: message.updatedAt,
text: message.data.trim(),
isCurrentUser: isCurrentUserAuthor,
mediaData: message.mediaData ?? [],
messageState: message.messageState,
messageUuid: message.uuid ?? '',
userSlug: state.chatRoom.users.receiver.slug,
messageType: message.type,
isConsultant: amIConsultant,
),
),
],
);
},
itemCount: state.chatMessages.length + (state.isLoading ? 1 : 0),