Fixed Bugs

master
FaizHashmi 1 month ago
parent 7669b6eca3
commit 64e2631cff

@ -124,17 +124,16 @@ class ApiClientImp implements ApiClient {
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
}
Future<Response> _postForResponse(
String url,
requestBody, {
String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0,
}) async {
Future<Response> _postForResponse(String url,
requestBody, {
String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0,
}) async {
try {
var headers0 = <String, String>{};
// Add Accept-Language header based on current locale
headers0['Accept-Language'] = _getCurrentLanguage();
@ -211,7 +210,8 @@ class ApiClientImp implements ApiClient {
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
var httpClient = HttpClient()
..badCertificateCallback = _certificateCheck;
var client = IOClient(httpClient);
try {
return await fn(client);
@ -254,7 +254,7 @@ class ApiClientImp implements ApiClient {
Future<Response> _getForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
try {
var headers0 = <String, String>{};
// Add Accept-Language header based on current locale
headers0['Accept-Language'] = _getCurrentLanguage();

@ -61,16 +61,15 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
'mowater_chat_channel', // More descriptive channel ID
'Chat Notifications',
description: 'Notifications for chat messages',
importance: Importance.max, // Changed to max for Android 14
importance: Importance.max,
// Changed to max for Android 14
playSound: true,
enableVibration: true,
showBadge: true,
);
await flutterLocalNotifications
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await flutterLocalNotifications.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel);
log("✅ Android notification channel created: ${channel.id}");
}
@ -141,6 +140,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
log("Data payload: ${message.data}");
log("Message ID: ${message.messageId}");
log("Sent time: ${message.sentTime}");
log("Android config: ${message.toMap()}");
log("======================================================");
// Just display notification - DON'T navigate automatically
@ -192,7 +192,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
// Backend sends NotiType as string: "1" = Request, "2" = Ads, "3" = General
String? notiTypeStr = data['NotiType'];
int? notiType = int.tryParse(notiTypeStr ?? '');
log("NotiType from backend: $notiTypeStr (parsed: $notiType)");
if (notiType == null || notiType < 1 || notiType > 3) {
@ -264,7 +264,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
try {
// Try both backend format and our format
int requestId = int.tryParse(data['RequestID']?.toString() ?? data['request_id']?.toString() ?? '0') ?? 0;
if (requestId == 0) {
log("❌ Invalid or missing RequestID in notification data");
return;
@ -273,7 +273,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
log("✅ Navigating to providers chat list for request: $requestId");
navigateWithName(context, AppRoutes.providersChatListPage);
// TODO: If backend sends all required data (ProviderId, CustomerId),
// TODO: If backend sends all required data (ProviderId, CustomerId),
// we can navigate directly to the chat screen
} catch (e) {
logger.e("Error navigating to request chat: $e");
@ -327,7 +327,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService {
try {
// Try both backend format and our format
int requestId = int.tryParse(data['RequestID']?.toString() ?? data['request_id']?.toString() ?? '0') ?? 0;
if (requestId == 0) {
log("❌ Invalid or missing RequestID in notification data");
return;

@ -2178,7 +2178,7 @@ class AdVM extends BaseVM {
}
VehiclePosting vehiclePosting = VehiclePosting(
id: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
id: isExtendAdEditEnabled ? null : (isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null),
userID: appState.getUser.data!.userInfo!.userId,
vehicleType: vehicleTypeId.selectedId,
vehicleModelID: vehicleModelId.selectedId,
@ -2647,6 +2647,11 @@ class AdVM extends BaseVM {
setState(ViewState.busy);
}
// Auto-add current typed Ad ID to history if not empty and not already in list
if (currentAdIDFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adsFilterAdIDSearchHistory, value: currentAdIDFilter)) {
addAdFilterAdIDSearchHistory(value: currentAdIDFilter);
}
List<String> adIdsList = [];
if (adsFilterAdIDSearchHistory.isNotEmpty) {
for (var element in adsFilterAdIDSearchHistory) {
@ -2700,6 +2705,11 @@ class AdVM extends BaseVM {
}
}
// Auto-add current typed phone number to history if not empty and not already in list
if (currentAdMobilePhoneFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adFilterMobilePhoneSearchHistory, value: currentAdMobilePhoneFilter)) {
addAdFilterMobilePhoneSearchHistory(value: currentAdMobilePhoneFilter);
}
List<String> phoneNumbersList = [];
if (adFilterMobilePhoneSearchHistory.isNotEmpty) {
for (var element in adFilterMobilePhoneSearchHistory) {
@ -2753,7 +2763,7 @@ class AdVM extends BaseVM {
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) {
isAdEditEnabled = true;
isDraftEditEnabled = true;
isDraftEditEnabled = isForDraft; // Only true if editing a draft
isExtendAdEditEnabled = isFromExtendAd;
previousAdDetails = previousDetails;
autoFillSelectedVehicleType();

@ -107,21 +107,39 @@ class DashboardVmCustomer extends BaseVM with WidgetsBindingObserver {
RequestsVM requestsVM = Provider.of<RequestsVM>(context, listen: false);
ChatVM chatVM = Provider.of<ChatVM>(context, listen: false);
// Set loading state immediately to prevent "No data" flash
adVM.setState(ViewState.busy);
appointmentsVM.setState(ViewState.busy);
requestsVM.setState(ViewState.busy);
// ✅ Inject ViewModels into ChatVM (only needs to be done once, but safe to repeat)
chatVM.setViewModels(requestsVM: requestsVM, adVM: adVM);
await appointmentsVM.populateBranchesFilterList();
await appointmentsVM.populateAppointmentsFilterList();
await adVM.populateAdsFilterList();
await requestsVM.populateDataForRequestsFilter();
await requestsVM.populateDeliveryOptionEnums();
await appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true);
await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches!
await appointmentsVM.getMyRecentBranches(); // to get my recent branches
// Call independent filter population APIs in parallel
await Future.wait<dynamic>([
appointmentsVM.populateBranchesFilterList(),
appointmentsVM.populateAppointmentsFilterList(),
adVM.populateAdsFilterList(),
requestsVM.populateDataForRequestsFilter(),
requestsVM.populateDeliveryOptionEnums(),
adVM.getVehicleTypes(),
adVM.getVehicleAdsDuration(),
]);
// Call data APIs in parallel
await Future.wait<dynamic>([
appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true),
appointmentsVM.applyFilterOnBranches(index: 0), // to get all branches!
appointmentsVM.getMyRecentBranches(), // to get my recent branches
requestsVM.getRequests(),
]);
// Call ads APIs in parallel (conditionally)
if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit && dashboardRouteEnum != DashboardRouteEnum.fromReserveAdsPayment) {
await adVM.getMyAds();
await adVM.getExploreAds();
await Future.wait<dynamic>([
adVM.getMyAds(),
adVM.getExploreAds(),
]);
}
// Handle different payment completion scenarios
@ -143,9 +161,7 @@ class DashboardVmCustomer extends BaseVM with WidgetsBindingObserver {
log("✅ Successfully navigated to Appointments after payment");
}
await requestsVM.getRequests();
await adVM.getVehicleTypes();
await adVM.getVehicleAdsDuration();
// Build chat hub connection last
await chatVM.buildHubConnection(context: context);
// if (appointmentsVM.myAppointments.isEmpty) {

@ -131,21 +131,46 @@ class DashboardVMProvider extends BaseVM with WidgetsBindingObserver {
final adVM = context.read<AdVM>();
final subscriptionsVM = context.read<SubscriptionsVM>();
// Set loading state immediately to prevent "No data" flash
adVM.setState(ViewState.busy);
appointmentVM.setState(ViewState.busy);
requestsVM.setState(ViewState.busy);
serviceVM.setState(ViewState.busy);
// ✅ Inject ViewModels into ChatVM (only needs to be done once, but safe to repeat)
chatVM.setViewModels(requestsVM: requestsVM, adVM: adVM);
await requestsVM.populateDataForRequestsFilter();
await requestsVM.populateDeliveryOptionEnums();
await appointmentVM.populateAppointmentsFilterList();
await adVM.populateAdsFilterList();
await serviceVM.populateBranchServiceFilters();
await serviceVM.getBranchAndServices();
await requestsVM.getRequests();
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);
// Call independent filter population APIs in parallel
await Future.wait<dynamic>([
requestsVM.populateDataForRequestsFilter(),
requestsVM.populateDeliveryOptionEnums(),
appointmentVM.populateAppointmentsFilterList(),
adVM.populateAdsFilterList(),
serviceVM.populateBranchServiceFilters(),
shippingManagementVM.populateShippingRequestFilterList(),
shippingManagementVM.populateSelfPickupRequestFilterList(),
adVM.getVehicleTypes(),
adVM.getVehicleAdsDuration(),
]);
// Call data APIs in parallel
await Future.wait<dynamic>([
serviceVM.getBranchAndServices(),
requestsVM.getRequests(),
subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true),
appointmentVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
shouldPopulateUpcoming: true,
),
]);
// Call ads APIs in parallel (conditionally)
if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit && dashboardRouteEnum != DashboardRouteEnum.fromReserveAdsPayment) {
await adVM.getMyAds();
await adVM.getExploreAds();
await Future.wait<dynamic>([
adVM.getMyAds(),
adVM.getExploreAds(),
]);
}
// Handle reserve ads payment completion
@ -156,16 +181,7 @@ class DashboardVMProvider extends BaseVM with WidgetsBindingObserver {
log("✅ Successfully navigated to Reserved Ads after payment");
}
await shippingManagementVM.populateShippingRequestFilterList();
await shippingManagementVM.populateSelfPickupRequestFilterList();
await appointmentVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
shouldPopulateUpcoming: true,
);
await adVM.getVehicleTypes();
await adVM.getVehicleAdsDuration();
// Build chat hub connection last
await chatVM.buildHubConnection(context: context);
}

@ -85,7 +85,8 @@ class SubscriptionsVM extends BaseVM {
}
}
Future<GenericRespModel> payForSubscription(int subscriptionId, bool isStartNow, bool isReview, String amount, {bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
Future<GenericRespModel> payForSubscription(
{required int subscriptionId, required bool isStartNow, required bool isRenew, required String amount, bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
Map<String, dynamic> map;
if (isDegrade) {
map = {
@ -95,7 +96,7 @@ class SubscriptionsVM extends BaseVM {
"subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(),
"subscriptionAmount": amount,
"isRenew": isReview.toString(),
"isRenew": isRenew.toString(),
"listOfBranches": listOfBranches,
"listOfUsers": listOfUsers
};
@ -107,7 +108,7 @@ class SubscriptionsVM extends BaseVM {
"subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(),
"subscriptionAmount": amount,
"isRenew": isReview.toString()
"isRenew": isRenew.toString()
// "listOfBranches": [],
// "listOfUsers": []
};
@ -116,8 +117,14 @@ class SubscriptionsVM extends BaseVM {
return genericRespModel;
}
Future<GenericRespModel> createSubscriptionOrder(int subscriptionId, bool isStartNow, bool isRenew, {bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
Map<String, dynamic> map = {"providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "", "subscriptionID": subscriptionId.toString(), "isStartNow": isStartNow.toString(), "isRenew": isRenew.toString()};
Future<GenericRespModel> createSubscriptionOrder(
{required int subscriptionId, required bool isStartNow, required bool isRenew, bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
Map<String, dynamic> map = {
"providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
"subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(),
"isRenew": isRenew.toString()
};
GenericRespModel genericRespModel = await subscriptionRepo.payForProviderSubscription(map);
return genericRespModel;
}
@ -190,9 +197,7 @@ class SubscriptionsVM extends BaseVM {
mySubscriptionsBySp.clear();
setState(ViewState.busy);
// allSubscriptions.data
print("====================== SUB =============");
for (var element in allSubscriptions.data!) {
print("SuBBB "+ element.subscriptionType.toString());
if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) {
mySubscriptionsBySp.add(element);
}

@ -148,7 +148,7 @@ class _AdsDetailViewState extends State<AdsDetailView> {
Row(
children: [
("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.mileage!.mileageEnd} ${LocaleKeys.km.tr()}".toText(fontSize: 12),
"${widget.adDetails.vehicle?.mileage?.mileageStart ?? ""} - ${widget.adDetails.vehicle?.mileage?.mileageEnd ?? ""} (${LocaleKeys.km.tr()})".toText(fontSize: 12),
],
),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, color: MyColors.lightTextColor) : const SizedBox(),
@ -166,12 +166,14 @@ class _AdsDetailViewState extends State<AdsDetailView> {
"${widget.adDetails.vehicle!.odometer ?? 0} ${LocaleKeys.km.tr()}".toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.vehicleCondition.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
(widget.adDetails.vehicle!.isInUsed == 0 ? LocaleKeys.brandNew.tr() : LocaleKeys.used.tr()).toText(fontSize: 12),
],
),
if (widget.adDetails.vehicle!.condition != null && widget.adDetails.vehicle!.condition?.id != null) ...[
Row(
children: [
("${LocaleKeys.vehicleCondition.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
(widget.adDetails.vehicle!.condition?.id == 2 ? LocaleKeys.used.tr() : LocaleKeys.used.tr()).toText(fontSize: 12),
],
),
],
Row(
children: [
("${LocaleKeys.accidentFree.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
@ -602,8 +604,8 @@ class _FavoriteAdButtonState extends State<FavoriteAdButton> with SingleTickerPr
bool success = await context.read<AdVM>().toggleAdFavorite(
adsID: isFavorite && widget.adDetails.favouriteAdID != null
? widget.adDetails.favouriteAdID! // Use favoriteAdsID when unfavoriting
: widget.adDetails.id!, // Use regular ad ID when favoriting
? widget.adDetails.favouriteAdID! // Use favoriteAdsID when unfavoriting
: widget.adDetails.id!, // Use regular ad ID when favoriting
isFavorite: isFavorite,
);
@ -679,7 +681,7 @@ class ShareAdButton extends StatelessWidget {
// Vehicle details
shareMessage += '${vehicle.vehicleTitle ?? ""}\n';
shareMessage += '${LocaleKeys.model.tr()}: ${vehicle.modelyear?.label ?? ""}\n';
shareMessage += '${LocaleKeys.mileage.tr()}: ${vehicle.mileage?.mileageEnd ?? ""}\n';
shareMessage += '${LocaleKeys.mileage.tr()}: ${vehicle.mileage?.mileageStart ?? ""} - ${vehicle.mileage?.mileageEnd ?? ""}\n';
shareMessage += '${LocaleKeys.price.tr()}: ${vehicle.demandAmount?.toInt()} ${vehicle.currency ?? ""}\n';
if (vehicle.cityName != null && vehicle.cityName!.isNotEmpty) {
shareMessage += '${LocaleKeys.location.tr()}: ${vehicle.cityName}\n';

@ -315,6 +315,8 @@ class _AdsFilterViewState extends State<AdsFilterView> {
onChanged: (value) => adVM.onCurrentAdMobilePhoneFilterChanged(value),
value: adVM.currentAdMobilePhoneFilter,
hint: LocaleKeys.enterMobileNumber.tr(),
keyboardType: TextInputType.phone,
numbersOnly: true,
postfixWidget: Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.currentAdMobilePhoneFilter.isEmpty) {

@ -341,11 +341,14 @@ class _AdCardState extends State<AdCard> {
height: 18 / 12,
),
2.width,
(widget.adDetails.vehicle!.mileage!.mileageEnd ?? "").toText(
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
Expanded(
child: "${widget.adDetails.vehicle?.mileage?.mileageStart ?? ""} - ${widget.adDetails.vehicle?.mileage?.mileageEnd ?? ""}km".toText(
overflow: TextOverflow.ellipsis,
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
)
],
),
],
@ -355,8 +358,8 @@ class _AdCardState extends State<AdCard> {
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(widget.adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor, fontSize: 8),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 8) : const SizedBox(),
(widget.adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor, fontSize: 4),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 4) : const SizedBox(),
],
),
],

@ -120,10 +120,15 @@ class BookAppointmentServicesView extends StatelessWidget {
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
const Icon(Icons.arrow_drop_down, size: 30)
],
).onPress(() => appointmentsVM.priceBreakDownClicked(context, serviceData)),
),
],
],
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10));
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10),
onTap: () => appointmentsVM.priceBreakDownClicked(context, serviceData),
);
},
).expand(),
Row(

@ -78,9 +78,7 @@ class AppointmentServicePickBottomSheet extends StatelessWidget {
if (element.categoryId == appointmentsVM.branchSelectedCategoryId.selectedId) {
serviceCategories.add(DropValue(
element.serviceProviderServiceId ?? 0,
isArabic
? element.serviceDescriptionN!
: element.serviceDescription!,
isArabic ? element.serviceDescriptionN! : element.serviceDescription!,
// element.serviceDescription!,
"",
));
@ -218,7 +216,9 @@ class AppointmentServicePickBottomSheet extends StatelessWidget {
appointmentsVM.currentServiceSelection!.rangePricePerKm.toString().toText(fontSize: 30, isBold: true),
"${LocaleKeys.sar.tr()}/km".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
] else ...[
(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService * appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch)
// Calculate using rounded values so displayed math matches the result
(double.parse(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)) *
double.parse(appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)))
.toStringAsFixed(2)
.toText(
fontSize: 30,
@ -226,7 +226,7 @@ class AppointmentServicePickBottomSheet extends StatelessWidget {
),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
10.width,
("(${(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService).toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)} KMs )")
("(${appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)} KMs )")
.toText(fontSize: 13, color: MyColors.lightTextColor)
.paddingOnly(bottom: 5),
],

@ -141,9 +141,7 @@ class RequestDetailPage extends StatelessWidget {
}) {
switch (requestStatus) {
case RequestStatusEnum.submitted:
String chatButtonText = requestTypeEnum == RequestsTypeEnum.specialCarRequest
? LocaleKeys.specialCarRequestChat.tr()
: LocaleKeys.sparePartRequestChat.tr();
String chatButtonText = requestTypeEnum == RequestsTypeEnum.specialCarRequest ? LocaleKeys.specialCarRequestChat.tr() : LocaleKeys.sparePartRequestChat.tr();
return ShowFillButton(
maxWidth: double.infinity,
@ -176,7 +174,7 @@ class RequestDetailPage extends StatelessWidget {
if (status) {
await requestVM.getRequests(isNeedToRebuild: true);
pop(context);
}
}
},
);
}
@ -303,16 +301,17 @@ class RequestDetailPage extends StatelessWidget {
appBar: CustomAppBar(
title: LocaleKeys.requestDetail.tr(),
actions: [
requestDetailPageArguments.requestModel.isChatted
? Padding(
padding: const EdgeInsets.only(top: 8, bottom: 8, right: 21),
child: const Icon(Icons.messenger_outline_rounded, color: Colors.black, size: 18).toContainer(
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
),
).onPress(() => onViewChatTapped(context))
: const SizedBox(),
// requestDetailPageArguments.requestModel.isChatted
// ?
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 8, right: 21),
child: const Icon(Icons.messenger_outline_rounded, color: Colors.black, size: 18).toContainer(
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
),
).onPress(() => onViewChatTapped(context))
// : const SizedBox(),
],
),
body: SizedBox(

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -382,15 +384,14 @@ extension BuildSVG on String? {
this!,
errorBuilder: (BuildContext context, Object obj, StackTrace? s) {
return Container(
height: height,
width: width,
decoration: BoxDecoration(border: Border.all(color: MyColors.roundedCrossBgColor)),
child: Icon(
Icons.image_not_supported_outlined,
color: MyColors.roundedCrossBgColor,
size: width,
),
);
height: height,
width: width,
decoration: BoxDecoration(border: Border.all(color: MyColors.roundedCrossBgColor)),
child: const Icon(
Icons.image_not_supported_outlined,
color: MyColors.roundedCrossBgColor,
// size: width,
));
},
loadingBuilder: (BuildContext context, Widget? child, ImageChunkEvent? imageChunk) {
if (imageChunk == null) {

Loading…
Cancel
Save