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.
311 lines
14 KiB
Dart
311 lines
14 KiB
Dart
import 'dart:developer';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.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/theme/colors.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/chat_view_model.dart';
|
|
import 'package:mc_common_app/view_models/payment_view_model.dart';
|
|
import 'package:mc_common_app/view_models/requests_view_model.dart';
|
|
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
|
|
import 'package:mc_common_app/views/chat/widgets/chat_bottom_sheets.dart';
|
|
import 'package:mc_common_app/views/chat/widgets/chat_message_widget.dart';
|
|
import 'package:mc_common_app/views/requests/request_bottomsheets.dart';
|
|
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
|
|
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
|
import 'package:mc_common_app/widgets/common_widgets/app_bar.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';
|
|
import 'package:easy_localization/easy_localization.dart' as lcl;
|
|
|
|
class ChatView extends StatefulWidget {
|
|
final ChatViewArguments chatViewArguments;
|
|
|
|
const ChatView({super.key, required this.chatViewArguments});
|
|
|
|
@override
|
|
State<ChatView> createState() => _ChatViewState();
|
|
}
|
|
|
|
class _ChatViewState extends State<ChatView> {
|
|
late ChatVM chatVM;
|
|
|
|
late ChatTypeEnum chatTypeEnum;
|
|
ChatViewArgumentsForRequest? chatViewArgumentsForRequest;
|
|
ChatViewArgumentsForAd? chatViewArgumentsForAd;
|
|
|
|
@override
|
|
void initState() {
|
|
chatTypeEnum = widget.chatViewArguments.chatTypeEnum;
|
|
if (chatTypeEnum == ChatTypeEnum.ads) {
|
|
chatViewArgumentsForAd = widget.chatViewArguments.chatViewArgumentsForAd;
|
|
} else if (chatTypeEnum == ChatTypeEnum.requestOffer) {
|
|
chatViewArgumentsForRequest = widget.chatViewArguments.chatViewArgumentsForRequest;
|
|
} else if (chatTypeEnum == ChatTypeEnum.general) {
|
|
// For General Chat
|
|
chatViewArgumentsForAd = widget.chatViewArguments.chatViewArgumentsForAd;
|
|
}
|
|
chatVM = context.read<ChatVM>();
|
|
chatVM.isUserOnChatScreen = true;
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
if (chatVM.scrollController.hasClients) {
|
|
chatVM.scrollChatDown();
|
|
}
|
|
});
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
chatVM.isUserOnChatScreen = false;
|
|
super.dispose();
|
|
}
|
|
|
|
Future<bool> onMessageSend({required ChatMessageTypeEnum chatMessageType}) async {
|
|
bool status = false;
|
|
if (chatTypeEnum == ChatTypeEnum.requestOffer) {
|
|
status = await chatVM.onMessageSendForRequest(
|
|
context: context,
|
|
receiverId: chatViewArgumentsForRequest!.receiverId,
|
|
message: chatVM.chatMessageText,
|
|
requestId: chatViewArgumentsForRequest!.requestId ?? 0,
|
|
chatMessageType: chatMessageType,
|
|
);
|
|
} else if (chatTypeEnum == ChatTypeEnum.ads) {
|
|
status = await chatVM.onTextMessageSendForAds(
|
|
receiverId: chatViewArgumentsForAd!.receiverUserID ?? "",
|
|
chatMessageType: ChatMessageTypeEnum.freeText,
|
|
message: chatVM.chatMessageText,
|
|
adId: chatViewArgumentsForAd!.adsID!,
|
|
context: context,
|
|
);
|
|
} else if (chatTypeEnum == ChatTypeEnum.general) {
|
|
status = await chatVM.onTextMessageSendForGeneralChat(
|
|
receiverId: chatViewArgumentsForAd!.receiverUserID ?? "",
|
|
chatMessageType: ChatMessageTypeEnum.freeText,
|
|
message: chatVM.chatMessageText,
|
|
adId: chatViewArgumentsForAd!.adsID!,
|
|
context: context,
|
|
);
|
|
}
|
|
Utils.hideLoading(context);
|
|
|
|
return status;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget? appBarHeadlines;
|
|
final requestVM = context.read<RequestsVM>();
|
|
if (chatTypeEnum == ChatTypeEnum.requestOffer &&
|
|
requestVM.currentSelectedRequest != null &&
|
|
(requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery)) {
|
|
appBarHeadlines = Container(
|
|
width: double.infinity,
|
|
color: MyColors.darkIconColor,
|
|
padding: const EdgeInsets.symmetric(horizontal: 21, vertical: 10),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
"Your Delivery / Shipping Status is: ".toText(
|
|
fontSize: 12,
|
|
color: Colors.white,
|
|
decorationColor: MyColors.white,
|
|
),
|
|
Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated).toText(
|
|
fontSize: 16,
|
|
color: Colors.white,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
return Scaffold(
|
|
appBar: CustomAppBar(title: LocaleKeys.chat.tr()),
|
|
body: Consumer2<ChatVM, RequestsVM>(builder: (BuildContext context, ChatVM chatVM, RequestsVM requestVM, Widget? child) {
|
|
List<ChatMessageModel> chatMessages = [];
|
|
if (chatTypeEnum == ChatTypeEnum.general) {
|
|
chatMessages = chatVM.currentMessagesForGeneralChat;
|
|
} else if (chatTypeEnum == ChatTypeEnum.ads) {
|
|
chatMessages = chatVM.currentMessagesForAds;
|
|
} else if (chatTypeEnum == ChatTypeEnum.requestOffer) {
|
|
if (AppState().currentAppType == AppType.customer && chatVM.serviceProviderOffersList.isNotEmpty) {
|
|
chatMessages = chatVM.serviceProviderOffersList[chatViewArgumentsForRequest!.providerIndex].chatMessages ?? [];
|
|
} else {
|
|
chatMessages = requestVM.myFilteredRequests[chatViewArgumentsForRequest!.requestIndex].chatMessages;
|
|
}
|
|
}
|
|
return Column(
|
|
children: [
|
|
if (appBarHeadlines != null) ...[
|
|
appBarHeadlines,
|
|
5.height,
|
|
],
|
|
Expanded(
|
|
child: chatMessages.isEmpty
|
|
? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22)
|
|
: ListView.separated(
|
|
controller: chatVM.scrollController,
|
|
itemCount: chatMessages.length,
|
|
separatorBuilder: (BuildContext context, int index) => 20.height,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
ChatMessageModel chatMessageModel = chatMessages[index];
|
|
return ChatMessageCustomWidget(
|
|
chatMessageModel: chatMessageModel,
|
|
requestModel: chatViewArgumentsForRequest!.requestModel!,
|
|
requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus,
|
|
chatTypeEnum: chatTypeEnum,
|
|
requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest,
|
|
);
|
|
},
|
|
).horPaddingMain(),
|
|
),
|
|
10.height,
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
if (chatTypeEnum == ChatTypeEnum.requestOffer &&
|
|
requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest &&
|
|
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress &&
|
|
AppState().currentAppType == AppType.customer) ...[
|
|
Expanded(
|
|
child: ShowFillButton(
|
|
maxWidth: double.infinity,
|
|
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
|
maxHeight: 55,
|
|
title: LocaleKeys.reviewAndPayment.tr(),
|
|
isBold: false,
|
|
onPressed: () {
|
|
context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id);
|
|
navigateWithName(context, AppRoutes.reviewRequestOffer, arguments: PaymentTypes.request);
|
|
},
|
|
),
|
|
),
|
|
// Center(
|
|
// child: LocaleKeys.requestAlreadyInProgress.tr().toText(
|
|
// textAlign: TextAlign.center,
|
|
// color: MyColors.lightTextColor,
|
|
// fontSize: 14,
|
|
// ),
|
|
// ).paddingAll(15)
|
|
] else if (chatTypeEnum == ChatTypeEnum.requestOffer &&
|
|
requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.specialCarRequest &&
|
|
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress &&
|
|
requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted &&
|
|
AppState().currentAppType == AppType.customer) ...[
|
|
Expanded(
|
|
child: ShowFillButton(
|
|
maxWidth: double.infinity,
|
|
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
|
maxHeight: 55,
|
|
title: LocaleKeys.completeDeal.tr(),
|
|
isBold: false,
|
|
onPressed: () {
|
|
return dealCompletedConfirmationBottomSheet(mainContext: context, requestStatusEnum: RequestStatusEnum.completed, requestId: requestVM.currentSelectedRequest!.id);
|
|
},
|
|
),
|
|
),
|
|
] else ...[
|
|
if (AppState().currentAppType == AppType.provider &&
|
|
chatTypeEnum == ChatTypeEnum.requestOffer &&
|
|
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted &&
|
|
chatVM.pickedImagesForMessage.isEmpty) ...[
|
|
Expanded(
|
|
flex: 1,
|
|
child: const Icon(
|
|
Icons.local_offer_rounded,
|
|
color: MyColors.darkPrimaryColor,
|
|
size: 30,
|
|
).onPress(
|
|
() {
|
|
RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(
|
|
requestIndex: chatViewArgumentsForRequest!.requestIndex,
|
|
requestModel: chatViewArgumentsForRequest!.requestModel!,
|
|
);
|
|
buildSendOfferBottomSheet(
|
|
context: context,
|
|
requestDetailPageArguments: requestDetailArguments,
|
|
isFromChatScreen: true,
|
|
offerId: null, // null means creating new offer
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
if (chatVM.pickedImagesForMessage.isNotEmpty) ...[
|
|
Expanded(
|
|
flex: 8,
|
|
child: PickedFilesContainer(
|
|
pickedFiles: chatVM.pickedImagesForMessage,
|
|
onCrossPressedPrimary: chatVM.removeImageFromList,
|
|
onAddFilePressed: () => chatVM.pickMultipleImages(),
|
|
),
|
|
),
|
|
] else if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[
|
|
Expanded(
|
|
flex: 1,
|
|
child: const Icon(
|
|
Icons.photo_library_rounded,
|
|
color: MyColors.darkPrimaryColor,
|
|
size: 30,
|
|
).onPress(() => chatVM.pickMultipleImages()),
|
|
),
|
|
],
|
|
if (chatVM.pickedImagesForMessage.isEmpty) ...[
|
|
Expanded(
|
|
flex: 8,
|
|
child: TxtField(
|
|
value: chatVM.chatMessageText,
|
|
hint: LocaleKeys.typeMessageHere.tr(),
|
|
keyboardType: TextInputType.text,
|
|
isNeedBorder: false,
|
|
onChanged: (v) => chatVM.updateChatMessageText(v),
|
|
),
|
|
),
|
|
],
|
|
Expanded(
|
|
flex: 1,
|
|
child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress(
|
|
() async {
|
|
ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText;
|
|
|
|
if (chatVM.pickedImagesForMessage.isNotEmpty) {
|
|
chatMessageTypeEnum = ChatMessageTypeEnum.image;
|
|
}
|
|
final status = await onMessageSend(chatMessageType: chatMessageTypeEnum);
|
|
|
|
if (status) {
|
|
chatVM.scrollChatDown();
|
|
if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) {
|
|
chatVM.clearChatMessageText();
|
|
} else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) {
|
|
chatVM.clearPickedImagesForMessage();
|
|
}
|
|
}
|
|
},
|
|
),
|
|
),
|
|
],
|
|
],
|
|
).toContainer(isShadowEnabled: true)
|
|
],
|
|
);
|
|
}),
|
|
// body:
|
|
);
|
|
}
|
|
}
|