You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			981 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			981 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Dart
		
	
import 'dart:developer';
 | 
						|
 | 
						|
import 'package:cached_network_image/cached_network_image.dart';
 | 
						|
import 'package:easy_localization/easy_localization.dart' as lcl;
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:mc_common_app/classes/app_state.dart';
 | 
						|
import 'package:mc_common_app/classes/consts.dart';
 | 
						|
import 'package:mc_common_app/config/routes.dart';
 | 
						|
import 'package:mc_common_app/extensions/int_extensions.dart';
 | 
						|
import 'package:mc_common_app/extensions/string_extensions.dart';
 | 
						|
import 'package:mc_common_app/generated/locale_keys.g.dart';
 | 
						|
import 'package:mc_common_app/models/chat_models/chat_message_model.dart';
 | 
						|
import 'package:mc_common_app/models/requests_models/request_model.dart';
 | 
						|
import 'package:mc_common_app/theme/colors.dart';
 | 
						|
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
 | 
						|
import 'package:mc_common_app/utils/enums.dart';
 | 
						|
import 'package:mc_common_app/utils/navigator.dart';
 | 
						|
import 'package:mc_common_app/utils/utils.dart';
 | 
						|
import 'package:mc_common_app/view_models/ad_view_model.dart';
 | 
						|
import 'package:mc_common_app/view_models/chat_view_model.dart';
 | 
						|
import 'package:mc_common_app/view_models/requests_view_model.dart';
 | 
						|
import 'package:mc_common_app/views/chat/widgets/chat_bottom_sheets.dart';
 | 
						|
import 'package:mc_common_app/views/requests/request_bottomsheets.dart';
 | 
						|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
 | 
						|
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
 | 
						|
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
 | 
						|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
 | 
						|
import 'package:mc_common_app/widgets/txt_field.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
 | 
						|
class ChatMessageCustomWidget extends StatefulWidget {
 | 
						|
  final ChatMessageModel chatMessageModel;
 | 
						|
  final RequestStatusEnum? requestStatusEnum;
 | 
						|
  final ChatTypeEnum chatTypeEnum;
 | 
						|
  final RequestsTypeEnum requestsTypeEnum;
 | 
						|
  final RequestModel? requestModel;
 | 
						|
 | 
						|
  const ChatMessageCustomWidget({
 | 
						|
    super.key,
 | 
						|
    required this.chatMessageModel,
 | 
						|
    required this.requestStatusEnum,
 | 
						|
    required this.chatTypeEnum,
 | 
						|
    this.requestModel,
 | 
						|
    this.requestsTypeEnum = RequestsTypeEnum.specialCarRequest,
 | 
						|
  });
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ChatMessageCustomWidget> createState() => _ChatMessageCustomWidgetState();
 | 
						|
}
 | 
						|
 | 
						|
class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
 | 
						|
  Future buildDealNotCompletedBottomSheetOptions({required ChatMessageModel chatMessageModel}) {
 | 
						|
    return showModalBottomSheet(
 | 
						|
      context: context,
 | 
						|
      isScrollControlled: true,
 | 
						|
      enableDrag: true,
 | 
						|
      builder: (BuildContext context) {
 | 
						|
        return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
 | 
						|
          return InfoBottomSheet(
 | 
						|
              title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
 | 
						|
              description: Padding(
 | 
						|
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
						|
                child: Column(
 | 
						|
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                  children: [
 | 
						|
                    12.height,
 | 
						|
                    ListView.separated(
 | 
						|
                      shrinkWrap: true,
 | 
						|
                      itemCount: chatVM.offerRejectModelList.length,
 | 
						|
                      separatorBuilder: (BuildContext context, int index) {
 | 
						|
                        bool indexContains = chatVM.indexesForDealNotCompleted.indexWhere((i) => i == index) != -1;
 | 
						|
                        if ((!indexContains)) {
 | 
						|
                          return const SizedBox();
 | 
						|
                        }
 | 
						|
 | 
						|
                        return const Divider(thickness: 0.5);
 | 
						|
                      },
 | 
						|
                      itemBuilder: (BuildContext context, int index) {
 | 
						|
                        bool indexContains = chatVM.indexesForDealNotCompleted.indexWhere((i) => i == index) != -1;
 | 
						|
 | 
						|
                        if (!indexContains) {
 | 
						|
                          return const SizedBox();
 | 
						|
                        }
 | 
						|
 | 
						|
                        OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index];
 | 
						|
                        return CircleCheckBoxWithTitle(
 | 
						|
                          isChecked: offerRequestCommentModel.isSelected ?? false,
 | 
						|
                          title: '${offerRequestCommentModel.title}',
 | 
						|
                          onSelected: () {
 | 
						|
                            chatVM.updateSelectionInOfferRejectModelList(index);
 | 
						|
                          },
 | 
						|
                          selectedColor: MyColors.darkPrimaryColor,
 | 
						|
                        );
 | 
						|
                      },
 | 
						|
                    ),
 | 
						|
                    if (chatVM.offerRejectModelList.last.isSelected ?? false) ...[
 | 
						|
                      // comparing if the "other" is selected
 | 
						|
                      12.height,
 | 
						|
                      TxtField(
 | 
						|
                        maxLines: 5,
 | 
						|
                        value: chatVM.rejectOfferDescription,
 | 
						|
                        errorValue: chatVM.rejectOfferDescriptionError,
 | 
						|
                        keyboardType: TextInputType.text,
 | 
						|
                        hint: LocaleKeys.description.tr(),
 | 
						|
                        onChanged: (v) => chatVM.updateRejectOfferDescription(v),
 | 
						|
                      ),
 | 
						|
                    ],
 | 
						|
                    25.height,
 | 
						|
                    ShowFillButton(
 | 
						|
                      title: LocaleKeys.submit.tr(),
 | 
						|
                      onPressed: () async {
 | 
						|
                        String comments = "";
 | 
						|
                        if (chatVM.offerRejectModelList.last.isSelected ?? false) {
 | 
						|
                          comments = chatVM.rejectOfferDescription;
 | 
						|
                        } else {
 | 
						|
                          comments = chatVM.offerRejectModelList.firstWhere((element) => element.isSelected!).title ?? "";
 | 
						|
                        }
 | 
						|
                        if (!chatVM.isRejectOfferButtonValidated()) {
 | 
						|
                          return;
 | 
						|
                        }
 | 
						|
                        Navigator.pop(context);
 | 
						|
                        bool status = await chatVM.onSendMessageForActionOnRequestOffer(
 | 
						|
                          receiverId: (chatMessageModel.isMyMessage ?? false) ? chatMessageModel.receiverUserID ?? "" : chatMessageModel.senderUserID ?? "",
 | 
						|
                          chatMessageType: ChatMessageTypeEnum.offer,
 | 
						|
                          comments: comments,
 | 
						|
                          requestId: chatMessageModel.reqOffer!.requestID ?? -1,
 | 
						|
                          serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
 | 
						|
                          requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
 | 
						|
                          offerPrice: chatMessageModel.reqOffer!.price.toString(),
 | 
						|
                          serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
 | 
						|
                          manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
 | 
						|
                          manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
 | 
						|
                          requestOfferStatusEnum: RequestOfferStatusEnum.rejected,
 | 
						|
                          context: context,
 | 
						|
                        );
 | 
						|
 | 
						|
                        if (status) {
 | 
						|
                          final requestVM = context.read<RequestsVM>();
 | 
						|
                          chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.rejected;
 | 
						|
                          int index = chatVM.serviceProviderOffersList
 | 
						|
                              .indexWhere((element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId));
 | 
						|
 | 
						|
                          if (index != -1) {
 | 
						|
                            chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum;
 | 
						|
                          }
 | 
						|
                          setState(() {});
 | 
						|
                          chatVM.updateRejectOfferDescription('');
 | 
						|
                          Utils.showToast(LocaleKeys.offerRejected.tr());
 | 
						|
                          // navigateReplaceWithName(context, AppRoutes.dashboard);
 | 
						|
                        }
 | 
						|
                      },
 | 
						|
                      maxWidth: double.infinity,
 | 
						|
                    ),
 | 
						|
                    19.height,
 | 
						|
                  ],
 | 
						|
                ),
 | 
						|
              ));
 | 
						|
        });
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Future buildDealBottomSheetOptionsForSpecialCar({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum, required bool fromCancelOffer}) {
 | 
						|
    return showModalBottomSheet(
 | 
						|
      context: context,
 | 
						|
      isScrollControlled: true,
 | 
						|
      enableDrag: true,
 | 
						|
      builder: (BuildContext sheetContext) {
 | 
						|
        return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
 | 
						|
          return InfoBottomSheet(
 | 
						|
              title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
 | 
						|
              description: Padding(
 | 
						|
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
						|
                child: Column(
 | 
						|
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                  children: [
 | 
						|
                    Column(
 | 
						|
                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                      children: [
 | 
						|
                        12.height,
 | 
						|
                        CheckBoxWithTitleDescription(
 | 
						|
                          isSelected: chatVM.dealOptionsModelList[0].isSelected!,
 | 
						|
                          title: '${chatVM.dealOptionsModelList[0].title}',
 | 
						|
                          description: '',
 | 
						|
                          onSelection: (bool value) {
 | 
						|
                            chatVM.updateIsSelectedInDealOptionsModelList(0, value);
 | 
						|
                          },
 | 
						|
                        ),
 | 
						|
                        CheckBoxWithTitleDescription(
 | 
						|
                          isSelected: chatVM.dealOptionsModelList[1].isSelected ?? false,
 | 
						|
                          title: '${chatVM.dealOptionsModelList[1].title}',
 | 
						|
                          description: '',
 | 
						|
                          onSelection: (bool value) {
 | 
						|
                            chatVM.updateIsSelectedInDealOptionsModelList(1, value);
 | 
						|
                          },
 | 
						|
                        ),
 | 
						|
                      ],
 | 
						|
                    ),
 | 
						|
                    25.height,
 | 
						|
                    ShowFillButton(
 | 
						|
                      title: LocaleKeys.continu.tr(),
 | 
						|
                      onPressed: () async {
 | 
						|
                        pop(sheetContext);
 | 
						|
                        if (chatVM.dealOptionsModelList[0].isSelected ?? false) {
 | 
						|
                          if (fromCancelOffer) {
 | 
						|
                            final requestVM = context.read<RequestsVM>();
 | 
						|
                            return dealCompletedConsentBottomSheet(
 | 
						|
                              mainContext: context,
 | 
						|
                              requestStatusEnum: RequestStatusEnum.completed,
 | 
						|
                              requestId: requestVM.currentSelectedRequest!.id,
 | 
						|
                              showAcknowledgement: AppState().currentAppType == AppType.customer,
 | 
						|
                            );
 | 
						|
                          } else {
 | 
						|
                            final requestVM = context.read<RequestsVM>();
 | 
						|
                            return dealCompletedConsentBottomSheet(
 | 
						|
                                mainContext: context,
 | 
						|
                                requestStatusEnum: RequestStatusEnum.completed,
 | 
						|
                                requestId: requestVM.currentSelectedRequest!.id,
 | 
						|
                                showAcknowledgement: AppState().currentAppType == AppType.customer,
 | 
						|
                                acceptRequestOffer: () async {
 | 
						|
                                  bool status = await chatVM.onSendMessageForActionOnRequestOffer(
 | 
						|
                                    receiverId: chatMessageModel.senderUserID ?? "",
 | 
						|
                                    chatMessageType: ChatMessageTypeEnum.offer,
 | 
						|
                                    comments: GlobalConsts.acceptingThisOffer,
 | 
						|
                                    requestId: chatMessageModel.reqOffer!.requestID ?? -1,
 | 
						|
                                    serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
 | 
						|
                                    requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
 | 
						|
                                    offerPrice: chatMessageModel.reqOffer!.price.toString(),
 | 
						|
                                    serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
 | 
						|
                                    manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
 | 
						|
                                    manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
 | 
						|
                                    requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
 | 
						|
                                    context: context,
 | 
						|
                                  );
 | 
						|
 | 
						|
                                  if (status) {
 | 
						|
                                    chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted;
 | 
						|
                                    requestVM.currentSelectedRequest!.requestStatus = RequestStatusEnum.inProgress;
 | 
						|
                                    requestVM.updateAcceptedReqOffer(chatMessageModel.reqOffer!);
 | 
						|
                                    requestVM.updateAcceptedRequestOfferProviderName(chatMessageModel.senderName ?? "");
 | 
						|
                                    int index = chatVM.serviceProviderOffersList.indexWhere(
 | 
						|
                                        (element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId));
 | 
						|
 | 
						|
                                    if (index != -1) {
 | 
						|
                                      chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum;
 | 
						|
                                    }
 | 
						|
                                    setState(() {});
 | 
						|
                                    Utils.showToast(LocaleKeys.offerAccepted.tr());
 | 
						|
                                    return true;
 | 
						|
                                  } else {
 | 
						|
                                    return false;
 | 
						|
                                  }
 | 
						|
                                });
 | 
						|
                          }
 | 
						|
                        } else {
 | 
						|
                          if (fromCancelOffer) {
 | 
						|
                            buildRejectOrCancelOfferBottomSheet(chatMessageModel: chatMessageModel, requestOfferStatusEnum: RequestOfferStatusEnum.cancel);
 | 
						|
                          } else {
 | 
						|
                            buildDealNotCompletedBottomSheetOptions(chatMessageModel: chatMessageModel);
 | 
						|
                          }
 | 
						|
                        }
 | 
						|
                      },
 | 
						|
                      maxWidth: double.infinity,
 | 
						|
                    ),
 | 
						|
                    19.height,
 | 
						|
                  ],
 | 
						|
                ),
 | 
						|
              ));
 | 
						|
        });
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Future buildRejectOrCancelOfferBottomSheet({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum}) {
 | 
						|
    return showModalBottomSheet(
 | 
						|
      context: context,
 | 
						|
      isScrollControlled: true,
 | 
						|
      enableDrag: true,
 | 
						|
      builder: (BuildContext context) {
 | 
						|
        return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
 | 
						|
          String title = "";
 | 
						|
          if (requestOfferStatusEnum == RequestOfferStatusEnum.cancel) {
 | 
						|
            title = LocaleKeys.dealNotCompleted.tr();
 | 
						|
          } else {
 | 
						|
            title = LocaleKeys.pleaseSpecify.tr();
 | 
						|
          }
 | 
						|
          return InfoBottomSheet(
 | 
						|
              title: title.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
 | 
						|
              description: Padding(
 | 
						|
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
						|
                child: Column(
 | 
						|
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                  children: [
 | 
						|
                    Column(
 | 
						|
                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                      children: [
 | 
						|
                        12.height,
 | 
						|
                        ListView.separated(
 | 
						|
                          shrinkWrap: true,
 | 
						|
                          itemCount: chatVM.offerRejectModelList.length,
 | 
						|
                          separatorBuilder: (BuildContext context, int index) {
 | 
						|
                            bool indexContainsInCancel = widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest
 | 
						|
                                ? (chatVM.indexesForCancelSpecialCarOffer.indexWhere((i) => i == index) != -1)
 | 
						|
                                : (chatVM.indexesForCancelSparePartOffer.indexWhere((i) => i == index) != -1);
 | 
						|
                            bool indexContainsInReject = chatVM.indexesForRejectOffer.indexWhere((i) => i == index) != -1;
 | 
						|
                            if ((!indexContainsInCancel) && requestOfferStatusEnum == RequestOfferStatusEnum.cancel) {
 | 
						|
                              return const SizedBox();
 | 
						|
                            }
 | 
						|
 | 
						|
                            if ((!indexContainsInReject) && requestOfferStatusEnum == RequestOfferStatusEnum.rejected) {
 | 
						|
                              return const SizedBox();
 | 
						|
                            }
 | 
						|
                            return const Divider(thickness: 0.5);
 | 
						|
                          },
 | 
						|
                          itemBuilder: (BuildContext context, int index) {
 | 
						|
                            bool indexContainsInCancel = widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest
 | 
						|
                                ? (chatVM.indexesForCancelSpecialCarOffer.indexWhere((i) => i == index) != -1)
 | 
						|
                                : (chatVM.indexesForCancelSparePartOffer.indexWhere((i) => i == index) != -1);
 | 
						|
                            bool indexContainsInReject = chatVM.indexesForRejectOffer.indexWhere((i) => i == index) != -1;
 | 
						|
 | 
						|
                            if ((!indexContainsInCancel) && requestOfferStatusEnum == RequestOfferStatusEnum.cancel) {
 | 
						|
                              return const SizedBox();
 | 
						|
                            }
 | 
						|
 | 
						|
                            if ((!indexContainsInReject) && requestOfferStatusEnum == RequestOfferStatusEnum.rejected) {
 | 
						|
                              return const SizedBox();
 | 
						|
                            }
 | 
						|
                            OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index];
 | 
						|
                            return CircleCheckBoxWithTitle(
 | 
						|
                              isChecked: offerRequestCommentModel.isSelected ?? false,
 | 
						|
                              title: '${offerRequestCommentModel.title}',
 | 
						|
                              onSelected: () {
 | 
						|
                                chatVM.updateSelectionInOfferRejectModelList(index);
 | 
						|
                              },
 | 
						|
                              selectedColor: MyColors.darkPrimaryColor,
 | 
						|
                            );
 | 
						|
                          },
 | 
						|
                        ),
 | 
						|
                        if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) ...[
 | 
						|
                          // comparing if the "other" is selected
 | 
						|
                          12.height,
 | 
						|
                          TxtField(
 | 
						|
                            maxLines: 5,
 | 
						|
                            value: chatVM.rejectOfferDescription,
 | 
						|
                            errorValue: chatVM.rejectOfferDescriptionError,
 | 
						|
                            keyboardType: TextInputType.text,
 | 
						|
                            hint: LocaleKeys.description.tr(),
 | 
						|
                            onChanged: (v) => chatVM.updateRejectOfferDescription(v),
 | 
						|
                          ),
 | 
						|
                        ],
 | 
						|
                      ],
 | 
						|
                    ),
 | 
						|
                    25.height,
 | 
						|
                    ShowFillButton(
 | 
						|
                      title: LocaleKeys.submit.tr(),
 | 
						|
                      onPressed: () async {
 | 
						|
                        String comments = "";
 | 
						|
                        if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) //Other
 | 
						|
                        {
 | 
						|
                          comments = chatVM.rejectOfferDescription;
 | 
						|
                        } else {
 | 
						|
                          comments = chatVM.selectedOfferRequestCommentModel.title ?? "";
 | 
						|
                        }
 | 
						|
                        if (!chatVM.isRejectOfferButtonValidated()) {
 | 
						|
                          return;
 | 
						|
                        }
 | 
						|
                        Navigator.pop(context);
 | 
						|
                        bool status = await chatVM.onSendMessageForActionOnRequestOffer(
 | 
						|
                          receiverId: (chatMessageModel.isMyMessage ?? false) ? chatMessageModel.receiverUserID ?? "" : chatMessageModel.senderUserID ?? "",
 | 
						|
                          chatMessageType: ChatMessageTypeEnum.offer,
 | 
						|
                          comments: comments,
 | 
						|
                          requestId: chatMessageModel.reqOffer!.requestID ?? -1,
 | 
						|
                          serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
 | 
						|
                          requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
 | 
						|
                          offerPrice: chatMessageModel.reqOffer!.price.toString(),
 | 
						|
                          serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
 | 
						|
                          manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
 | 
						|
                          manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
 | 
						|
                          requestOfferStatusEnum: requestOfferStatusEnum,
 | 
						|
                          context: context,
 | 
						|
                        );
 | 
						|
 | 
						|
                        if (status) {
 | 
						|
                          final requestVM = context.read<RequestsVM>();
 | 
						|
                          chatMessageModel.reqOffer!.requestOfferStatusEnum = requestOfferStatusEnum;
 | 
						|
                          int index = chatVM.serviceProviderOffersList
 | 
						|
                              .indexWhere((element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId));
 | 
						|
 | 
						|
                          if (index != -1) {
 | 
						|
                            chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum;
 | 
						|
                          }
 | 
						|
                          setState(() {});
 | 
						|
                          // Navigator.pop(context);
 | 
						|
                          chatVM.updateRejectOfferDescription('');
 | 
						|
                          Utils.showToast("Offer ${requestOfferStatusEnum == RequestOfferStatusEnum.rejected ? "Rejected" : "Cancelled"}");
 | 
						|
                          // navigateReplaceWithName(context, AppRoutes.dashboard);
 | 
						|
                        }
 | 
						|
                      },
 | 
						|
                      maxWidth: double.infinity,
 | 
						|
                    ),
 | 
						|
                    19.height,
 | 
						|
                  ],
 | 
						|
                ),
 | 
						|
              ));
 | 
						|
        });
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  void offerAcceptConfirmationBottomSheet({required ChatMessageModel chatMessageModel}) {
 | 
						|
    return actionConfirmationBottomSheet(
 | 
						|
      context: context,
 | 
						|
      title: LocaleKeys.acceptOfferConfirmation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
 | 
						|
      subtitle: LocaleKeys.acceptOfferConfirmationMessage.tr(),
 | 
						|
      actionButtonYes: Expanded(
 | 
						|
        child: ShowFillButton(
 | 
						|
          maxHeight: 55,
 | 
						|
          title: LocaleKeys.yes.tr(),
 | 
						|
          fontSize: 15,
 | 
						|
          onPressed: () async {
 | 
						|
            Navigator.pop(context);
 | 
						|
            bool status = await context.read<ChatVM>().onSendMessageForActionOnRequestOffer(
 | 
						|
                  receiverId: chatMessageModel.senderUserID ?? "",
 | 
						|
                  chatMessageType: ChatMessageTypeEnum.offer,
 | 
						|
                  comments: GlobalConsts.acceptingThisOffer,
 | 
						|
                  requestId: chatMessageModel.reqOffer!.requestID ?? -1,
 | 
						|
                  serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
 | 
						|
                  requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
 | 
						|
                  offerPrice: chatMessageModel.reqOffer!.price.toString(),
 | 
						|
                  serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
 | 
						|
                  manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
 | 
						|
                  manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
 | 
						|
                  requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
 | 
						|
                  context: context,
 | 
						|
                );
 | 
						|
 | 
						|
            if (status) {
 | 
						|
              final requestVM = context.read<RequestsVM>();
 | 
						|
              ChatVM chatVM = context.read<ChatVM>();
 | 
						|
 | 
						|
              chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted;
 | 
						|
              requestVM.currentSelectedRequest!.requestStatus = RequestStatusEnum.inProgress;
 | 
						|
              requestVM.updateAcceptedReqOffer(chatMessageModel.reqOffer!);
 | 
						|
              requestVM.updateAcceptedRequestOfferProviderName(chatMessageModel.senderName ?? "");
 | 
						|
              int index = chatVM.serviceProviderOffersList
 | 
						|
                  .indexWhere((element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId));
 | 
						|
 | 
						|
              if (index != -1) {
 | 
						|
                chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum;
 | 
						|
              }
 | 
						|
              setState(() {});
 | 
						|
              // Navigator.pop(context);
 | 
						|
              Utils.showToast(LocaleKeys.offerAccepted.tr());
 | 
						|
              // navigateReplaceWithName(context, AppRoutes.dashboard);
 | 
						|
            }
 | 
						|
          },
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
      actionButtonNo: Expanded(
 | 
						|
        child: ShowFillButton(
 | 
						|
          maxHeight: 55,
 | 
						|
          isFilled: false,
 | 
						|
          borderColor: MyColors.darkPrimaryColor,
 | 
						|
          title: LocaleKeys.no.tr(),
 | 
						|
          txtColor: MyColors.darkPrimaryColor,
 | 
						|
          fontSize: 15,
 | 
						|
          onPressed: () {
 | 
						|
            Navigator.pop(context);
 | 
						|
          },
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget buildImagesInOffer(List<MessageImageModel> offerImages, bool isMyMessage) {
 | 
						|
    int imageCount = offerImages.length;
 | 
						|
    return SizedBox(
 | 
						|
      height: 50,
 | 
						|
      child: ListView.builder(
 | 
						|
          scrollDirection: Axis.horizontal,
 | 
						|
          itemCount: imageCount,
 | 
						|
          itemBuilder: (BuildContext context, int index) {
 | 
						|
            Widget widget = const SizedBox();
 | 
						|
            if ((offerImages[index].isFromNetwork ?? false)) {
 | 
						|
              widget = offerImages[index].imageUrl.buildNetworkImage(fit: BoxFit.cover, width: 50);
 | 
						|
            } else {
 | 
						|
              widget = offerImages[index].imagePath.buildFileImage(fit: BoxFit.cover, width: 50);
 | 
						|
            }
 | 
						|
            return Container(
 | 
						|
                    decoration: BoxDecoration(
 | 
						|
                      borderRadius: BorderRadius.circular(5), // Optional: Rounded corners
 | 
						|
                    ),
 | 
						|
                    child: ClipRRect(borderRadius: BorderRadius.circular(5), child: widget))
 | 
						|
                .paddingOnly(left: isMyMessage ? 10 : 0, right: isMyMessage ? 0 : 10)
 | 
						|
                .onPress(() => navigateWithName(context, AppRoutes.mediaViewerScreen, arguments: offerImages));
 | 
						|
          }),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget buildOfferDetailsInChatMessage({required RequestStatusEnum requestStatusEnum, required ChatMessageModel chatMessageModel, required BuildContext context}) {
 | 
						|
    final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer;
 | 
						|
    if (requestStatusEnum != RequestStatusEnum.submitted && requestOfferStatusEnum != RequestOfferStatusEnum.accepted) {
 | 
						|
      return Column(
 | 
						|
        children: [
 | 
						|
          Row(
 | 
						|
            crossAxisAlignment: CrossAxisAlignment.end,
 | 
						|
            children: [
 | 
						|
              "${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}".toText(fontSize: 19, isBold: true, color: chatMessageModel.isMyMessage! ? MyColors.white : MyColors.darkTextColor),
 | 
						|
              5.width,
 | 
						|
              LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
 | 
						|
            ],
 | 
						|
          ),
 | 
						|
          5.height,
 | 
						|
          Center(
 | 
						|
            child: LocaleKeys.offerNoLongerAvailable.tr().toText(
 | 
						|
                  color: chatMessageModel.isMyMessage! ? MyColors.adPendingStatusColor : MyColors.lightTextColor,
 | 
						|
                  fontSize: 12,
 | 
						|
                  isItalic: true,
 | 
						|
                ),
 | 
						|
          ).toContainer(
 | 
						|
              borderRadius: 40, width: double.infinity, backgroundColor: chatMessageModel.isMyMessage! ? MyColors.adPendingStatusColor.withOpacity(0.16) : MyColors.grey98Color.withOpacity(0.1)),
 | 
						|
        ],
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    switch (requestOfferStatusEnum) {
 | 
						|
      case RequestOfferStatusEnum.offer:
 | 
						|
        return Column(
 | 
						|
          children: [
 | 
						|
            5.height,
 | 
						|
            Row(
 | 
						|
              crossAxisAlignment: CrossAxisAlignment.end,
 | 
						|
              children: [
 | 
						|
                "${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}"
 | 
						|
                    .toText(fontSize: 19, isBold: true, color: AppState().currentAppType == AppType.provider ? MyColors.white : MyColors.darkTextColor),
 | 
						|
                5.width,
 | 
						|
                LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
            if (widget.chatMessageModel.isMyMessage == false) ...[
 | 
						|
              10.height,
 | 
						|
              Row(
 | 
						|
                children: [
 | 
						|
                  Expanded(
 | 
						|
                    child: ShowFillButton(
 | 
						|
                      maxHeight: 27,
 | 
						|
                      title: LocaleKeys.accept.tr(),
 | 
						|
                      fontSize: 9,
 | 
						|
                      borderColor: MyColors.greenColor,
 | 
						|
                      isFilled: false,
 | 
						|
                      onPressed: () {
 | 
						|
                        if (widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest) {
 | 
						|
                          buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum, fromCancelOffer: false);
 | 
						|
                        } else {
 | 
						|
                          offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel);
 | 
						|
                        }
 | 
						|
                      },
 | 
						|
                      backgroundColor: MyColors.white,
 | 
						|
                      txtColor: MyColors.greenColor,
 | 
						|
                    ),
 | 
						|
                  ),
 | 
						|
                  20.width,
 | 
						|
                  Expanded(
 | 
						|
                    child: ShowFillButton(
 | 
						|
                      maxHeight: 27,
 | 
						|
                      title: LocaleKeys.reject.tr(),
 | 
						|
                      borderColor: MyColors.redColor,
 | 
						|
                      isFilled: false,
 | 
						|
                      backgroundColor: MyColors.white,
 | 
						|
                      txtColor: MyColors.redColor,
 | 
						|
                      fontSize: 9,
 | 
						|
                      onPressed: () {
 | 
						|
                        buildRejectOrCancelOfferBottomSheet(chatMessageModel: chatMessageModel, requestOfferStatusEnum: RequestOfferStatusEnum.rejected);
 | 
						|
                      },
 | 
						|
                    ),
 | 
						|
                  )
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
            ] else if (requestStatusEnum == RequestStatusEnum.submitted) ...[
 | 
						|
              10.height,
 | 
						|
              Row(
 | 
						|
                children: [
 | 
						|
                  if (widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest) ...[
 | 
						|
                    Expanded(
 | 
						|
                      child: ShowFillButton(
 | 
						|
                        maxHeight: 27,
 | 
						|
                        title: LocaleKeys.more.tr(),
 | 
						|
                        fontSize: 9,
 | 
						|
                        borderColor: MyColors.lightTextColor,
 | 
						|
                        isFilled: false,
 | 
						|
                        onPressed: () {
 | 
						|
                          buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum, fromCancelOffer: true);
 | 
						|
                        },
 | 
						|
                        backgroundColor: MyColors.white,
 | 
						|
                        txtColor: MyColors.lightTextColor,
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                    20.width,
 | 
						|
                  ],
 | 
						|
                  Expanded(
 | 
						|
                    child: ShowFillButton(
 | 
						|
                      maxHeight: 27,
 | 
						|
                      title: LocaleKeys.cancelOffer.tr(),
 | 
						|
                      fontSize: 9,
 | 
						|
                      borderColor: MyColors.lightTextColor,
 | 
						|
                      isFilled: false,
 | 
						|
                      onPressed: () {
 | 
						|
                        buildRejectOrCancelOfferBottomSheet(chatMessageModel: chatMessageModel, requestOfferStatusEnum: RequestOfferStatusEnum.cancel);
 | 
						|
                      },
 | 
						|
                      backgroundColor: MyColors.white,
 | 
						|
                      txtColor: MyColors.lightTextColor,
 | 
						|
                    ),
 | 
						|
                  ),
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
            ],
 | 
						|
          ],
 | 
						|
        );
 | 
						|
      case RequestOfferStatusEnum.negotiate:
 | 
						|
        return Column(
 | 
						|
          children: [
 | 
						|
            Center(
 | 
						|
              child: LocaleKeys.newOfferRequired.tr().toText(
 | 
						|
                    color: MyColors.adPendingStatusColor,
 | 
						|
                    fontSize: 12,
 | 
						|
                    isItalic: true,
 | 
						|
                  ),
 | 
						|
            ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
 | 
						|
          ],
 | 
						|
        );
 | 
						|
      case RequestOfferStatusEnum.accepted:
 | 
						|
        return Column(
 | 
						|
          children: [
 | 
						|
            Row(
 | 
						|
              crossAxisAlignment: CrossAxisAlignment.end,
 | 
						|
              children: [
 | 
						|
                "${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}".toText(fontSize: 19, isBold: true, color: chatMessageModel.isMyMessage! ? MyColors.white : MyColors.darkTextColor),
 | 
						|
                5.width,
 | 
						|
                LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
            5.height,
 | 
						|
            Center(
 | 
						|
              child: LocaleKeys.offerHasBeenAccepted.tr().toText(
 | 
						|
                    color: MyColors.adPendingStatusColor,
 | 
						|
                    fontSize: 12,
 | 
						|
                    isItalic: true,
 | 
						|
                  ),
 | 
						|
            ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
 | 
						|
          ],
 | 
						|
        );
 | 
						|
      case RequestOfferStatusEnum.rejected:
 | 
						|
        return Column(
 | 
						|
          children: [
 | 
						|
            Row(
 | 
						|
              crossAxisAlignment: CrossAxisAlignment.end,
 | 
						|
              children: [
 | 
						|
                "${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}".toText(fontSize: 19, isBold: true, color: chatMessageModel.isMyMessage! ? MyColors.white : MyColors.darkTextColor),
 | 
						|
                5.width,
 | 
						|
                LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
            5.height,
 | 
						|
            Center(
 | 
						|
              child: LocaleKeys.offerHasBeenRejected.tr().toText(
 | 
						|
                    color: MyColors.adPendingStatusColor,
 | 
						|
                    fontSize: 12,
 | 
						|
                    isItalic: true,
 | 
						|
                  ),
 | 
						|
            ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
 | 
						|
          ],
 | 
						|
        );
 | 
						|
      case RequestOfferStatusEnum.cancel:
 | 
						|
        return Column(
 | 
						|
          children: [
 | 
						|
            Row(
 | 
						|
              crossAxisAlignment: CrossAxisAlignment.end,
 | 
						|
              children: [
 | 
						|
                "${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}".toText(fontSize: 19, isBold: true, color: chatMessageModel.isMyMessage! ? MyColors.white : MyColors.darkTextColor),
 | 
						|
                5.width,
 | 
						|
                LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
            5.height,
 | 
						|
            Center(
 | 
						|
              child: LocaleKeys.offerHasBeenCancelled.tr().toText(
 | 
						|
                    color: MyColors.adPendingStatusColor,
 | 
						|
                    fontSize: 12,
 | 
						|
                    isItalic: true,
 | 
						|
                  ),
 | 
						|
            ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
 | 
						|
          ],
 | 
						|
        );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Widget getProfilePicture({String profileImageUrl = ""}) {
 | 
						|
    Widget widget = const SizedBox();
 | 
						|
 | 
						|
    if (profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userLocalImage != null) {
 | 
						|
      widget = Image.file(
 | 
						|
        AppState().getUser.data!.userInfo!.userLocalImage!,
 | 
						|
        width: 34,
 | 
						|
        height: 34,
 | 
						|
        fit: BoxFit.fill,
 | 
						|
      );
 | 
						|
    } else if (profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userImageUrl != null) {
 | 
						|
      widget = CachedNetworkImage(
 | 
						|
          imageUrl: AppState().getUser.data!.userInfo!.userImageUrl,
 | 
						|
          imageBuilder: (context, imageProvider) => Container(
 | 
						|
                decoration: BoxDecoration(
 | 
						|
                  image: DecorationImage(
 | 
						|
                    image: imageProvider,
 | 
						|
                    fit: BoxFit.cover,
 | 
						|
                  ),
 | 
						|
                ),
 | 
						|
              ),
 | 
						|
          placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
 | 
						|
          errorWidget: (context, url, error) => const Icon(Icons.supervised_user_circle_outlined),
 | 
						|
          fadeInCurve: Curves.easeIn,
 | 
						|
          width: 34,
 | 
						|
          height: 34,
 | 
						|
          fit: BoxFit.fill,
 | 
						|
          fadeInDuration: const Duration(milliseconds: 1000),
 | 
						|
          useOldImageOnUrlChange: false);
 | 
						|
    }
 | 
						|
    return widget.toCircle(borderRadius: 100);
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> onOfferEditIconPressed() async {
 | 
						|
    int index = context.read<RequestsVM>().myFilteredRequests.indexWhere((request) => request.id == widget.requestModel!.id);
 | 
						|
    RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(
 | 
						|
      requestIndex: index, // Not getting used in case of update offer
 | 
						|
      requestModel: widget.requestModel!,
 | 
						|
    );
 | 
						|
    RequestsVM requestVM = context.read<RequestsVM>();
 | 
						|
    requestVM.resetSendOfferBottomSheet();
 | 
						|
    ReqOffer offer = widget.chatMessageModel.reqOffer!;
 | 
						|
    requestVM.updateOfferPrice((offer.price ?? "").toString());
 | 
						|
    requestVM.updateServiceItem((offer.serviceItemName ?? "").toString());
 | 
						|
    requestVM.updateItemManufacturer((offer.manufacturedByName ?? "").toString());
 | 
						|
    requestVM.updateServiceItemCreatedOn((offer.manufacturedOn ?? "").toString());
 | 
						|
    requestVM.updateOfferDescription((widget.chatMessageModel.chatText ?? "").toString());
 | 
						|
    requestVM.updateIsDeliveryAvailableStatus((offer.isDeliveryAvailable ?? false));
 | 
						|
    if (offer.reqOfferImages != null && offer.reqOfferImages!.isNotEmpty) {
 | 
						|
      for (var element in offer.reqOfferImages!) {
 | 
						|
        if (element.imageUrl != null || element.imageStr != null) {
 | 
						|
          ImageModel imageModel = ImageModel(
 | 
						|
              id: element.id,
 | 
						|
              filePath: element.imageStr != null && element.imageStr!.isNotEmpty ? element.imageStr : element.imageUrl,
 | 
						|
              isFromNetwork: element.imageStr != null && element.imageStr!.isNotEmpty ? false : true);
 | 
						|
          requestVM.addImageToPickedVehicleImages(imageModel);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    buildSendOfferBottomSheet(context: context, requestDetailPageArguments: requestDetailArguments, isFromChatScreen: true, offerId: offer.id);
 | 
						|
  }
 | 
						|
 | 
						|
  Widget buildFreeTextDetailsInMessage({required ChatMessageTypeEnum chatMessageTypeEnum}) {
 | 
						|
    return Row(
 | 
						|
      children: [
 | 
						|
        if (chatMessageTypeEnum == ChatMessageTypeEnum.offer && (widget.chatMessageModel.isMyMessage == true) && (widget.chatMessageModel.isRead ?? false)) ...[
 | 
						|
          Row(
 | 
						|
            children: [
 | 
						|
              const Icon(Icons.remove_red_eye_outlined, size: 12, color: MyColors.lightTextColor),
 | 
						|
              4.width,
 | 
						|
              LocaleKeys.viewed.tr().toText(fontSize: 10, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),
 | 
						|
            ],
 | 
						|
          ),
 | 
						|
        ] else if (AppState().currentAppType == AppType.provider &&
 | 
						|
            chatMessageTypeEnum == ChatMessageTypeEnum.offer &&
 | 
						|
            widget.chatMessageModel.reqOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.offer &&
 | 
						|
            (widget.chatMessageModel.isMyMessage == true && widget.chatMessageModel.reqOffer != null && widget.chatMessageModel.reqOffer!.id != null)) ...[
 | 
						|
          MyAssets.icEdit.buildSvg(color: MyColors.white, height: 15).onPress(() => onOfferEditIconPressed()),
 | 
						|
        ],
 | 
						|
        Expanded(
 | 
						|
          child: Directionality(
 | 
						|
            textDirection: TextDirection.ltr,
 | 
						|
            child: (widget.chatMessageModel.chatText ?? "").toText(
 | 
						|
              color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
 | 
						|
              fontSize: 12,
 | 
						|
            ),
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ],
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget buildImageGridWidget({required List<MessageImageModel> messagesImages, double gridItemSize = 50.0, double spacing = 8.0, double borderWidth = 1, Color borderColor = MyColors.textColor}) {
 | 
						|
    int imageCount = messagesImages.length;
 | 
						|
    if (imageCount == 1) {
 | 
						|
      return Container(
 | 
						|
        width: double.infinity,
 | 
						|
        height: (gridItemSize * 4),
 | 
						|
        decoration: BoxDecoration(
 | 
						|
          border: Border.all(width: borderWidth, color: borderColor),
 | 
						|
          borderRadius: BorderRadius.circular(8),
 | 
						|
        ),
 | 
						|
        child: ClipRRect(
 | 
						|
          borderRadius: BorderRadius.circular(8),
 | 
						|
          child: (messagesImages[0].isFromNetwork ?? false)
 | 
						|
              ? messagesImages[0].imageUrl.buildNetworkImage(
 | 
						|
                    fit: BoxFit.cover,
 | 
						|
                  )
 | 
						|
              : messagesImages[0].imagePath.buildFileImage(fit: BoxFit.cover),
 | 
						|
        ),
 | 
						|
      ).onPress(() {
 | 
						|
        navigateWithName(context, AppRoutes.mediaViewerScreen, arguments: messagesImages);
 | 
						|
      });
 | 
						|
    }
 | 
						|
    return SizedBox(
 | 
						|
// height: (gridItemSize * 2) + (spacing * 2), // Fixed height for 2 rows including spacing
 | 
						|
      child: GridView.builder(
 | 
						|
        physics: const NeverScrollableScrollPhysics(),
 | 
						|
// Prevent scrolling inside grid
 | 
						|
        shrinkWrap: true,
 | 
						|
// Shrink size to fit the content
 | 
						|
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
						|
          crossAxisCount: 2, // Show 2 images per row
 | 
						|
          crossAxisSpacing: spacing,
 | 
						|
          mainAxisSpacing: spacing,
 | 
						|
          childAspectRatio: 1, // Keep items square
 | 
						|
        ),
 | 
						|
        itemCount: imageCount > 4 ? 4 : imageCount,
 | 
						|
        itemBuilder: (context, index) {
 | 
						|
          if (index == 3 && imageCount > 4) {
 | 
						|
            return Stack(
 | 
						|
              fit: StackFit.expand,
 | 
						|
              children: [
 | 
						|
                (messagesImages[index].isFromNetwork ?? false)
 | 
						|
                    ? messagesImages[index].imageUrl.buildNetworkImage(
 | 
						|
                          fit: BoxFit.cover,
 | 
						|
                          width: gridItemSize,
 | 
						|
                          height: gridItemSize,
 | 
						|
                        )
 | 
						|
                    : messagesImages[index].imagePath.buildFileImage(
 | 
						|
                          fit: BoxFit.cover,
 | 
						|
                          width: gridItemSize,
 | 
						|
                          height: gridItemSize,
 | 
						|
                        ),
 | 
						|
                Container(
 | 
						|
                  decoration: BoxDecoration(
 | 
						|
                    color: Colors.black.withOpacity(0.5),
 | 
						|
                    border: Border.all(width: borderWidth, color: borderColor),
 | 
						|
                    borderRadius: BorderRadius.circular(8), // Optional: Rounded corners
 | 
						|
                  ),
 | 
						|
                  child: Center(
 | 
						|
                    child: '+${imageCount - 4}'.toText(fontSize: 30, color: MyColors.white, fontWeight: MyFonts.Medium),
 | 
						|
                  ),
 | 
						|
                ),
 | 
						|
              ],
 | 
						|
            ).onPress(() {
 | 
						|
              navigateWithName(context, AppRoutes.mediaViewerScreen, arguments: messagesImages);
 | 
						|
            });
 | 
						|
          } else {
 | 
						|
            return Container(
 | 
						|
              width: gridItemSize,
 | 
						|
              height: gridItemSize,
 | 
						|
              decoration: BoxDecoration(
 | 
						|
                border: Border.all(width: borderWidth, color: borderColor),
 | 
						|
                borderRadius: BorderRadius.circular(8), // Optional: Rounded corners
 | 
						|
              ),
 | 
						|
              child: ClipRRect(
 | 
						|
                borderRadius: BorderRadius.circular(8), // Apply same radius to image
 | 
						|
                child: (messagesImages[index].isFromNetwork ?? false)
 | 
						|
                    ? messagesImages[index].imageUrl.buildNetworkImage(
 | 
						|
                          fit: BoxFit.cover,
 | 
						|
                          width: gridItemSize,
 | 
						|
                          height: gridItemSize,
 | 
						|
                        )
 | 
						|
                    : messagesImages[index].imagePath.buildFileImage(
 | 
						|
                          fit: BoxFit.cover,
 | 
						|
                          width: gridItemSize,
 | 
						|
                          height: gridItemSize,
 | 
						|
                        ),
 | 
						|
              ),
 | 
						|
            ).onPress(() {
 | 
						|
              navigateWithName(context, AppRoutes.mediaViewerScreen, arguments: messagesImages);
 | 
						|
            });
 | 
						|
          }
 | 
						|
        },
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Widget messageWidgetBasedOnType({required ChatMessageTypeEnum? chatMessageTypeEnum}) {
 | 
						|
    Widget messageTypeWidget = const SizedBox();
 | 
						|
    if (chatMessageTypeEnum == null) {
 | 
						|
      return const SizedBox();
 | 
						|
    }
 | 
						|
    switch (chatMessageTypeEnum) {
 | 
						|
      case ChatMessageTypeEnum.freeText:
 | 
						|
        messageTypeWidget = Column(children: [buildFreeTextDetailsInMessage(chatMessageTypeEnum: chatMessageTypeEnum), 10.height]);
 | 
						|
        break;
 | 
						|
      case ChatMessageTypeEnum.image:
 | 
						|
        messageTypeWidget = buildImageGridWidget(messagesImages: widget.chatMessageModel.messageImages ?? []);
 | 
						|
        break;
 | 
						|
      case ChatMessageTypeEnum.audio:
 | 
						|
      case ChatMessageTypeEnum.video:
 | 
						|
      case ChatMessageTypeEnum.file:
 | 
						|
      case ChatMessageTypeEnum.offer:
 | 
						|
        messageTypeWidget = Column(
 | 
						|
          crossAxisAlignment: (widget.chatMessageModel.isMyMessage ?? false) ? CrossAxisAlignment.end : CrossAxisAlignment.start,
 | 
						|
          children: [
 | 
						|
            buildFreeTextDetailsInMessage(chatMessageTypeEnum: chatMessageTypeEnum),
 | 
						|
            if (widget.requestsTypeEnum == RequestsTypeEnum.serviceRequest) ...[
 | 
						|
              2.height,
 | 
						|
              Directionality(
 | 
						|
                textDirection: TextDirection.ltr,
 | 
						|
                child: "${LocaleKeys.deliveryAvailable.tr()} : ${(widget.chatMessageModel.reqOffer!.isDeliveryAvailable ?? false) ? LocaleKeys.yes.tr() : LocaleKeys.no.tr()}".toText(
 | 
						|
                  fontSize: 10,
 | 
						|
                  color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
 | 
						|
                  fontWeight: MyFonts.Medium,
 | 
						|
                ),
 | 
						|
              ),
 | 
						|
            ],
 | 
						|
            if (widget.chatMessageModel.reqOffer!.reqOfferImages != null && widget.chatMessageModel.reqOffer!.reqOfferImages!.isNotEmpty) ...[
 | 
						|
              5.height,
 | 
						|
              buildImagesInOffer(widget.chatMessageModel.reqOffer!.reqOfferImages!, widget.chatMessageModel.isMyMessage ?? false),
 | 
						|
            ],
 | 
						|
            4.height,
 | 
						|
            buildOfferDetailsInChatMessage(requestStatusEnum: widget.requestStatusEnum!, chatMessageModel: widget.chatMessageModel, context: context),
 | 
						|
          ],
 | 
						|
        );
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    return messageTypeWidget.toContainer(
 | 
						|
      isShadowEnabled: !(widget.chatMessageModel.isMyMessage ?? false),
 | 
						|
      backgroundColor: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.darkIconColor : MyColors.white,
 | 
						|
      borderRadius: 0,
 | 
						|
      margin: EdgeInsets.fromLTRB((widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0, !(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return Directionality(
 | 
						|
      textDirection: (widget.chatMessageModel.isMyMessage ?? false) ? TextDirection.rtl : TextDirection.ltr,
 | 
						|
      child: Row(
 | 
						|
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
        children: [
 | 
						|
          Expanded(
 | 
						|
            flex: 1,
 | 
						|
            child: (widget.chatMessageModel.isMyMessage ?? false)
 | 
						|
                ? getProfilePicture()
 | 
						|
                : Container(
 | 
						|
                    width: 34,
 | 
						|
                    height: 34,
 | 
						|
                    alignment: Alignment.center,
 | 
						|
                    color: MyColors.darkTextColor,
 | 
						|
                    child: ((widget.chatMessageModel.senderName ?? "").getInitials()).toText(color: MyColors.white, isBold: true, fontSize: 12),
 | 
						|
                  ).toCircle(borderRadius: 100),
 | 
						|
          ),
 | 
						|
          10.width,
 | 
						|
          Expanded(
 | 
						|
            flex: 10,
 | 
						|
            child: Column(
 | 
						|
              children: [
 | 
						|
                Row(
 | 
						|
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
						|
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                  children: [
 | 
						|
                    ((widget.chatMessageModel.isMyMessage ?? false) ? LocaleKeys.you.tr() : widget.chatMessageModel.senderName ?? "").toText(
 | 
						|
                      fontSize: 16,
 | 
						|
                      isBold: true,
 | 
						|
                    ),
 | 
						|
                  ],
 | 
						|
                ),
 | 
						|
                5.height,
 | 
						|
                messageWidgetBasedOnType(chatMessageTypeEnum: widget.chatMessageModel.chatMessageTypeEnum),
 | 
						|
              ],
 | 
						|
            ),
 | 
						|
          )
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |