Chat Module almost finished!

mirza_development
Faiz Hashmi 2 years ago
parent c5cefa2309
commit 98b35fbc61

@ -1,5 +1,5 @@
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mc_common_app/models/general/post_params_model.dart';
import 'package:mc_common_app/models/general_models/post_params_model.dart';
import 'package:mc_common_app/models/user_models/user.dart';
import 'package:mc_common_app/utils/enums.dart';

@ -1,4 +1,7 @@
import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/user_models/register_user.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/user/change_email_page.dart';
import 'package:mc_common_app/views/user/change_mobile_page.dart';
@ -74,7 +77,6 @@ class AppRoutes {
static const String requestsDetailPage = "/requestsDetailPage";
static const String sendOfferPage = "/sendOfferPage";
//Setting Options
static const String settingOptionsFaqs = "/settingOptionsFaqs";
static const String settingOptionsLanguages = "/settingOptionsLanguages";
@ -106,3 +108,17 @@ class AppRoutes {
editAccountPage: (context) => const EditAccountPage(),
};
}
class ChatViewArguments {
final RequestModel? requestModel;
final ChatTypeEnum chatTypeEnum;
ChatViewArguments({required this.chatTypeEnum, this.requestModel});
}
class OfferListPageArguments {
final List<OffersModel> offersList;
final RequestModel? requestModel;
OfferListPageArguments({required this.offersList, this.requestModel});
}

@ -550,11 +550,22 @@ extension FormatMonthByNumber on String {
}
extension ChatMessageTypeEnumExt on int {
//FreeText = 1,
// Image = 2,
// Audio = 3,
// Video = 4,
// Offer = 5
ChatMessageTypeEnum toChatMessageTypeEnum() {
if (this == 1) {
return ChatMessageTypeEnum.freeText;
} else if (this == 2) {
return ChatMessageTypeEnum.freeText;
return ChatMessageTypeEnum.image;
} else if (this == 3) {
return ChatMessageTypeEnum.audio;
} else if (this == 4) {
return ChatMessageTypeEnum.video;
} else if (this == 5) {
return ChatMessageTypeEnum.offer;
}
return ChatMessageTypeEnum.freeText;
}
@ -565,18 +576,23 @@ extension ChatMessageTypeToInt on ChatMessageTypeEnum {
switch (this) {
case ChatMessageTypeEnum.freeText:
return 1;
case ChatMessageTypeEnum.offer:
case ChatMessageTypeEnum.image:
return 2;
case ChatMessageTypeEnum.audio:
return 3;
case ChatMessageTypeEnum.video:
return 4;
case ChatMessageTypeEnum.offer:
return 5;
default:
return 0;
return 1;
}
}
}
extension RequestOfferStatusEnumExt on int {
RequestOfferStatusEnum toChatMessageTypeEnum() {
RequestOfferStatusEnum toRequestOfferStatusEnum() {
if (this == 1) {
return RequestOfferStatusEnum.offer;
} else if (this == 2) {
@ -611,3 +627,32 @@ extension RequestOfferStatusEnumToInt on RequestOfferStatusEnum {
}
}
}
extension ChatTypeEnumExt on int {
ChatTypeEnum toChatTypeEnum() {
if (this == 1) {
return ChatTypeEnum.general;
} else if (this == 2) {
return ChatTypeEnum.ads;
} else if (this == 3) {
return ChatTypeEnum.requestOffer;
}
return ChatTypeEnum.general;
}
}
extension ChatTypeEnumToInt on ChatTypeEnum {
int getIdFromChatTypeEnum() {
switch (this) {
case ChatTypeEnum.general:
return 1;
case ChatTypeEnum.ads:
return 2;
case ChatTypeEnum.requestOffer:
return 3;
default:
return 1;
}
}
}

@ -1,5 +1,5 @@
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
class SSCarCheckScheduleModel {
int? serviceProviderID;

@ -1,6 +1,6 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
class SSPhotoOfficeScheduleModel {
int? photoOfficeID;

@ -1,6 +1,6 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
class CustomTimeDateSlotModel {
TimeSlotModel? date;

@ -1,26 +1,54 @@
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/utils/enums.dart';
class ChatMessageModel {
String? senderUserID;
String? senderName;
int? messageType;
ChatMessageTypeEnum? messageTypeEnum;
String? message;
RequestOffer? requestOffer;
int? requestID;
int? requestOfferID;
bool? isMyMessage;
ChatMessageModel({this.senderUserID, this.senderName, this.messageType, this.message, this.requestOffer, this.requestID, this.requestOfferID});
ChatMessageModel({
this.senderUserID,
this.senderName,
this.messageType,
this.message,
this.requestOffer,
this.requestID,
this.requestOfferID,
this.isMyMessage = true,
});
ChatMessageModel.fromJson(Map<String, dynamic> json) {
final myUserId = AppState().getUser.data!.userInfo!.userId.toString();
senderUserID = json['senderUserID'];
senderName = json['senderName'];
messageType = json['messageType'];
messageTypeEnum = (json['messageType'] as int).toChatMessageTypeEnum();
message = json['message'];
if (json['requestOffer'] != null) {
requestOffer = RequestOffer.fromJson(json['requestOffer']);
} else {
requestOffer = null;
}
requestOffer = json['requestOffer'] != null ? RequestOffer.fromJson(json['requestOffer']) : null;
requestID = json['requestID'];
requestOfferID = json['requestOfferID'];
isMyMessage = (json['senderUserId']).toString() == myUserId;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['senderUserID'] = senderUserID;
data['senderName'] = senderName;
data['messageType'] = messageType;
data['message'] = message;
if (requestOffer != null) {
data['requestOffer'] = requestOffer!.toJson();
}
data['requestID'] = requestID;
data['requestOfferID'] = requestOfferID;
return data;
}
}
@ -29,21 +57,47 @@ class RequestOffer {
int? requestID;
int? serviceProviderID;
int? offerStatus;
RequestOfferStatusEnum? requestOfferStatusEnum;
String? comment;
int? price;
double? price;
String? offeredItemCreatedBy;
String? offeredItemCreatedOn;
RequestOffer({this.id, this.requestID, this.serviceProviderID, this.offerStatus, this.comment, this.price, this.offeredItemCreatedBy, this.offeredItemCreatedOn});
RequestOffer({
this.id,
this.requestID,
this.serviceProviderID,
this.offerStatus,
this.comment,
this.price,
this.offeredItemCreatedBy,
this.offeredItemCreatedOn,
this.requestOfferStatusEnum = RequestOfferStatusEnum.offer,
});
RequestOffer.fromJson(Map<String, dynamic> json) {
id = json['id'];
requestID = json['requestID'];
serviceProviderID = json['serviceProviderID'];
offerStatus = json['offerStatus'];
offerStatus = json['offerStatus'];
requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum();
comment = json['comment'];
price = json['price'];
offeredItemCreatedBy = json['offeredItemCreatedBy'];
offeredItemCreatedOn = json['offeredItemCreatedOn'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['requestID'] = requestID;
data['serviceProviderID'] = serviceProviderID;
data['offerStatus'] = offerStatus;
data['comment'] = comment;
data['price'] = price;
data['offeredItemCreatedBy'] = offeredItemCreatedBy;
data['offeredItemCreatedOn'] = offeredItemCreatedOn;
return data;
}
}

@ -10,6 +10,7 @@ class RequestModel {
String vehicleTypeName;
String countryName;
String customerName;
String customerID;
dynamic serviceProviders;
int offerCount;
int id;
@ -43,6 +44,7 @@ class RequestModel {
required this.vehicleTypeName,
required this.countryName,
required this.customerName,
required this.customerID,
required this.serviceProviders,
required this.offerCount,
required this.id,
@ -68,39 +70,42 @@ class RequestModel {
required this.modifiedOn,
});
factory RequestModel.fromJson(Map<String, dynamic> json) => RequestModel(
requestType: json["requestType"],
requestTypeName: json["requestTypeName"],
requestStatusName: json["requestStatusName"],
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"],
customerName: json["customerName"],
serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"],
id: json["id"],
customerId: json["customerID"],
customer: json["customer"],
brand: json["brand"],
model: json["model"],
year: json["year"],
isNew: json["isNew"],
description: json["description"],
requestImages: List<dynamic>.from(json["requestImages"].map((x) => x)),
cityId: json["cityID"],
city: json["city"],
price: json["price"],
paymentStatus: json["paymentStatus"],
vehicleTypeId: json["vehicleTypeID"],
countryId: json["countryID"],
requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)),
isActive: json["isActive"],
createdBy: json["createdBy"],
createdOn: DateTime.parse(json["createdOn"]),
modifiedBy: json["modifiedBy"],
modifiedOn: json["modifiedOn"],
);
factory RequestModel.fromJson(Map<String, dynamic> json) {
return RequestModel(
requestType: json["requestType"],
requestTypeName: json["requestTypeName"],
requestStatusName: json["requestStatusName"],
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"],
customerName: json["customerName"],
customerID: json["customerUserID"],
serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"],
id: json["id"],
customerId: json["customerID"],
customer: json["customer"],
brand: json["brand"],
model: json["model"],
year: json["year"],
isNew: json["isNew"],
description: json["description"],
requestImages: List<dynamic>.from(json["requestImages"].map((x) => x)),
cityId: json["cityID"],
city: json["city"],
price: json["price"],
paymentStatus: json["paymentStatus"],
vehicleTypeId: json["vehicleTypeID"],
countryId: json["countryID"],
requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)),
isActive: json["isActive"],
createdBy: json["createdBy"],
createdOn: DateTime.parse(json["createdOn"]),
modifiedBy: json["modifiedBy"],
modifiedOn: json["modifiedOn"],
);
}
Map<String, dynamic> toJson() => {
"requestType": requestType,

@ -11,7 +11,7 @@ import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/utils/enums.dart';
abstract class AdsRepo {

@ -4,8 +4,8 @@ import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general/m_response.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/appointments_models/schedule_model.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';

@ -4,14 +4,14 @@ import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/models/user_models/role.dart';
import '../models/advertisment_models/vehicle_details_models.dart';
import '../models/general/enums_model.dart';
abstract class CommonRepo {
Future<Country> getAllCountries();

@ -2,7 +2,7 @@ import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/payment_models/pay_order_detail_resp_model.dart';
abstract class PaymentsRepo {

@ -4,7 +4,7 @@ import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';

@ -2,7 +2,7 @@ import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';

@ -7,7 +7,7 @@ import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general/m_response.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/user_models/basic_otp.dart';
import 'package:mc_common_app/models/user_models/change_email.dart';
import 'package:mc_common_app/models/user_models/change_mobile.dart';

@ -172,3 +172,9 @@ enum RequestOfferStatusEnum {
rejected,
cancel,
}
enum ChatTypeEnum {
general,
ads,
requestOffer,
}

@ -15,10 +15,10 @@ import 'package:mc_common_app/models/advertisment_models/special_service_model.d
import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/general/enums_model.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';

@ -4,14 +4,14 @@ 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/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/general/enums_model.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart';

@ -1,7 +1,10 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/models/chat_models/cat_message_model.dart';
import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
@ -14,14 +17,34 @@ class ChatVM extends ChangeNotifier {
late HubConnection hubConnection;
List<ChatMessageModel> chatMessages = [];
String chatMessageText = "";
updateChatMessageText(String value) {
chatMessageText = value;
}
Future<void> onNewMessageReceived({required List<ChatMessageModel> messages}) async {
chatMessages.addAll(messages);
notifyListeners();
}
Future<void> buildHubConnection() async {
// if (hubConnection.state != HubConnectionState.Connected) {
try {
hubConnection = await chatRepo.getHubConnection();
await hubConnection.start();
hubConnection.on("ReceiveMessageRequestOffer", (List<Object?>? arguments) {
print("this is the offer: ${arguments.toString()}");
if (arguments == null || arguments.isEmpty) return;
List<ChatMessageModel> chat = [];
for (var message in arguments) {
final chatMessage = ChatMessageModel.fromJson(message as Map<String, dynamic>);
chat.add(chatMessage);
}
onNewMessageReceived(messages: chat);
Utils.showToast("I received ping : ${arguments.toString()}");
logger.i("I received ping : ${arguments.toString()}");
});
} catch (e) {
logger.i("Error: ${e.toString()}");
@ -31,14 +54,18 @@ class ChatVM extends ChangeNotifier {
// }
}
Future<bool> onSendMessageForRequestOffer(
{required String receiverId, required ChatMessageTypeEnum chatMessageType, required String message, required int requestId, required String offerPrice}) async {
Future<bool> onSendMessageForRequestOffer({
required String receiverId,
required ChatMessageTypeEnum chatMessageType,
required String message,
required int requestId,
required String offerPrice,
}) async {
if (hubConnection.state != HubConnectionState.connected) {
await buildHubConnection();
}
if (hubConnection.state == HubConnectionState.connected) {
final providerId = AppState().getUser.data!.userInfo!.providerId;
print("providerId: $providerId");
hubConnection.invoke(
"SendMessageRequestOffer",
args: <Object>[
@ -65,4 +92,43 @@ class ChatVM extends ChangeNotifier {
}
return true;
}
Future<bool> onTextMessageSend({
required String receiverId,
required ChatMessageTypeEnum chatMessageType,
required String message,
required int requestId,
required String offerPrice,
}) async {
if (hubConnection.state != HubConnectionState.connected) {
await buildHubConnection();
}
if (hubConnection.state == HubConnectionState.connected) {
final providerId = AppState().getUser.data!.userInfo!.providerId;
hubConnection.invoke(
"SendMessageRequestOffer",
args: <Object>[
<String, dynamic>{
"ReceiverUserID": receiverId,
"MessageType": chatMessageType.getIdFromChatMessageTypeEnum(),
"Message": message,
"RequestID": requestId,
// "RequestOfferID": 0,
// "RequestOffer": <String, dynamic>{
// "RequestID": requestId,
// "Price": double.parse(offerPrice),
// "ServiceProviderID": providerId,
// "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
// "Comment": message,
// },
}
],
).catchError((e) {
logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}");
Utils.showToast(e.toString());
return false;
});
}
return true;
}
}

@ -1,19 +1,24 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:convert';
import 'dart:io';
import 'package:flutter/cupertino.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/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/general/enums_model.dart';
import 'package:mc_common_app/models/general/generic_resp_model.dart';
import 'package:mc_common_app/models/chat_models/cat_message_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/request_repo.dart';
import 'package:mc_common_app/services/common_services.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/base_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
@ -384,7 +389,14 @@ class RequestsVM extends BaseVM {
notifyListeners();
}
Future<void> onSendOfferPressed({required BuildContext context, required String receiverId, required String message, required int requestId, required String offerPrice}) async {
Future<void> onSendOfferPressed({
required BuildContext context,
required String receiverId,
required String message,
required int requestId,
required String offerPrice,
required RequestModel requestModel,
}) async {
if (isSendOfferValidated()) {
bool status = await context.read<ChatVM>().onSendMessageForRequestOffer(
receiverId: receiverId,
@ -397,6 +409,10 @@ class RequestsVM extends BaseVM {
if (status) {
// resetSendOfferBottomSheet();
Navigator.pop(context);
ChatMessageModel chatMessageModel = ChatMessageModel(isMyMessage: true, message: message, messageType: ChatMessageTypeEnum.freeText, );
context.read<ChatVM>().onNewMessageReceived(messages: messages);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: requestModel);
navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
}
}
}

@ -8,7 +8,7 @@ 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/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general/m_response.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/user_models/basic_otp.dart';
import 'package:mc_common_app/models/user_models/change_email.dart';
import 'package:mc_common_app/models/user_models/change_mobile.dart';

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart';

@ -3,7 +3,7 @@ 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/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.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';

@ -9,7 +9,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.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';

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';

@ -4,7 +4,7 @@ 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/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';

@ -2,7 +2,7 @@ import 'package:flutter/material.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/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';

@ -1,66 +1,88 @@
import 'package:flutter/material.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/models/chat_models/cat_message_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/chat_view_model.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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class ChatView extends StatelessWidget {
const ChatView({super.key});
final ChatViewArguments chatViewArguments;
const ChatView({super.key, required this.chatViewArguments});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(title: "Chat"),
body: Column(
children: [
Expanded(
child: ListView.separated(
itemCount: 15,
separatorBuilder: (BuildContext context, int index) => 20.height,
itemBuilder: (BuildContext context, int index) {
return ChatMessageCustomWidget(
isSent: index.isOdd,
profileUrl: MyAssets.bnCar,
messageText: "Hi, How Are you? I can help you out with the desired request.",
messageTypeEnum: index == 10
? (MessageTypeEnum.newOfferRequired)
: index == 12
? (MessageTypeEnum.offerProvided)
: (MessageTypeEnum.text),
senderName: "Al Abdullah Cars",
);
}).horPaddingMain(),
),
10.width,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 7,
child: TxtField(
// value: adVM.vehicleDemandAmount,
// errorValue: adVM.demandAmountError,
hint: "Type your message here..",
keyboardType: TextInputType.text,
isNeedBorder: false,
onChanged: (v) => null,
body: Consumer<ChatVM>(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
return Column(
children: [
Expanded(
child: ListView.separated(
itemCount: chatVM.chatMessages.length,
separatorBuilder: (BuildContext context, int index) => 20.height,
itemBuilder: (BuildContext context, int index) {
ChatMessageModel chatMessageModel = chatVM.chatMessages[index];
return ChatMessageCustomWidget(
isSent: chatMessageModel.isMyMessage ?? false,
profileUrl: MyAssets.bnCar,
messageText: "${chatMessageModel.message}",
messageTypeEnum: chatMessageModel.messageTypeEnum ?? ChatMessageTypeEnum.freeText,
requestOfferStatusEnum:
(chatMessageModel.requestOffer != null ? chatMessageModel.requestOffer!.requestOfferStatusEnum : RequestOfferStatusEnum.offer) ?? RequestOfferStatusEnum.offer,
senderName: "${chatMessageModel.senderName}",
);
}).horPaddingMain(),
),
10.width,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 7,
child: TxtField(
value: chatVM.chatMessageText,
hint: "Type your message here..",
keyboardType: TextInputType.text,
isNeedBorder: false,
onChanged: (v) => chatVM.updateChatMessageText(v),
),
),
),
Expanded(
Expanded(
flex: 1,
child: const Icon(
Icons.send_rounded,
color: MyColors.darkPrimaryColor,
size: 30,
).onPress(() {}))
],
).toContainer(isShadowEnabled: true),
],
),
).onPress(
() async {
final status = await chatVM.onTextMessageSend(
receiverId: "7db5e1ae-6de4-47d7-984b-08db2842f899", //Todo: This should be managed somehow!!
message: chatVM.chatMessageText,
requestId: chatViewArguments.chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArguments.requestModel!.id : 0,
offerPrice: "0.0",
chatMessageType: ChatMessageTypeEnum.freeText,
);
if (status) {
chatVM.updateChatMessageText("");
}
},
),
)
],
).toContainer(isShadowEnabled: true),
],
);
}),
// body:
);
}
@ -70,7 +92,8 @@ class ChatMessageCustomWidget extends StatelessWidget {
final String profileUrl;
final String senderName;
final String messageText;
final MessageTypeEnum messageTypeEnum;
final ChatMessageTypeEnum messageTypeEnum;
final RequestOfferStatusEnum requestOfferStatusEnum;
final bool isSent;
const ChatMessageCustomWidget({
@ -79,9 +102,107 @@ class ChatMessageCustomWidget extends StatelessWidget {
required this.senderName,
required this.messageText,
required this.messageTypeEnum,
this.requestOfferStatusEnum = RequestOfferStatusEnum.offer,
required this.isSent,
});
Widget buildOfferDetailsInChatMessage({required RequestOfferStatusEnum requestOfferStatusEnum}) {
switch (requestOfferStatusEnum) {
case RequestOfferStatusEnum.offer:
return Column(
children: [
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"40000".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
],
),
10.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: "Accept",
fontSize: 9,
borderColor: MyColors.greenColor,
isFilled: false,
onPressed: () {},
backgroundColor: MyColors.white,
txtColor: MyColors.greenColor,
),
),
20.width,
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: "Reject",
borderColor: MyColors.redColor,
isFilled: false,
onPressed: () {},
backgroundColor: MyColors.white,
txtColor: MyColors.redColor,
fontSize: 9,
),
)
],
),
],
);
case RequestOfferStatusEnum.negotiate:
return Column(
children: [
Center(
child: "You asked for the new offer.".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: [
Center(
child: "You have accepted the offer.".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: [
Center(
child: "You have rejected the offer.".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: [
Center(
child: "You have cancelled the offer.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
}
}
@override
Widget build(BuildContext context) {
return Directionality(
@ -125,56 +246,8 @@ class ChatMessageCustomWidget extends StatelessWidget {
),
],
),
if (messageTypeEnum == MessageTypeEnum.offerProvided || messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"40000".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
],
),
10.height,
if (messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[
Center(
child: "You asked for the new offer.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
] else ...[
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: "Accept",
fontSize: 9,
borderColor: MyColors.greenColor,
isFilled: false,
onPressed: () {},
backgroundColor: MyColors.white,
txtColor: MyColors.greenColor,
),
),
20.width,
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: "Reject",
borderColor: MyColors.redColor,
isFilled: false,
onPressed: () {},
backgroundColor: MyColors.white,
txtColor: MyColors.redColor,
fontSize: 9,
),
)
],
),
],
if (messageTypeEnum == ChatMessageTypeEnum.offer) ...[
buildOfferDetailsInChatMessage(requestOfferStatusEnum: requestOfferStatusEnum),
],
],
).toContainer(
@ -191,5 +264,3 @@ class ChatMessageCustomWidget extends StatelessWidget {
);
}
}
enum MessageTypeEnum { text, picture, offerProvided, recording, video, newOfferRequired }

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart';
import 'package:mc_common_app/views/advertisement/picked_images_container.dart';

@ -4,24 +4,26 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/requests_models/offers_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/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class OfferListPage extends StatelessWidget {
final List<OffersModel> offersList;
final OfferListPageArguments offerListPageArguments;
OfferListPage({required this.offersList});
const OfferListPage({super.key, required this.offerListPageArguments});
@override
Widget build(BuildContext context) {
final List<OffersModel> offersList = offerListPageArguments.offersList;
return Scaffold(
appBar: CustomAppBar(title: "Offers"),
appBar: const CustomAppBar(title: "Offers"),
body: offersList.isEmpty
? Center(child: "No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor))
: ListView.separated(
itemCount: offersList.length,
padding: EdgeInsets.all(16),
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
OffersModel offersModel = offersList[index];
return Stack(
@ -33,7 +35,7 @@ class OfferListPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${offersModel.serviceProvider!.companyName ?? ""}".toText(fontSize: 16, isBold: true),
(offersModel.serviceProvider!.companyName ?? "").toText(fontSize: 16, isBold: true),
//Un read offers count
@ -70,14 +72,15 @@ class OfferListPage extends StatelessWidget {
),
],
),
Icon(
const Icon(
Icons.arrow_forward,
color: MyColors.darkIconColor,
size: 18,
),
],
).onPress(() {
navigateWithName(context, AppRoutes.chatView);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: offerListPageArguments.requestModel);
navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
}).toContainer(isShadowEnabled: true);
},
separatorBuilder: (context, index) => 16.height,

@ -1,3 +1,5 @@
// ignore_for_file: use_build_context_synchronously
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:flutter/material.dart';
@ -34,7 +36,7 @@ class RequestItem extends StatelessWidget {
6.height,
"${request.brand} ${request.model}".toText(fontSize: 16, isBold: true),
showItem("Model:", "${request.year}"),
showItem("Customer Name:", "${request.customerName}"),
showItem("Customer Name:", request.customerName),
],
),
),
@ -93,7 +95,7 @@ class RequestItem extends StatelessWidget {
),
],
),
Icon(
const Icon(
Icons.arrow_forward,
color: MyColors.darkIconColor,
size: 18,
@ -106,7 +108,8 @@ class RequestItem extends StatelessWidget {
navigateWithName(context, AppRoutes.requestsDetailPage, arguments: request);
} else {
List<OffersModel> offers = await context.read<RequestsVM>().getOffersByRequest(requestId: request.id, context: context);
navigateWithName(context, AppRoutes.offersListPage, arguments: offers);
OfferListPageArguments offerListPageArguments = OfferListPageArguments(offersList: offers, requestModel: request);
navigateWithName(context, AppRoutes.offersListPage, arguments: offerListPageArguments);
}
});
}

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
class FiltersList extends StatelessWidget {

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/general/widgets_models.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
class BuildTimeSlots extends StatelessWidget {

Loading…
Cancel
Save