Debugging changes for request management chat

master_new_changes
Faiz Hashmi 2 years ago
parent 7f0df61ff0
commit 9b50be3b05

@ -186,7 +186,7 @@
"updateBranch": "تحديث فرع", "updateBranch": "تحديث فرع",
"branches": "الفروع", "branches": "الفروع",
"requests": "الطلبات", "requests": "الطلبات",
"noBranchFound" : "لم يتم العثور على فرع", "noBranchFound": "لم يتم العثور على فرع",
"onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات", "onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات",
"pickAddress": "اختر العنوان", "pickAddress": "اختر العنوان",
"pickLocation": "اختر الموقع", "pickLocation": "اختر الموقع",
@ -202,19 +202,19 @@
"completeProfile2": "اكمل الملف الشخصي 2/3", "completeProfile2": "اكمل الملف الشخصي 2/3",
"completeProfile3": "اكمل الملف الشخصي 3/3", "completeProfile3": "اكمل الملف الشخصي 3/3",
"provider": "مزود", "provider": "مزود",
"noRequeststoShow" : "لا توجد طلبات للعرض", "noRequeststoShow": "لا توجد طلبات للعرض",
"myBranches": "فروعي", "myBranches": "فروعي",
"mergeAppointments" : "دمج المواعيد", "mergeAppointments": "دمج المواعيد",
"addService" : "أضف الخدمة", "addService": "أضف الخدمة",
"selectServicestoAdd" : "حدد الخدمات التي تريد إضافتها", "selectServicestoAdd": "حدد الخدمات التي تريد إضافتها",
"noServiceFound": "لم يتم العثور على الخدمة", "noServiceFound": "لم يتم العثور على الخدمة",
"selectItems" : "اختيار العناصر", "selectItems": "اختيار العناصر",
"noItemSelectedYet" : "لم يتم تحديد أي عنصر بعد", "noItemSelectedYet": "لم يتم تحديد أي عنصر بعد",
"totalAdditionalAmount" : "إجمالي المبلغ الإضافي", "totalAdditionalAmount": "إجمالي المبلغ الإضافي",
"sar" : "ريال سعودي", "sar": "ريال سعودي",
"cancel" : "يلغي", "cancel": "يلغي",
"add" : "يضيف", "add": "يضيف",
"itemsAddedSuccessfully" : "تمت إضافة العناصر بنجاح", "itemsAddedSuccessfully": "تمت إضافة العناصر بنجاح",
"pleaseSelectItems": "يرجى اختيار العناصر", "pleaseSelectItems": "يرجى اختيار العناصر",
"totalAmount": "المبلغ الإجمالي", "totalAmount": "المبلغ الإجمالي",
"searchItems": "البحث عن العناصر", "searchItems": "البحث عن العناصر",
@ -566,15 +566,6 @@
"defineLicenses": "تحديد التراخيص", "defineLicenses": "تحديد التراخيص",
"logOut": "تسجيل الخروج", "logOut": "تسجيل الخروج",
"customer": "العميل", "customer": "العميل",
"accept": "قبول" "accept": "قبول",
"requestAlreadyInProgress": "هذا الطلب قيد التقدم بالفعل."
} }

@ -423,93 +423,93 @@
"reserveAd": "Reserve Ad", "reserveAd": "Reserve Ad",
"reservationAmount": "Reservation Amount", "reservationAmount": "Reservation Amount",
"belowAmountPayLater": "Below Amount that you will pay later", "belowAmountPayLater": "Below Amount that you will pay later",
"carPrice":"Car Price", "carPrice": "Car Price",
"vatExcluded":"VAT Excluded", "vatExcluded": "VAT Excluded",
"carInsuranceService":"Car insurance Service", "carInsuranceService": "Car insurance Service",
"toBeDecided":"To be Decided", "toBeDecided": "To be Decided",
"registrationCarPlates":"Registration & Car Plates", "registrationCarPlates": "Registration & Car Plates",
"homeDeliveryService":"Home Delivery Service", "homeDeliveryService": "Home Delivery Service",
"specialServicechargesInsuranceDeliveryLocation":"Special service charges will be added based on desired insurance and delivery Location", "specialServicechargesInsuranceDeliveryLocation": "Special service charges will be added based on desired insurance and delivery Location",
"estimated":"Estimated", "estimated": "Estimated",
"servicesReservingAd":"Some services are mandatory while reserving Ad", "servicesReservingAd": "Some services are mandatory while reserving Ad",
"completeReservation":"Complete Reservation", "completeReservation": "Complete Reservation",
"contact":"Contact", "contact": "Contact",
"setDateandTime":"Set Date and Time", "setDateandTime": "Set Date and Time",
"selectOffice":"Select Office", "selectOffice": "Select Office",
"availableSlots":"Available Slots", "availableSlots": "Available Slots",
"bookAndPay":"Book and Pay", "bookAndPay": "Book and Pay",
"reservationAmounts":"Reservation Amounts", "reservationAmounts": "Reservation Amounts",
"tax":"Tax", "tax": "Tax",
"adsFilter": "Ads Filter", "adsFilter": "Ads Filter",
"searchByCity":"Search By City", "searchByCity": "Search By City",
"selectCity":"Select City", "selectCity": "Select City",
"searchByBrandName":"Search By Brand Name", "searchByBrandName": "Search By Brand Name",
"selectVehicleBrand":"Select Vehicle Brand", "selectVehicleBrand": "Select Vehicle Brand",
"searchByVehicleYear":"Search By Vehicle Year", "searchByVehicleYear": "Search By Vehicle Year",
"selectYear":"Select Year", "selectYear": "Select Year",
"searchByAdOwner":"Search By Ad Owner", "searchByAdOwner": "Search By Ad Owner",
"selectOwner":"Select Owner", "selectOwner": "Select Owner",
"search":"Search", "search": "Search",
"clearFilters":"Clear Filters", "clearFilters": "Clear Filters",
"book":"Book", "book": "Book",
"markAsSold":"Mark As Sold", "markAsSold": "Mark As Sold",
"deactivateAd":"Deactivate Ad", "deactivateAd": "Deactivate Ad",
"doWantDeactivateAd":"Do you want to the Deactivate this Ad?", "doWantDeactivateAd": "Do you want to the Deactivate this Ad?",
"stoptheBuyers":"We will stop showing this ad to the buyers", "stoptheBuyers": "We will stop showing this ad to the buyers",
"cancelReservation":"Cancel Reservation", "cancelReservation": "Cancel Reservation",
"reasonForCancellation":"Reason for Cancellation", "reasonForCancellation": "Reason for Cancellation",
"doWantCancelReservation":"Do you want to cancel the reservation", "doWantCancelReservation": "Do you want to cancel the reservation",
"yourAdVisibletoBuy.":"Your ad reservation will be cancelled and this ad will be again visible to everyone to buy", "yourAdVisibletoBuy.": "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy",
"completeDeal":"Complete Deal", "completeDeal": "Complete Deal",
"uploadBankReceipt":"Upload Bank Receipt", "uploadBankReceipt": "Upload Bank Receipt",
"notesForAdmin":"Notes For Admin", "notesForAdmin": "Notes For Admin",
"extendAd":"Extend Ad", "extendAd": "Extend Ad",
"updateAdDetails":"Do you want to update the Ad Details", "updateAdDetails": "Do you want to update the Ad Details",
"durationExtendingAd":"You can change the ad duration and details before extending the ad", "durationExtendingAd": "You can change the ad duration and details before extending the ad",
"waitingAdminsResponse":"Waiting for Admins Response", "waitingAdminsResponse": "Waiting for Admins Response",
"cancelledByOwner":"Cancelled by Owner", "cancelledByOwner": "Cancelled by Owner",
"cancelledByAdmin":"Cancelled by Admin", "cancelledByAdmin": "Cancelled by Admin",
"reservationTimeOver":"Reservation Time Over", "reservationTimeOver": "Reservation Time Over",
"paymentVerified":"Payment Verified", "paymentVerified": "Payment Verified",
"rejectedFormAdmin":"Rejected form Admin", "rejectedFormAdmin": "Rejected form Admin",
"waitingAdminPost":"Waiting for admin to post", "waitingAdminPost": "Waiting for admin to post",
"waitingAdminsApproval":"Waiting for Admins Approval", "waitingAdminsApproval": "Waiting for Admins Approval",
"sold":"Sold", "sold": "Sold",
"noAdsShow":"No Ads to show", "noAdsShow": "No Ads to show",
"damagePartList":"Damage Part List", "damagePartList": "Damage Part List",
"searchPart":"Search Part", "searchPart": "Search Part",
"addSpecialService":"Add Special Service", "addSpecialService": "Add Special Service",
"vehicleVar":"Vehicle", "vehicleVar": "Vehicle",
"detailsVar":"Details", "detailsVar": "Details",
"damageVar":"Damage", "damageVar": "Damage",
"partsVar": "Parts", "partsVar": "Parts",
"additional":"Additional", "additional": "Additional",
"review":"Review", "review": "Review",
"adVar": "Ad", "adVar": "Ad",
"updateAd":"Update Ad", "updateAd": "Update Ad",
"createAd":"Create Ad", "createAd": "Create Ad",
"next":"Next", "next": "Next",
"submitAd":"Submit Ad", "submitAd": "Submit Ad",
"selectAdType":"Select Ad Type", "selectAdType": "Select Ad Type",
"validUntilSubscriptionExpiration":"Valid Until Subscription Expiration", "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration",
"adsRemaining ":"Ads Remaining", "adsRemaining ": "Ads Remaining",
"youLeftAdsGivenSubscription":"You have left with 05 out of 50 ads given in the subscription.", "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.",
"updateSubscription":"Update Subscription", "updateSubscription": "Update Subscription",
"workInProgress":"Work In Progress", "workInProgress": "Work In Progress",
"visitCompleted":"Visit Completed", "visitCompleted": "Visit Completed",
"youWantCancelAppointment":"Do you want to cancel this appointment?", "youWantCancelAppointment": "Do you want to cancel this appointment?",
"appointmentCancelledCannotUndoAction":"Your appointment will be cancelled and you cannot undo this action.", "appointmentCancelledCannotUndoAction": "Your appointment will be cancelled and you cannot undo this action.",
"appointment":"Appointment", "appointment": "Appointment",
"rescheduleAppointment":"Reschedule Appointment", "rescheduleAppointment": "Reschedule Appointment",
"payforAppointment":"Pay for Appointment", "payforAppointment": "Pay for Appointment",
"appointmentsFilter":"Appointments Filter", "appointmentsFilter": "Appointments Filter",
"searchByProvider":"Search By Provider", "searchByProvider": "Search By Provider",
"selectProvider":"Select Provider", "selectProvider": "Select Provider",
"searchByBranch":"Search By Branch", "searchByBranch": "Search By Branch",
"searchByCategory":"Search By Category", "searchByCategory": "Search By Category",
"selectCategory":"Select Category", "selectCategory": "Select Category",
"searchByService":"Search By Service", "searchByService": "Search By Service",
"selectServices":"Select Services", "selectServices": "Select Services",
"modifyPackage": "Modify Package", "modifyPackage": "Modify Package",
"schedule": "Schedule", "schedule": "Schedule",
"serviceLocation": "Service Location:", "serviceLocation": "Service Location:",
@ -527,13 +527,13 @@
"dateAndTime": "Date and Time", "dateAndTime": "Date and Time",
"timeLocation": "Time & Location", "timeLocation": "Time & Location",
"serviceCharges": "Service Charges", "serviceCharges": "Service Charges",
"locationCharges" : "Location Charges", "locationCharges": "Location Charges",
"payableNow": "Payable Now", "payableNow": "Payable Now",
"remainingAmount": "Remaining Amount", "remainingAmount": "Remaining Amount",
"branchesFilter": "Branches Filter", "branchesFilter": "Branches Filter",
"searchByDistance": "Search By Distance", "searchByDistance": "Search By Distance",
"searchByMinimumRatings": "Search By Minimum Ratings", "searchByMinimumRatings": "Search By Minimum Ratings",
"chat": "Chat", "chat": "Chat",
"noRequestsShow": "No Requests to show.", "noRequestsShow": "No Requests to show.",
"typeMessageHere": "Type your message here..", "typeMessageHere": "Type your message here..",
"reject": "Reject", "reject": "Reject",
@ -561,11 +561,12 @@
"termPrivacy": "Term & Privacy", "termPrivacy": "Term & Privacy",
"inviteFriends": "Invite Friends", "inviteFriends": "Invite Friends",
"more": "More", "more": "More",
"language" :"Language", "language": "Language",
"mySubscriptions": "My Subscriptions", "mySubscriptions": "My Subscriptions",
"subscriptions": "Subscriptions", "subscriptions": "Subscriptions",
"defineLicenses": "Define Licenses", "defineLicenses": "Define Licenses",
"logOut": "Log Out", "logOut": "Log Out",
"customer": "Customer", "customer": "Customer",
"accept": "Accept" "accept": "Accept",
"requestAlreadyInProgress": "This request is already in progress."
} }

@ -582,7 +582,8 @@ class CodegenLoader extends AssetLoader{
"defineLicenses": "تحديد التراخيص", "defineLicenses": "تحديد التراخيص",
"logOut": "تسجيل الخروج", "logOut": "تسجيل الخروج",
"customer": "العميل", "customer": "العميل",
"accept": "قبول" "accept": "قبول",
"requestAlreadyInProgress": "هذا الطلب قيد التقدم بالفعل."
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1153,7 +1154,8 @@ static const Map<String,dynamic> en_US = {
"defineLicenses": "Define Licenses", "defineLicenses": "Define Licenses",
"logOut": "Log Out", "logOut": "Log Out",
"customer": "Customer", "customer": "Customer",
"accept": "Accept" "accept": "Accept",
"requestAlreadyInProgress": "This request is already in progress."
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -546,5 +546,6 @@ abstract class LocaleKeys {
static const logOut = 'logOut'; static const logOut = 'logOut';
static const customer = 'customer'; static const customer = 'customer';
static const accept = 'accept'; static const accept = 'accept';
static const requestAlreadyInProgress = 'requestAlreadyInProgress';
} }

@ -34,7 +34,7 @@ class RequestModel {
List<dynamic> requestProviderItem; List<dynamic> requestProviderItem;
bool isActive; bool isActive;
int createdBy; int createdBy;
DateTime createdOn; String? createdOn;
dynamic modifiedBy; dynamic modifiedBy;
dynamic modifiedOn; dynamic modifiedOn;
List<ChatMessageModel> chatMessages; List<ChatMessageModel> chatMessages;
@ -110,7 +110,7 @@ class RequestModel {
requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)), requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)),
isActive: json["isActive"], isActive: json["isActive"],
createdBy: json["createdBy"], createdBy: json["createdBy"],
createdOn: DateTime.parse(json["createdOn"]), createdOn: json["createdOn"],
modifiedBy: json["modifiedBy"], modifiedBy: json["modifiedBy"],
modifiedOn: json["modifiedOn"], modifiedOn: json["modifiedOn"],
chatMessages: [], chatMessages: [],

@ -5,6 +5,17 @@
// unverified, // unverified,
// } // }
//
//
class AppEnums {
static const int requestFilterEnumId = 16; // Requests Filter Enums
static const int myAdsFilterEnumId = 18; // My Ads Filter Enums
static const int exploreAdsFilterEnumId = 23; // Explore Ads Filter Enums
static const int appointmentsFilterEnumId = 13; // Appointments Filter Enums
}
enum VehicleType { enum VehicleType {
car, car,
motorCycle, motorCycle,
@ -78,15 +89,7 @@ enum PaymentMethods {
tamara, tamara,
} }
enum PaymentTypes { enum PaymentTypes { subscription, appointment, adReserve, ads, request, extendAds, partialAppointment }
subscription,
appointment,
adReserve,
ads,
request,
extendAds,
partialAppointment
}
enum AdCreationSteps { enum AdCreationSteps {
vehicleDetails, vehicleDetails,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -102,41 +102,31 @@ class ChatVM extends ChangeNotifier {
return isValidated; return isValidated;
} }
Future<void> onNewMessageReceived( Future<void> onNewMessageReceived({required List<ChatMessageModel> messages, required BuildContext context, bool isMyOwnOffer = false}) async {
{required List<ChatMessageModel> messages,
required BuildContext context,
bool isMyOwnOffer = false}) async {
// log("message I received in onNewMessageReceived ${messages.first.toString()}");
if (AppState().currentAppType == AppType.customer) { if (AppState().currentAppType == AppType.customer) {
for (var msg in messages) { for (var msg in messages) {
int providerIndex = serviceProviderOffersList.indexWhere( int providerIndex = serviceProviderOffersList.indexWhere((element) => element.providerUserId == msg.senderUserID); // TODO : NEED TO BE CHECKED
(element) => element.providerUserId == msg.senderUserID);
if (providerIndex != -1) { if (providerIndex != -1) {
serviceProviderOffersList[providerIndex].chatMessages!.add(msg); serviceProviderOffersList[providerIndex].chatMessages!.add(msg);
} }
} }
//providerUserId
} else { } else {
for (var msg in messages) { for (var msg in messages) {
// Where we need to call this function for saving a message in chat we will use receiverUserID and in those cases where received ID is null , it means it is a signal R call // Where we need to call this function for saving a message in chat we will use receiverUserID and in those cases where received ID is null , it means it is a signal R call
int providerIndex = -1; int providerIndex = -1;
if (isMyOwnOffer) { if (isMyOwnOffer) {
providerIndex = providerIndex = context.read<RequestsVM>().myFilteredRequests.indexWhere(
context.read<RequestsVM>().myFilteredRequests.indexWhere( (element) => element.customerUserID == msg.receiverUserID,
(element) => element.customerUserID == msg.receiverUserID, );
);
} else { } else {
providerIndex = providerIndex = context.read<RequestsVM>().myFilteredRequests.indexWhere(
context.read<RequestsVM>().myFilteredRequests.indexWhere( (element) => element.customerUserID == msg.senderUserID,
(element) => element.customerUserID == msg.senderUserID, );
);
} }
// log("here is it: $providerIndex");
// log("here is it: ${msg.senderUserID}");
// log("here is it: ${context.read<RequestsVM>().myFilteredRequests.first.customerUserID.toString()}");
if (providerIndex != -1) { if (providerIndex != -1) {
context context.read<RequestsVM>().addChatMessagesInRequestsModel(msg: msg, index: providerIndex);
.read<RequestsVM>()
.addChatMessagesInRequestsModel(msg: msg, index: providerIndex);
} }
} }
} }
@ -145,18 +135,15 @@ class ChatVM extends ChangeNotifier {
} }
Future<void> buildHubConnection(BuildContext context) async { Future<void> buildHubConnection(BuildContext context) async {
if (hubConnection == null || if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) {
hubConnection!.state != HubConnectionState.connected) {
try { try {
hubConnection = await chatRepo.getHubConnection(); hubConnection = await chatRepo.getHubConnection();
await hubConnection!.start(); await hubConnection!.start();
hubConnection!.on("ReceiveMessageRequestOffer", hubConnection!.on("ReceiveMessageRequestOffer", (List<Object?>? arguments) {
(List<Object?>? arguments) {
if (arguments == null || arguments.isEmpty) return; if (arguments == null || arguments.isEmpty) return;
List<ChatMessageModel> chat = []; List<ChatMessageModel> chat = [];
for (var message in arguments) { for (var message in arguments) {
final chatMessage = final chatMessage = ChatMessageModel.fromJson(message as Map<String, dynamic>);
ChatMessageModel.fromJson(message as Map<String, dynamic>);
chat.add(chatMessage); chat.add(chatMessage);
} }
onNewMessageReceived(messages: chat, context: context); onNewMessageReceived(messages: chat, context: context);
@ -178,8 +165,7 @@ class ChatVM extends ChangeNotifier {
required String offerPrice, required String offerPrice,
required BuildContext context, required BuildContext context,
}) async { }) async {
if (hubConnection == null || if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) {
hubConnection!.state != HubConnectionState.connected) {
await buildHubConnection(context); await buildHubConnection(context);
} }
if (hubConnection!.state == HubConnectionState.connected) { if (hubConnection!.state == HubConnectionState.connected) {
@ -197,8 +183,7 @@ class ChatVM extends ChangeNotifier {
"RequestID": requestId, "RequestID": requestId,
"Price": double.parse(offerPrice), "Price": double.parse(offerPrice),
"ServiceProviderID": providerId, "ServiceProviderID": providerId,
"OfferStatus": RequestOfferStatusEnum.offer "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
.getIdFromRequestOfferStatusEnum(),
"Comment": message, "Comment": message,
}, },
} }
@ -209,6 +194,21 @@ class ChatVM extends ChangeNotifier {
return false; return false;
}); });
} }
logger.i(<String, dynamic>{
"ReceiverUserID": receiverId,
"MessageType": chatMessageType.getIdFromChatMessageTypeEnum(),
"ChatText": message,
"RequestID": requestId,
"ReqOfferID": 0,
"ReqOffer": <String, dynamic>{
"RequestID": requestId,
"Price": double.parse(offerPrice),
"ServiceProviderID": AppState().getUser.data!.userInfo!.providerId,
"OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
"Comment": message,
},
});
return true; return true;
} }
@ -222,22 +222,22 @@ class ChatVM extends ChangeNotifier {
}) async { }) async {
if (message.isEmpty) return false; if (message.isEmpty) return false;
if (hubConnection == null || if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) {
hubConnection!.state != HubConnectionState.connected) {
await buildHubConnection(context); await buildHubConnection(context);
} }
if (hubConnection!.state == HubConnectionState.connected) { if (hubConnection!.state == HubConnectionState.connected) {
final userId = AppState().getUser.data!.userInfo!.userId.toString(); final userId = AppState().getUser.data!.userInfo!.userId.toString();
final name = AppState().getUser.data!.userInfo!.firstName.toString(); final name = AppState().getUser.data!.userInfo!.firstName.toString();
log("I have saved this: ${(<String, dynamic>{ logger.i((<String, dynamic>{
"ReceiverUserID": receiverId, "ReceiverUserID": receiverId,
"SenderUserID": userId, "SenderUserID": userId,
"MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(),
"ChatText": message, "ChatText": message,
"RequestID": requestId, "RequestID": requestId,
"ReqOfferID": latestOfferId, "ReqOfferID": latestOfferId,
}).toString()}"); }));
hubConnection!.invoke( hubConnection!.invoke(
"SendMessageRequestOffer", "SendMessageRequestOffer",
args: <Object>[ args: <Object>[
@ -251,10 +251,11 @@ class ChatVM extends ChangeNotifier {
} }
], ],
).catchError((e) { ).catchError((e) {
logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}"); logger.i("error in invoking SendMessage: ${e.toString()}");
Utils.showToast(e.toString()); Utils.showToast(e.toString());
return false; return false;
}); });
ChatMessageModel chatMessageModel = ChatMessageModel( ChatMessageModel chatMessageModel = ChatMessageModel(
messageType: chatMessageType.getIdFromChatMessageTypeEnum(), messageType: chatMessageType.getIdFromChatMessageTypeEnum(),
chatText: message, chatText: message,
@ -267,21 +268,14 @@ class ChatVM extends ChangeNotifier {
); );
if (AppState().currentAppType == AppType.customer) { if (AppState().currentAppType == AppType.customer) {
int providerIndex = serviceProviderOffersList int providerIndex = serviceProviderOffersList.indexWhere((element) => element.providerUserId == receiverId);
.indexWhere((element) => element.providerUserId == receiverId);
if (providerIndex != -1) { if (providerIndex != -1) {
serviceProviderOffersList[providerIndex] serviceProviderOffersList[providerIndex].chatMessages!.add(chatMessageModel);
.chatMessages!
.add(chatMessageModel);
} }
} else { } else {
int providerIndex = context int providerIndex = context.read<RequestsVM>().myFilteredRequests.indexWhere((element) => element.customerUserID == receiverId);
.read<RequestsVM>()
.myFilteredRequests
.indexWhere((element) => element.customerUserID == receiverId);
if (providerIndex != -1) { if (providerIndex != -1) {
context.read<RequestsVM>().addChatMessagesInRequestsModel( context.read<RequestsVM>().addChatMessagesInRequestsModel(msg: chatMessageModel, index: providerIndex);
msg: chatMessageModel, index: providerIndex);
} }
} }
return true; return true;
@ -291,12 +285,10 @@ class ChatVM extends ChangeNotifier {
List<ServiceProvidersOffers> serviceProviderOffersList = []; List<ServiceProvidersOffers> serviceProviderOffersList = [];
Future<void> getOffersFromProvidersByRequest( Future<void> getOffersFromProvidersByRequest({required int requestId, required BuildContext context}) async {
{required int requestId, required BuildContext context}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
ProviderOffersModel providerOffersModel = await requestRepo ProviderOffersModel providerOffersModel = await requestRepo.getOffersFromProvidersByRequest(requestId: requestId);
.getOffersFromProvidersByRequest(requestId: requestId);
Utils.hideLoading(context); Utils.hideLoading(context);
serviceProviderOffersList.clear(); serviceProviderOffersList.clear();
serviceProviderOffersList = providerOffersModel.serviceProviders ?? []; serviceProviderOffersList = providerOffersModel.serviceProviders ?? [];
@ -318,15 +310,10 @@ class ChatVM extends ChangeNotifier {
try { try {
int customerId = AppState().getUser.data!.userInfo!.customerId!; int customerId = AppState().getUser.data!.userInfo!.customerId!;
Utils.showLoading(context); Utils.showLoading(context);
List<ChatMessageModel> chatMessages = await chatRepo.getUsersChatMessages( List<ChatMessageModel> chatMessages = await chatRepo.getUsersChatMessages(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId);
providerId: providerId,
customerId: customerId,
requestOfferId: requestOfferId,
requestId: requestId);
serviceProviderOffersList[providerOfferIndex].chatMessages = chatMessages; serviceProviderOffersList[providerOfferIndex].chatMessages = chatMessages;
if (serviceProviderOffersList[providerOfferIndex].chatMessages != null) { if (serviceProviderOffersList[providerOfferIndex].chatMessages != null) {
for (var message for (var message in serviceProviderOffersList[providerOfferIndex].chatMessages!) {
in serviceProviderOffersList[providerOfferIndex].chatMessages!) {
if (message.chatMessageTypeEnum == ChatMessageTypeEnum.offer) { if (message.chatMessageTypeEnum == ChatMessageTypeEnum.offer) {
updateLatestOfferId(message.reqOfferID ?? 0); updateLatestOfferId(message.reqOfferID ?? 0);
log("latestOfferId: $latestOfferId"); log("latestOfferId: $latestOfferId");
@ -352,13 +339,8 @@ class ChatVM extends ChangeNotifier {
try { try {
int providerId = AppState().getUser.data!.userInfo!.providerId!; int providerId = AppState().getUser.data!.userInfo!.providerId!;
Utils.showLoading(context); Utils.showLoading(context);
List<ChatMessageModel> chatMessages = await chatRepo.getUsersChatMessages( List<ChatMessageModel> chatMessages = await chatRepo.getUsersChatMessages(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId);
providerId: providerId, context.read<RequestsVM>().overwriteChatMessagesInRequestsModel(messages: chatMessages, index: customerRequestIndex);
customerId: customerId,
requestOfferId: requestOfferId,
requestId: requestId);
context.read<RequestsVM>().overwriteChatMessagesInRequestsModel(
messages: chatMessages, index: customerRequestIndex);
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (e) { } catch (e) {
logger.i(e.toString()); logger.i(e.toString());
@ -367,16 +349,10 @@ class ChatVM extends ChangeNotifier {
} }
} }
Future<int> onActionOfferTapped( Future<int> onActionOfferTapped({required BuildContext context, required RequestOfferStatusEnum requestOfferStatusEnum, required int reqOfferId}) async {
{required BuildContext context,
required RequestOfferStatusEnum requestOfferStatusEnum,
required int reqOfferId}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
GenericRespModel genericRespModel = GenericRespModel genericRespModel = await requestRepo.updateOfferRequestStatus(requestOfferStatusEnum: requestOfferStatusEnum, requestOfferId: reqOfferId);
await requestRepo.updateOfferRequestStatus(
requestOfferStatusEnum: requestOfferStatusEnum,
requestOfferId: reqOfferId);
Utils.hideLoading(context); Utils.hideLoading(context);
return genericRespModel.messageStatus == 1 ? reqOfferId : -1; return genericRespModel.messageStatus == 1 ? reqOfferId : -1;
} catch (e) { } catch (e) {

@ -33,10 +33,7 @@ class RequestsVM extends BaseVM {
final CommonRepo commonRepo; final CommonRepo commonRepo;
final RequestRepo requestRepo; final RequestRepo requestRepo;
RequestsVM( RequestsVM({required this.commonServices, required this.commonRepo, required this.requestRepo});
{required this.commonServices,
required this.commonRepo,
required this.requestRepo});
List<RequestModel> myRequests = []; List<RequestModel> myRequests = [];
List<RequestModel> myFilteredRequests = []; List<RequestModel> myFilteredRequests = [];
@ -45,27 +42,26 @@ class RequestsVM extends BaseVM {
List<EnumsModel> myRequestsTypeEnum = []; List<EnumsModel> myRequestsTypeEnum = [];
RequestModel? currentSelectedRequest;
void updateCurrentSelectedRequest(RequestModel value) {
currentSelectedRequest = value;
}
populateRequestsFilterList() async { populateRequestsFilterList() async {
if (requestsTypeFilterOptions.isNotEmpty) return; if (requestsTypeFilterOptions.isNotEmpty) return;
if (myRequestsTypeEnum.isEmpty) { if (myRequestsTypeEnum.isEmpty) {
myRequestsTypeEnum = await commonRepo.getEnumTypeValues( myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.requestFilterEnumId);
enumTypeID: 16); //TODO: 16 is to get Requests Filter Enums
} }
for (int i = 0; i < myRequestsTypeEnum.length; i++) { for (int i = 0; i < myRequestsTypeEnum.length; i++) {
requestsTypeFilterOptions.add(FilterListModel( requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue));
title: myRequestsTypeEnum[i].enumValueStr,
isSelected: false,
id: myRequestsTypeEnum[i].enumValue));
} }
log("requestsTypeFilterOptions: ${requestsTypeFilterOptions.toString()}");
notifyListeners(); notifyListeners();
} }
Future<void> getRequests( Future<void> getRequests({bool isNeedToRebuild = false, required AppType appType}) async {
{bool isNeedToRebuild = false, required AppType appType}) async {
if (isNeedToRebuild) setState(ViewState.busy); if (isNeedToRebuild) setState(ViewState.busy);
var paramsForGetRequests = <String, dynamic>{}; var paramsForGetRequests = <String, dynamic>{};
@ -76,29 +72,22 @@ class RequestsVM extends BaseVM {
"requestType": 0, "requestType": 0,
}; };
if (appType == AppType.provider) { if (appType == AppType.provider) {
paramsForGetRequests.addEntries([ paramsForGetRequests.addEntries([MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)]);
MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)
]);
} else { } else {
paramsForGetRequests.addEntries([ paramsForGetRequests.addEntries([MapEntry("customerID", AppState().getUser.data!.userInfo!.customerId)]);
MapEntry("customerID", AppState().getUser.data!.userInfo!.customerId)
]);
} }
myRequests = await requestRepo.getRequests(paramsForGetRequests); myRequests = await requestRepo.getRequests(paramsForGetRequests);
applyFilterOnRequestsVM( applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest);
requestsTypeEnum: RequestsTypeEnum.specialCarRequest);
setState(ViewState.idle); setState(ViewState.idle);
notifyListeners(); notifyListeners();
} }
addChatMessagesInRequestsModel( addChatMessagesInRequestsModel({required ChatMessageModel msg, required int index}) {
{required ChatMessageModel msg, required int index}) {
myFilteredRequests[index].chatMessages.add(msg); myFilteredRequests[index].chatMessages.add(msg);
notifyListeners(); notifyListeners();
} }
overwriteChatMessagesInRequestsModel( overwriteChatMessagesInRequestsModel({required List<ChatMessageModel> messages, required int index}) {
{required List<ChatMessageModel> messages, required int index}) {
myFilteredRequests[index].chatMessages.clear(); myFilteredRequests[index].chatMessages.clear();
myFilteredRequests[index].chatMessages = messages; myFilteredRequests[index].chatMessages = messages;
notifyListeners(); notifyListeners();
@ -109,14 +98,8 @@ class RequestsVM extends BaseVM {
for (var value in requestsTypeFilterOptions) { for (var value in requestsTypeFilterOptions) {
value.isSelected = false; value.isSelected = false;
} }
requestsTypeFilterOptions[ requestsTypeFilterOptions[requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1].isSelected = true; // -1 to match with the index
requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1] myFilteredRequests = myRequests.where((element) => element.requestType == requestsTypeEnum.getIdFromRequestTypeStatusEnum()).toList();
.isSelected = true; // -1 to match with the index
myFilteredRequests = myRequests
.where((element) =>
element.requestType ==
requestsTypeEnum.getIdFromRequestTypeStatusEnum())
.toList();
notifyListeners(); notifyListeners();
} }
@ -125,8 +108,7 @@ class RequestsVM extends BaseVM {
String vehicleImageError = ""; String vehicleImageError = "";
void removeImageFromList(String filePath) { void removeImageFromList(String filePath) {
int index = pickedVehicleImages int index = pickedVehicleImages.indexWhere((element) => element.filePath == filePath);
.indexWhere((element) => element.filePath == filePath);
if (index == -1) { if (index == -1) {
return; return;
} }
@ -156,8 +138,7 @@ class RequestsVM extends BaseVM {
List<VehicleCountryModel> vehicleCountries = []; List<VehicleCountryModel> vehicleCountries = [];
List<VehicleCityModel> vehicleCities = []; List<VehicleCityModel> vehicleCities = [];
SelectionModel requestTypeId = SelectionModel requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionRequestTypeId(SelectionModel id) async { void updateSelectionRequestTypeId(SelectionModel id) async {
requestTypeId = id; requestTypeId = id;
@ -165,8 +146,7 @@ class RequestsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleTypeId = SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
Future<void> getVehicleTypes() async { Future<void> getVehicleTypes() async {
resetRequestCreationForm(); resetRequestCreationForm();
@ -197,8 +177,7 @@ class RequestsVM extends BaseVM {
// } // }
isFetchingVehicleDetail = true; isFetchingVehicleDetail = true;
notifyListeners(); notifyListeners();
vehicleDetails = await commonRepo.getVehicleDetails( vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId);
vehicleTypeId: vehicleTypeId.selectedId);
if (vehicleDetails != null) { if (vehicleDetails != null) {
vehicleBrands = vehicleDetails!.vehicleBrands!; vehicleBrands = vehicleDetails!.vehicleBrands!;
@ -210,30 +189,24 @@ class RequestsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleBrandId = SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleBrandId(SelectionModel id) { void updateSelectionVehicleBrandId(SelectionModel id) {
vehicleBrandId = id; vehicleBrandId = id;
vehicleModelId = vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleModelId = SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelId(SelectionModel id) { void updateSelectionVehicleModelId(SelectionModel id) {
vehicleModelId = id; vehicleModelId = id;
vehicleModelYearId = vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleModelYearId = SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelYearId(SelectionModel id) { void updateSelectionVehicleModelYearId(SelectionModel id) {
vehicleModelYearId = id; vehicleModelYearId = id;
@ -248,21 +221,18 @@ class RequestsVM extends BaseVM {
} }
bool isCountryFetching = false; bool isCountryFetching = false;
SelectionModel vehicleCountryId = SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCountryId(SelectionModel id) async { void updateSelectionVehicleCountryId(SelectionModel id) async {
vehicleCountryId = id; vehicleCountryId = id;
isCountryFetching = true; isCountryFetching = true;
notifyListeners(); notifyListeners();
vehicleCities = await commonRepo.getVehicleCities( vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
countryId: vehicleCountryId.selectedId);
isCountryFetching = false; isCountryFetching = false;
notifyListeners(); notifyListeners();
} }
SelectionModel vehicleCityId = SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCityId(SelectionModel id) { void updateSelectionVehicleCityId(SelectionModel id) {
vehicleCityId = id; vehicleCityId = id;
@ -280,12 +250,10 @@ class RequestsVM extends BaseVM {
description = v; description = v;
} }
Future<RequestPostingImages> convertFileToRequestPostingImages( Future<RequestPostingImages> convertFileToRequestPostingImages({required File file}) async {
{required File file}) async {
List<int> imageBytes = await file.readAsBytes(); List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes); String image = base64Encode(imageBytes);
RequestPostingImages vehiclePostingImages = RequestPostingImages vehiclePostingImages = RequestPostingImages(requestImage: image);
RequestPostingImages(requestImage: image);
return vehiclePostingImages; return vehiclePostingImages;
} }
@ -294,8 +262,7 @@ class RequestsVM extends BaseVM {
log("requestImages: ${pickedVehicleImages.length}"); log("requestImages: ${pickedVehicleImages.length}");
for (var image in pickedVehicleImages) { for (var image in pickedVehicleImages) {
var value = var value = await convertFileToRequestPostingImages(file: File(image.filePath!));
await convertFileToRequestPostingImages(file: File(image.filePath!));
requestImages.add(value); requestImages.add(value);
} }
@ -306,8 +273,7 @@ class RequestsVM extends BaseVM {
if (validateCreateRequestForm()) { if (validateCreateRequestForm()) {
Utils.showLoading(context); Utils.showLoading(context);
List<RequestPostingImages> vehicleImages = List<RequestPostingImages> vehicleImages = await getVehiclePostingImageList();
await getVehiclePostingImageList();
List requestImages = []; List requestImages = [];
vehicleImages.forEach((element) { vehicleImages.forEach((element) {
requestImages.add(element.toJson()); requestImages.add(element.toJson());
@ -377,12 +343,10 @@ class RequestsVM extends BaseVM {
return isValid; return isValid;
} }
Future<List<OffersModel>> getOffersByRequest( Future<List<OffersModel>> getOffersByRequest({required int requestId, required BuildContext context}) async {
{required int requestId, required BuildContext context}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<OffersModel> respModel = List<OffersModel> respModel = await requestRepo.getOffersByRequest(requestId: requestId);
await requestRepo.getOffersByRequest(requestId: requestId);
Utils.hideLoading(context); Utils.hideLoading(context);
return respModel; return respModel;
} catch (e) { } catch (e) {
@ -473,26 +437,22 @@ class RequestsVM extends BaseVM {
ChatMessageModel chatMessageModel = ChatMessageModel( ChatMessageModel chatMessageModel = ChatMessageModel(
isMyMessage: true, isMyMessage: true,
chatText: message, chatText: message,
messageType: messageType: ChatMessageTypeEnum.offer.getIdFromChatMessageTypeEnum(),
ChatMessageTypeEnum.offer.getIdFromChatMessageTypeEnum(),
senderName: senderName, senderName: senderName,
senderUserID: senderId, senderUserID: senderId,
receiverUserID: receiverId, receiverUserID: receiverId,
chatMessageTypeEnum: ChatMessageTypeEnum.offer, chatMessageTypeEnum: ChatMessageTypeEnum.offer,
requestID: requestModel.id, requestID: requestModel.id,
offerStatus: offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
reqOffer: ReqOffer( reqOffer: ReqOffer(
offerStatus: RequestOfferStatusEnum.offer offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
.getIdFromRequestOfferStatusEnum(),
requestID: requestModel.id, requestID: requestModel.id,
price: double.parse(offerPrice), price: double.parse(offerPrice),
requestOfferStatusEnum: RequestOfferStatusEnum.offer, requestOfferStatusEnum: RequestOfferStatusEnum.offer,
comment: message, comment: message,
offerStatusText: "", offerStatusText: "",
)); ));
context.read<ChatVM>().onNewMessageReceived( context.read<ChatVM>().onNewMessageReceived(messages: [chatMessageModel], context: context, isMyOwnOffer: true);
messages: [chatMessageModel], context: context, isMyOwnOffer: true);
if (!isFromChatScreen) { if (!isFromChatScreen) {
ChatViewArguments chatViewArguments = ChatViewArguments( ChatViewArguments chatViewArguments = ChatViewArguments(
chatTypeEnum: ChatTypeEnum.requestOffer, chatTypeEnum: ChatTypeEnum.requestOffer,
@ -502,8 +462,7 @@ class RequestsVM extends BaseVM {
requestIndex: requestIndex, requestIndex: requestIndex,
providerIndex: -1, providerIndex: -1,
); );
navigateWithName(context, AppRoutes.chatView, navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
arguments: chatViewArguments);
} }
} }
} }

@ -104,7 +104,7 @@ class AdCard extends StatelessWidget {
(adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, isBold: true), (adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, isBold: true),
Row( Row(
children: [ children: [
(LocaleKeys.model.tr() + ":").toText( ("${LocaleKeys.model.tr()}:").toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
2.width, 2.width,
@ -113,7 +113,7 @@ class AdCard extends StatelessWidget {
), ),
Row( Row(
children: [ children: [
(LocaleKeys.mileage.tr() + ":").toText( ("${LocaleKeys.mileage.tr()}:").toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
2.width, 2.width,

@ -16,7 +16,6 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class AppointmentDetailView extends StatelessWidget { class AppointmentDetailView extends StatelessWidget {
final AppointmentListModel appointmentListModel; final AppointmentListModel appointmentListModel;
@ -267,7 +266,7 @@ class AppointmentDetailView extends StatelessWidget {
), ),
], ],
15.height, 15.height,
if (appointmentListModel.appointmentStatusEnum != AppointmentStatusEnum.workStarted && appointmentListModel.appointmentStatusEnum != AppointmentStatusEnum.visitCompleted) ...[ if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked || appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed) ...[
Row( Row(
children: [ children: [
CardButtonWithIcon( CardButtonWithIcon(

@ -34,15 +34,11 @@ class ChatView extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return Consumer(builder: return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) {
(BuildContext context, RequestsVM requestsVM, Widget? child) {
return InfoBottomSheet( return InfoBottomSheet(
title: LocaleKeys.makeAnOffer title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
.tr()
.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -64,8 +60,7 @@ class ChatView extends StatelessWidget {
errorValue: requestsVM.offerDescriptionError, errorValue: requestsVM.offerDescriptionError,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(), hint: LocaleKeys.description.tr(),
onChanged: (v) => onChanged: (v) => requestsVM.updateOfferDescription(v),
requestsVM.updateOfferDescription(v),
), ),
], ],
), ),
@ -99,29 +94,21 @@ class ChatView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.chat.tr()), appBar: CustomAppBar(title: LocaleKeys.chat.tr()),
body: Consumer2<ChatVM, RequestsVM>(builder: (BuildContext context, body: Consumer2<ChatVM, RequestsVM>(builder: (BuildContext context, ChatVM chatVM, RequestsVM requestVM, Widget? child) {
ChatVM chatVM, RequestsVM requestVM, Widget? child) {
final chatMessages = AppState().currentAppType == AppType.customer final chatMessages = AppState().currentAppType == AppType.customer
? chatVM.serviceProviderOffersList[chatViewArguments.providerIndex] ? chatVM.serviceProviderOffersList[chatViewArguments.providerIndex].chatMessages
.chatMessages : requestVM.myFilteredRequests[chatViewArguments.requestIndex].chatMessages;
: requestVM.myFilteredRequests[chatViewArguments.requestIndex]
.chatMessages;
return chatMessages == null return chatMessages == null
? Center( ? Center(child: LocaleKeys.noRequestsShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
child: LocaleKeys.noRequestsShow
.tr()
.toText(fontSize: 16, color: MyColors.lightTextColor))
: Column( : Column(
children: [ children: [
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: chatMessages.length, itemCount: chatMessages.length,
separatorBuilder: (BuildContext context, int index) => separatorBuilder: (BuildContext context, int index) => 20.height,
20.height,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ChatMessageModel chatMessageModel = chatMessages[index]; ChatMessageModel chatMessageModel = chatMessages[index];
return ChatMessageCustomWidget( return ChatMessageCustomWidget(chatMessageModel: chatMessageModel);
chatMessageModel: chatMessageModel);
}, },
).horPaddingMain(), ).horPaddingMain(),
), ),
@ -129,54 +116,64 @@ class ChatView extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (AppState().currentAppType == AppType.provider) ...[ if (requestVM.currentSelectedRequest!.requestStatus == RequestStatus.inProgress) ...[
Center(
child: LocaleKeys.requestAlreadyInProgress.tr().toText(
textAlign: TextAlign.center,
color: MyColors.lightTextColor,
fontSize: 14,
),
).paddingAll(15)
] else ...[
if (AppState().currentAppType == AppType.provider) ...[
Expanded(
flex: 1,
child: const Icon(
Icons.local_offer_rounded,
color: MyColors.darkPrimaryColor,
size: 30,
).onPress(
() async {
buildSendOfferBottomSheet(context);
},
),
),
],
Expanded(
flex: 8,
child: TxtField(
value: chatVM.chatMessageText,
hint: LocaleKeys.typeMessageHere.tr(),
keyboardType: TextInputType.text,
isNeedBorder: false,
onChanged: (v) => chatVM.updateChatMessageText(v),
),
),
Expanded( Expanded(
flex: 1, flex: 1,
child: const Icon( child: const Icon(
Icons.local_offer_rounded, Icons.send_rounded,
color: MyColors.darkPrimaryColor, color: MyColors.darkPrimaryColor,
size: 30, size: 30,
).onPress( ).onPress(
() async { () async {
buildSendOfferBottomSheet(context); log("chatViewArguments.requestId:${chatViewArguments.requestId}");
final status = await chatVM.onTextMessageSend(
context: context,
receiverId: chatViewArguments.receiverId,
message: chatVM.chatMessageText,
requestId: chatViewArguments.requestId ?? 0,
offerPrice: "0.0",
chatMessageType: ChatMessageTypeEnum.freeText,
);
if (status) {
chatVM.clearChatMessageText();
}
}, },
), ),
), ),
], ],
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 {
log("chatViewArguments.requestId:${chatViewArguments.requestId}");
final status = await chatVM.onTextMessageSend(
context: context,
receiverId: chatViewArguments.receiverId,
message: chatVM.chatMessageText,
requestId: chatViewArguments.requestId ?? 0,
offerPrice: "0.0",
chatMessageType: ChatMessageTypeEnum.freeText,
);
if (status) {
chatVM.clearChatMessageText();
}
},
),
)
], ],
).toContainer(isShadowEnabled: true), ).toContainer(isShadowEnabled: true),
], ],
@ -193,8 +190,7 @@ class ChatMessageCustomWidget extends StatefulWidget {
const ChatMessageCustomWidget({super.key, required this.chatMessageModel}); const ChatMessageCustomWidget({super.key, required this.chatMessageModel});
@override @override
State<ChatMessageCustomWidget> createState() => State<ChatMessageCustomWidget> createState() => _ChatMessageCustomWidgetState();
_ChatMessageCustomWidgetState();
} }
class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> { class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
@ -204,15 +200,11 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return Consumer( return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
builder: (BuildContext context, ChatVM chatVM, Widget? child) {
return InfoBottomSheet( return InfoBottomSheet(
title: LocaleKeys.makeAnOffer title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
.tr()
.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -223,18 +215,14 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
ListView.separated( ListView.separated(
shrinkWrap: true, shrinkWrap: true,
itemCount: chatVM.offerRejectModelList.length, itemCount: chatVM.offerRejectModelList.length,
separatorBuilder: (BuildContext context, int index) => separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 0.5),
const Divider(thickness: 0.5),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
OfferRequestCommentModel offerRequestCommentModel = OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index];
chatVM.offerRejectModelList[index];
return CircleCheckBoxWithTitle( return CircleCheckBoxWithTitle(
isChecked: isChecked: offerRequestCommentModel.isSelected ?? false,
offerRequestCommentModel.isSelected ?? false,
title: '${offerRequestCommentModel.title}', title: '${offerRequestCommentModel.title}',
onSelected: () { onSelected: () {
chatVM.updateSelectionInOfferRejectModelList( chatVM.updateSelectionInOfferRejectModelList(index);
index);
}, },
selectedColor: MyColors.darkPrimaryColor, selectedColor: MyColors.darkPrimaryColor,
); );
@ -247,8 +235,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
errorValue: chatVM.rejectOfferDescriptionError, errorValue: chatVM.rejectOfferDescriptionError,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(), hint: LocaleKeys.description.tr(),
onChanged: (v) => onChanged: (v) => chatVM.updateRejectOfferDescription(v),
chatVM.updateRejectOfferDescription(v),
), ),
], ],
), ),
@ -267,12 +254,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
); );
} }
Widget buildOfferDetailsInChatMessage( Widget buildOfferDetailsInChatMessage({required ChatMessageModel chatMessageModel, required BuildContext context}) {
{required ChatMessageModel chatMessageModel, final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer;
required BuildContext context}) {
final requestOfferStatusEnum =
chatMessageModel.reqOffer!.requestOfferStatusEnum ??
RequestOfferStatusEnum.offer;
switch (requestOfferStatusEnum) { switch (requestOfferStatusEnum) {
case RequestOfferStatusEnum.offer: case RequestOfferStatusEnum.offer:
@ -282,18 +265,9 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
"${chatMessageModel.reqOffer!.price}".toText( "${chatMessageModel.reqOffer!.price}".toText(fontSize: 19, isBold: true, color: AppState().currentAppType == AppType.provider ? MyColors.white : MyColors.darkTextColor),
fontSize: 19,
isBold: true,
color: AppState().currentAppType == AppType.provider
? MyColors.white
: MyColors.darkTextColor),
5.width, 5.width,
LocaleKeys.sar.tr().toText( LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
color: MyColors.lightTextColor,
height: 2.2,
fontSize: 10,
isBold: true),
], ],
), ),
if (widget.chatMessageModel.isMyMessage == false) ...[ if (widget.chatMessageModel.isMyMessage == false) ...[
@ -308,19 +282,15 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
borderColor: MyColors.greenColor, borderColor: MyColors.greenColor,
isFilled: false, isFilled: false,
onPressed: () async { onPressed: () async {
int status = int status = await context.read<ChatVM>().onActionOfferTapped(
await context.read<ChatVM>().onActionOfferTapped( context: context,
context: context, requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
requestOfferStatusEnum: reqOfferId: chatMessageModel.reqOfferID ?? -1,
RequestOfferStatusEnum.accepted, );
reqOfferId: chatMessageModel.reqOfferID ?? -1,
);
if (status != -1) { if (status != -1) {
log("accepted: $status");
if (chatMessageModel.reqOfferID == status) { if (chatMessageModel.reqOfferID == status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted;
RequestOfferStatusEnum.accepted;
setState(() {}); setState(() {});
} }
} }
@ -358,11 +328,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer( ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.accepted: case RequestOfferStatusEnum.accepted:
@ -374,11 +340,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer( ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.rejected: case RequestOfferStatusEnum.rejected:
@ -390,11 +352,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer( ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.cancel: case RequestOfferStatusEnum.cancel:
@ -406,11 +364,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer( ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
} }
@ -419,9 +373,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Directionality( return Directionality(
textDirection: (widget.chatMessageModel.isMyMessage ?? false) textDirection: (widget.chatMessageModel.isMyMessage ?? false) ? TextDirection.rtl : TextDirection.ltr,
? TextDirection.rtl
: TextDirection.ltr,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -443,10 +395,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
((widget.chatMessageModel.isMyMessage ?? false) ((widget.chatMessageModel.isMyMessage ?? false) ? "You" : widget.chatMessageModel.senderName ?? "").toText(fontSize: 16, isBold: true),
? "You"
: widget.chatMessageModel.senderName ?? "")
.toText(fontSize: 16, isBold: true),
], ],
), ),
5.height, 5.height,
@ -458,13 +407,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Expanded( Expanded(
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: child: (widget.chatMessageModel.chatText ?? "").toText(
(widget.chatMessageModel.chatText ?? "").toText( color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
color:
(widget.chatMessageModel.isMyMessage ?? false)
? MyColors.white
: MyColors.lightTextColor,
fontSize: 12, fontSize: 12,
// isBold: true, // isBold: true,
), ),
@ -472,26 +416,15 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
), ),
], ],
), ),
if (widget.chatMessageModel.chatMessageTypeEnum == if (widget.chatMessageModel.chatMessageTypeEnum == ChatMessageTypeEnum.offer) ...[
ChatMessageTypeEnum.offer) ...[ buildOfferDetailsInChatMessage(chatMessageModel: widget.chatMessageModel, context: context),
buildOfferDetailsInChatMessage(
chatMessageModel: widget.chatMessageModel,
context: context),
], ],
], ],
).toContainer( ).toContainer(
isShadowEnabled: isShadowEnabled: !(widget.chatMessageModel.isMyMessage ?? false),
!(widget.chatMessageModel.isMyMessage ?? false), backgroundColor: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.darkIconColor : MyColors.white,
backgroundColor:
(widget.chatMessageModel.isMyMessage ?? false)
? MyColors.darkIconColor
: MyColors.white,
borderRadius: 0, borderRadius: 0,
margin: EdgeInsets.fromLTRB( margin: EdgeInsets.fromLTRB((widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0, !(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0),
(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0,
0,
!(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0,
0),
), ),
], ],
), ),

@ -1,9 +1,6 @@
import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
@ -11,14 +8,9 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_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/generated/locale_keys.g.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart'; import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
import 'package:mc_common_app/views/user/change_password_page.dart';
import 'package:mc_common_app/views/user/change_password_page.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -46,7 +38,6 @@ class _ProfileScreenState extends State<ProfileScreen> {
backgroundColor: const Color(0xffefefef), backgroundColor: const Color(0xffefefef),
body: Consumer<UserVM>(builder: (_, model, __) { body: Consumer<UserVM>(builder: (_, model, __) {
return Stack( return Stack(
// fit: StackFit.loose,
children: [ children: [
Column( Column(
children: [ children: [
@ -54,29 +45,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
flex: 3, flex: 3,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: AppState() image: AppState().getUser.data!.userInfo!.userLocalImage != null
.getUser
.data!
.userInfo!
.userLocalImage !=
null
? DecorationImage( ? DecorationImage(
image: FileImage(AppState() image: FileImage(AppState().getUser.data!.userInfo!.userLocalImage!),
.getUser
.data!
.userInfo!
.userLocalImage!),
fit: BoxFit.cover, fit: BoxFit.cover,
) )
: AppState().getUser.data!.userInfo!.userImageUrl != : AppState().getUser.data!.userInfo!.userImageUrl != null
null
? DecorationImage( ? DecorationImage(
image: CachedNetworkImageProvider( image: CachedNetworkImageProvider(
AppState() AppState().getUser.data!.userInfo!.userImageUrl,
.getUser
.data!
.userInfo!
.userImageUrl,
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
) )
@ -103,9 +80,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
child: ListView( child: ListView(
children: [ children: [
20.height, 20.height,
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}" "${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25),
.toText(fontSize: 20)
.paddingOnly(left: 25),
Column( Column(
children: [ children: [
CustomProfileOptionsTile( CustomProfileOptionsTile(
@ -116,39 +91,29 @@ class _ProfileScreenState extends State<ProfileScreen> {
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.email.tr(), titleText: LocaleKeys.email.tr(),
subtitleText: subtitleText: "${AppState().getUser.data!.userInfo!.email}",
"${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
Navigator.pushNamed( Navigator.pushNamed(context, AppRoutes.changeEmailPage);
context, AppRoutes.changeEmailPage);
}, },
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.phoneNumber.tr(), titleText: LocaleKeys.phoneNumber.tr(),
subtitleText: subtitleText: "${AppState().getUser.data!.userInfo!.email}",
"${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
Navigator.pushNamed( Navigator.pushNamed(context, AppRoutes.changeMobilePage);
context, AppRoutes.changeMobilePage);
}, },
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.password.tr(), titleText: LocaleKeys.password.tr(),
subtitleText: "************", subtitleText: "************",
onTap: () { onTap: () {
Navigator.pushNamed( Navigator.pushNamed(context, AppRoutes.changePassword);
context, AppRoutes.changePassword);
}, },
), ),
], ],
).toContainer( ).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 20, 24, 0), borderRadius: 0),
width: double.infinity,
isShadowEnabled: true,
paddingAll: 10,
margin: const EdgeInsets.fromLTRB(24, 20, 24, 0),
borderRadius: 0),
], ],
), ),
), ),
@ -161,8 +126,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
height: 90, height: 90,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: ClipOval( child: ClipOval(
child: AppState().getUser.data!.userInfo!.userLocalImage != child: AppState().getUser.data!.userInfo!.userLocalImage != null
null
? Image.file( ? Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!, AppState().getUser.data!.userInfo!.userLocalImage!,
width: 90, width: 90,
@ -170,8 +134,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
fit: BoxFit.fill, fit: BoxFit.fill,
) )
: CachedNetworkImage( : CachedNetworkImage(
imageUrl: imageUrl: "${AppState().getUser.data!.userInfo!.userImageUrl}",
"${AppState().getUser.data!.userInfo!.userImageUrl}",
imageBuilder: (context, imageProvider) => Container( imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
@ -180,10 +143,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
), ),
), ),
), ),
placeholder: (context, url) => placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
const Center(child: CircularProgressIndicator()), errorWidget: (context, url, error) => const Icon(Icons.error),
errorWidget: (context, url, error) =>
const Icon(Icons.error),
width: 90, width: 90,
height: 90, height: 90,
fit: BoxFit.fill, fit: BoxFit.fill,
@ -200,14 +161,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
child: Container( child: Container(
height: 35, height: 35,
width: 35, width: 35,
decoration: BoxDecoration( decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)),
color: MyColors.white, child: const Icon(Icons.edit_note, color: MyColors.darkIconColor, size: 27).paddingOnly(left: 5),
shape: BoxShape.circle,
border:
Border.all(color: MyColors.darkTextColor, width: 0.1)),
child: const Icon(Icons.edit_note,
color: MyColors.darkIconColor, size: 27)
.paddingOnly(left: 5),
).onPress( ).onPress(
() async { () async {
model.updateUserImage(context); model.updateUserImage(context);

@ -23,29 +23,23 @@ class OfferListPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<ServiceProvidersOffers> serviceProviderOffers = final List<ServiceProvidersOffers> serviceProviderOffers = offerListPageArguments.serviceProviderOffers;
offerListPageArguments.serviceProviderOffers;
return Scaffold( return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.offers.tr()), appBar: CustomAppBar(title: LocaleKeys.offers.tr()),
body: serviceProviderOffers.isEmpty body: serviceProviderOffers.isEmpty
? Center( ? Center(child: LocaleKeys.noOffersShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor))
child: LocaleKeys.noOffersShow
.tr()
.toText(fontSize: 16, color: MyColors.lightTextColor))
: ListView.separated( : ListView.separated(
itemCount: serviceProviderOffers.length, itemCount: serviceProviderOffers.length,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
itemBuilder: (context, index) { itemBuilder: (context, index) {
ServiceProvidersOffers offersModel = ServiceProvidersOffers offersModel = serviceProviderOffers[index];
serviceProviderOffers[index];
return Column( return Column(
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(offersModel.name ?? "") (offersModel.name ?? "").toText(fontSize: 16, isBold: true),
.toText(fontSize: 16, isBold: true),
Center( Center(
child: "${offersModel.offerCount}".toText( child: "${offersModel.offerCount}".toText(
color: Colors.white, color: Colors.white,
@ -56,8 +50,8 @@ class OfferListPage extends StatelessWidget {
backgroundColor: MyColors.redColor, backgroundColor: MyColors.redColor,
borderRadius: 100, borderRadius: 100,
paddingAll: 1, paddingAll: 1,
width: 20, width: 22,
height: 20, height: 22,
), ),
], ],
), ),
@ -72,6 +66,13 @@ class OfferListPage extends StatelessWidget {
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
fontSize: 12, fontSize: 12,
), ),
//TODO: createdOn parameter need to be added in the backend
// if (offersModel.createdOn != null) ...[
// DateTime.parse(offersModel.createdOn!).getTimeAgo().toText(
// color: MyColors.lightTextColor,
// ),
// ],
" | 1 hour ago".toText( " | 1 hour ago".toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
fontSize: 12, fontSize: 12,
@ -90,12 +91,10 @@ class OfferListPage extends StatelessWidget {
ChatViewArguments chatViewArguments = ChatViewArguments( ChatViewArguments chatViewArguments = ChatViewArguments(
chatTypeEnum: ChatTypeEnum.requestOffer, chatTypeEnum: ChatTypeEnum.requestOffer,
receiverId: "${offersModel.providerUserId}", receiverId: "${offersModel.providerUserId}",
senderId: senderId: AppState().getUser.data!.userInfo!.userId.toString(),
AppState().getUser.data!.userInfo!.userId.toString(),
requestId: offerListPageArguments.requestId, requestId: offerListPageArguments.requestId,
providerIndex: index, providerIndex: index,
requestIndex: requestIndex: -1, // This will be only send in case of provider
-1, // This will be only send in case of provider
); );
final chatVM = context.read<ChatVM>(); final chatVM = context.read<ChatVM>();
@ -109,8 +108,7 @@ class OfferListPage extends StatelessWidget {
providerOfferIndex: index, providerOfferIndex: index,
) )
.whenComplete( .whenComplete(
() => navigateWithName(context, AppRoutes.chatView, () => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments),
arguments: chatViewArguments),
); );
}).toContainer(isShadowEnabled: true); }).toContainer(isShadowEnabled: true);
}, },

@ -13,6 +13,7 @@ import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -22,11 +23,7 @@ class RequestItem extends StatelessWidget {
final AppType appType; final AppType appType;
final int requestIndex; final int requestIndex;
const RequestItem( const RequestItem({super.key, required this.request, required this.appType, required this.requestIndex});
{super.key,
required this.request,
required this.appType,
required this.requestIndex});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -40,16 +37,11 @@ class RequestItem extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Utils.statusContainerChip( Utils.statusContainerChip(text: request.requestStatusName, chipColor: Utils.getChipColorByRequestStatus(request.requestStatus)),
text: request.requestStatusName,
chipColor: Utils.getChipColorByRequestStatus(
request.requestStatus)),
6.height, 6.height,
"${request.brand} ${request.model}" "${request.brand} ${request.model}".toText(fontSize: 16, isBold: true),
.toText(fontSize: 16, isBold: true), showItem("${LocaleKeys.model.tr()}:", "${request.year}"),
showItem((LocaleKeys.model.tr()), "${request.year}"), showItem("${LocaleKeys.customerName.tr()}:", request.customerName),
showItem(
(LocaleKeys.customerName.tr()), request.customerName),
], ],
), ),
), ),
@ -62,28 +54,30 @@ class RequestItem extends StatelessWidget {
child: "${request.offerCount}".toText( child: "${request.offerCount}".toText(
color: Colors.white, color: Colors.white,
isBold: true, isBold: true,
fontSize: 10, fontSize: 12,
), ),
).toContainer( ).toContainer(
backgroundColor: MyColors.redColor, backgroundColor: MyColors.redColor,
borderRadius: 100, borderRadius: 100,
paddingAll: 1, paddingAll: 1,
width: 20, width: 25,
height: 20, height: 25,
), ),
], ],
2.height, 2.height,
request.cityName.toText( request.cityName.toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
"9 Hours Ago".toText( if (request.createdOn != null) ...[
color: MyColors.lightTextColor, DateTime.parse(request.createdOn!).getTimeAgo().toText(
) color: MyColors.lightTextColor,
),
],
], ],
) )
], ],
), ),
showItem((LocaleKeys.description.tr()), request.description), showItem("${LocaleKeys.description.tr()}:", request.description),
showItem("Price Range: ", ""), showItem("Price Range: ", ""),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -109,33 +103,31 @@ class RequestItem extends StatelessWidget {
), ),
], ],
), ),
const Icon( request.requestStatus == RequestStatus.submitted
Icons.arrow_forward, ? const Icon(
color: MyColors.darkIconColor, Icons.arrow_forward,
size: 18, color: MyColors.darkIconColor,
), size: 18,
)
: const SizedBox()
], ],
), ),
], ],
).toContainer(isShadowEnabled: true).onPress(() async { ).toContainer(isShadowEnabled: true).onPress(() async {
RequestsVM requestsVM = context.read<RequestsVM>();
requestsVM.updateCurrentSelectedRequest(request);
if (request.requestStatus == RequestStatus.pending) { if (request.requestStatus == RequestStatus.pending) {
return; return;
} }
if (appType == AppType.provider) { if (appType == AppType.provider) {
RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments(requestIndex: requestIndex, requestModel: request);
RequestDetailPageArguments( navigateWithName(context, AppRoutes.requestsDetailPage, arguments: requestDetailPageArguments);
requestIndex: requestIndex, requestModel: request);
navigateWithName(context, AppRoutes.requestsDetailPage,
arguments: requestDetailPageArguments);
} else { } else {
ChatVM chatVM = context.read<ChatVM>(); ChatVM chatVM = context.read<ChatVM>();
await chatVM.getOffersFromProvidersByRequest(
requestId: request.id, context: context); await chatVM.getOffersFromProvidersByRequest(requestId: request.id, context: context);
OfferListPageArguments offerListPageArguments = OfferListPageArguments( OfferListPageArguments offerListPageArguments = OfferListPageArguments(serviceProviderOffers: chatVM.serviceProviderOffersList, requestId: request.id);
serviceProviderOffers: chatVM.serviceProviderOffersList, navigateWithName(context, AppRoutes.offersListPage, arguments: offerListPageArguments);
requestId: request.id);
navigateWithName(context, AppRoutes.offersListPage,
arguments: offerListPageArguments);
} }
}); });
} }

Loading…
Cancel
Save