aamir_dev
Faiz Hashmi 10 months ago
parent f8514aaf7b
commit 2215bbd63b

@ -793,5 +793,9 @@
"companyNameMandatory": "اسم الشركة إلزامي",
"connectionProblem": "مشكلة في الاتصال",
"pleaseCheckConnection": "يرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى",
"ok": "نعم"
"ok": "نعم",
"continueAsGuest": "الاستمرار كضيف",
"loginToViewAppointments": "الرجاء تسجيل الدخول لعرض المواعيد",
"itemType": "غرض"
}

@ -791,5 +791,8 @@
"addServiceDetails": "Add service details",
"connectionProblem": "Connection Problem",
"pleaseCheckConnection": "Please check your internet connection and try again.",
"ok": "Ok"
"ok": "Ok",
"continueAsGuest": "Continue as a guest",
"loginToViewAppointments": "Please Login to View Appointments",
"itemType": "Item Type"
}

@ -52,9 +52,7 @@ import 'package:mc_common_app/widgets/image_viewer/image_viewer_screen.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
class AppRoutes {
//User
static const String splash = "/splash";
static const String registerSelection = "/registerSelection";
@ -187,28 +185,12 @@ class AppRoutes {
registerProvider: (context) => const RegisterProviderPage(),
forgetPassword: (context) => const ForgetPasswordPage(),
loginVerification: (context) => const LoginVerificationPage(),
loginWithPassword: (context) => const LoginWithPassword(),
loginMethodSelection: (context) =>
LoginMethodSelectionPage(ModalRoute
.of(context)!
.settings
.arguments as String),
completeProfile: (context) =>
CompleteProfilePage(ModalRoute
.of(context)!
.settings
.arguments as RegisterUserRespModel),
loginWithPassword: (context) => LoginWithPassword(isRemoveBackButton: (ModalRoute.of(context)!.settings.arguments ?? true) as bool),
loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String),
completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUserRespModel),
verifyPassword: (context) => VerifyPasswordPage(),
confirmNewPasswordPage: (context) =>
ConfirmNewPasswordPage(ModalRoute
.of(context)!
.settings
.arguments as String),
forgetPasswordMethodPage: (context) =>
ForgetPasswordMethodPage(ModalRoute
.of(context)!
.settings
.arguments as String),
confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String),
forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String),
changeMobilePage: (context) => ChangeMobilePage(),
changeEmailPage: (context) => const ChangeEmailPage(),
updateUserDetails: (context) => const UpdateUserDetails(),
@ -221,66 +203,30 @@ class AppRoutes {
providerLicensePage: (context) => const ProviderLicensePage(),
// common pages
AppRoutes.adsDetailView: (context) =>
AdsDetailView(adDetails: ModalRoute
.of(context)!
.settings
.arguments as AdDetailsModel),
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(),
AppRoutes.adsFilterView: (context) => const AdsFilterView(),
AppRoutes.selectAdTypeView: (context) =>
SelectAdTypeView(arguments: ModalRoute
.of(context)!
.settings
.arguments as List<dynamic>),
AppRoutes.chatView: (context) =>
ChatView(chatViewArguments: ModalRoute
.of(context)!
.settings
.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) =>
AdsBuyerChatsView(buyersListViewArguments: ModalRoute
.of(context)!
.settings
.arguments as List<BuyersChatForAdsModel>),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<dynamic>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),
AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(),
AppRoutes.settingOptionsContactUs: (context) => const SettingOptionsContactUs(),
AppRoutes.settingOptionsAppInfo: (context) => const SettingOptionsAppInfo(),
AppRoutes.settingOptionsTermsAndConditions: (context) => const SettingOptionsTermsAndConditions(),
AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(),
AppRoutes.paymentMethodsView: (context) =>
PaymentMethodsView(paymentType: ModalRoute
.of(context)!
.settings
.arguments as PaymentTypes),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
//Requests
AppRoutes.requestsDetailPage: (context) =>
RequestDetailPage(requestDetailPageArguments: ModalRoute
.of(context)!
.settings
.arguments as RequestDetailPageArguments),
AppRoutes.requestsDetailPage: (context) => RequestDetailPage(requestDetailPageArguments: ModalRoute.of(context)!.settings.arguments as RequestDetailPageArguments),
AppRoutes.createRequestPage: (context) => const CreateRequestPage(),
AppRoutes.offersListPage: (context) =>
OfferListPage(requestId: ModalRoute
.of(context)!
.settings
.arguments as int),
AppRoutes.offersListPage: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int),
AppRoutes.reviewRequestOffer: (context) => const ReviewRequestOffer(),
AppRoutes.requestsFilterView: (context) => const RequestsFilterView(),
//MediaViewer
AppRoutes.mediaViewerScreen: (context) =>
MediaViewerScreen(images: ModalRoute
.of(context)!
.settings
.arguments as List<MessageImageModel>),
AppRoutes.mediaViewerScreen: (context) => MediaViewerScreen(images: ModalRoute.of(context)!.settings.arguments as List<MessageImageModel>),
// ChatsList Provider
AppRoutes.generalChatsListForProvider: (context) =>
OfferListPage(requestId: ModalRoute
.of(context)!
.settings
.arguments as int),
AppRoutes.generalChatsListForProvider: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int),
//Shipping
AppRoutes.shippingManagementView: (context) => const ShippingManagementView(),

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
abstract class LocaleKeys {
abstract class LocaleKeys {
static const firstTimeLogIn = 'firstTimeLogIn';
static const signUp = 'signUp';
static const changeMobile = 'changeMobile';
@ -47,7 +47,7 @@ abstract class LocaleKeys {
static const emailChangedSuccessfully = 'emailChangedSuccessfully';
static const passwordIsUpdated = 'passwordIsUpdated';
static const passwordShouldContains = 'passwordShouldContains';
static const successfullyRegistered = ' successfullyRegistered';
static const successfullyRegistered = ' successfullyRegistered';
static const pleaseEnterSamePassword = 'pleaseEnterSamePassword';
static const firstNameMandatory = 'firstNameMandatory';
static const surnameNameMandatory = 'surnameNameMandatory';
@ -764,14 +764,17 @@ abstract class LocaleKeys {
static const tapToView = 'tapToView';
static const noServicesAvailableToCopy = 'noServicesAvailableToCopy';
static const copySelectedItems = 'copySelectedItems';
static const companyNameMandatory = 'companyNameMandatory';
static const noOfInvites = 'noOfInvites';
static const noSpecialServicesAvailable = 'noSpecialServicesAvailable';
static const customService = 'customService';
static const selectServiceDetails = 'selectServiceDetails';
static const addServiceDetails = 'addServiceDetails';
static const companyNameMandatory = 'companyNameMandatory';
static const connectionProblem = 'connectionProblem';
static const pleaseCheckConnection = 'pleaseCheckConnection';
static const ok = 'ok';
static const continueAsGuest = 'continueAsGuest';
static const loginToViewAppointments = 'loginToViewAppointments';
static const itemType = 'itemType';
}

@ -12,8 +12,22 @@ class ShippingRequestModel {
String? createdOn;
int? customerID;
String? customerName;
int? vehicleTypeID;
String? vehicleType;
ShippingRequestModel({this.id, this.requestID, this.request, this.shippingStatus, this.deliveredOn, this.comment, this.createdOn, this.customerID, this.customerName});
ShippingRequestModel({
this.id,
this.requestID,
this.request,
this.shippingStatus,
this.deliveredOn,
this.comment,
this.createdOn,
this.customerID,
this.customerName,
this.vehicleTypeID,
this.vehicleType,
});
ShippingRequestModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -26,22 +40,8 @@ class ShippingRequestModel {
createdOn = json['createdOn'];
customerID = json['customerID'];
customerName = json['customerName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['requestID'] = requestID;
if (request != null) {
data['request'] = request!.toJson();
}
data['shippingStatus'] = shippingStatus;
data['deliveredOn'] = deliveredOn;
data['comment'] = comment;
data['createdOn'] = createdOn;
data['customerID'] = customerID;
data['customerName'] = customerName;
return data;
vehicleTypeID = json['vehicleTypeID'];
vehicleType = json['vehicleType'];
}
}

@ -27,13 +27,13 @@ abstract class PaymentService {
class PaymentServiceImp implements PaymentService {
MyInAppBrowser? myInAppBrowser;
var inAppBrowserOptions = InAppBrowserClassSettings(
webViewSettings: InAppWebViewSettings(
useShouldOverrideUrlLoading: false,
transparentBackground: false,
isInspectable: false,
applePayAPIEnabled: true,
cacheEnabled: false,
allowsBackForwardNavigationGestures: false,
),
browserSettings: InAppBrowserSettings(
hideUrlBar: true,
@ -42,7 +42,7 @@ class PaymentServiceImp implements PaymentService {
hideToolbarBottom: true,
hideToolbarTop: false,
hideCloseButton: false,
allowGoBackWithBackButton: true,
allowGoBackWithBackButton: false,
toolbarBottomBackgroundColor: Colors.black,
closeButtonColor: Colors.white,
presentationStyle: ModalPresentationStyle.FULL_SCREEN,

@ -344,7 +344,9 @@ class AdVM extends BaseVM {
pageIndexForMyAds = 1;
hasMoreDataForMyAds = true;
setState(ViewState.busy);
myAds = await adsRepo.getAllAds(isMyAds: true);
if (!AppState().getIsViewOnly) {
myAds = await adsRepo.getAllAds(isMyAds: true);
}
myAdsFilteredList = myAds;
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;

@ -64,9 +64,6 @@ class DashboardVmCustomer extends BaseVM {
RequestsVM requestsVM = Provider.of<RequestsVM>(context, listen: false);
ChatVM chatVM = Provider.of<ChatVM>(context, listen: false);
appointmentsVM.populateBranchesFilterList();
appointmentsVM.populateAppointmentsFilterList();
adVM.populateAdsFilterList();

@ -37,6 +37,7 @@ class DashboardVMProvider extends BaseVM {
void onNavbarTapped(int index) async {
logger.i(AppState().getDeviceToken);
selectedNavbarBarIndex = index;
notifyListeners();
}

@ -136,7 +136,7 @@ class PaymentVM extends ChangeNotifier {
}
},
onSuccess: () async {
Utils.showToast("Verifying Payment..");
// Utils.showToast("Verifying Payment..");
switch (paymentTypeEnum) {
case PaymentTypes.subscription:

@ -65,7 +65,7 @@ class AdsListWidget extends StatelessWidget {
isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus,
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
});
},
separatorBuilder: (BuildContext context, int index) {

@ -59,7 +59,7 @@ class AdsFragment extends StatelessWidget {
})
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: SizedBox(
width: double.infinity,
@ -91,8 +91,8 @@ class AdsFragment extends StatelessWidget {
},
),
),
if(!AppState().getIsViewOnly) 12.width,
if(!AppState().getIsViewOnly) Expanded(
12.width,
Expanded(
child: ShowFillButton(
isFilled: !adVM.isExploreAdsTapped,
txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
@ -102,7 +102,9 @@ class AdsFragment extends StatelessWidget {
onPressed: () {
adVM.updateIsExploreAds(false);
},
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
),
],
).horPaddingMain(),
@ -118,17 +120,16 @@ class AdsFragment extends StatelessWidget {
needLeftPadding: false,
).paddingOnly(left: 21),
]
] else
...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum());
},
needLeftPadding: false,
).paddingOnly(left: 21),
],
] else ...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum());
},
needLeftPadding: false,
).paddingOnly(left: 21),
],
],
);
},
@ -138,46 +139,38 @@ class AdsFragment extends StatelessWidget {
child: RefreshIndicator(
onRefresh: () async {
if (adVM.isExploreAdsTapped) {
int vehicleBrandId = adVM.exploreAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id;
int vehicleBrandId = adVM.exploreAdsFilterOptions.firstWhere((element) => element.isSelected).id;
adVM.applyFilterOnExploreAds(vehicleBrandId: vehicleBrandId);
} else {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id
.toAdPostEnum();
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum();
adVM.applyFilterOnMyAds(adPostStatusEnum: adPostStatusEnum);
}
},
child: adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: AdsListWidget(
isAdsFragment: true,
shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: getAdsList(adVM),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
onFetchMoreAds: () async {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id
.toAdPostEnum();
isAdsFragment: true,
shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: getAdsList(adVM),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
onFetchMoreAds: () async {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum();
if (adVM.isExploreAdsTapped) {
await adVM.fetchMoreExploreAds();
} else {
await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum);
}
},
),
if (adVM.isExploreAdsTapped) {
await adVM.fetchMoreExploreAds();
} else {
await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum);
}
},
),
),
),
if (adVM.isLoadingMore) ...[
const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
))
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
))
]
],
),
@ -197,14 +190,12 @@ class AdsFragment extends StatelessWidget {
}
}
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector
.get<AppState>()
.currentAppType == AppType.provider, false, -1]);
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector.get<AppState>().currentAppType == AppType.provider, false, -1]);
},
backgroundColor: MyColors.darkPrimaryColor,
child: const Icon(Icons.add, color: MyColors.white),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
);
},

@ -95,7 +95,7 @@ class MyRequestsFragment extends StatelessWidget {
})
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: Container(
color: MyColors.backgroundColor,
@ -178,7 +178,7 @@ class MyRequestsFragment extends StatelessWidget {
navigateWithName(context, AppRoutes.offersListPage, arguments: request.id);
}
}).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
);
},
@ -201,7 +201,7 @@ class MyRequestsFragment extends StatelessWidget {
color: MyColors.white,
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
})
: null,
);

@ -186,6 +186,9 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
),
("${shippingRequest.request!.brand} ${shippingRequest.request!.model} | ${shippingRequest.requestID.toString()}").toText(fontSize: 16),
(shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
if (shippingRequest.vehicleType != null && shippingRequest.vehicleType!.isNotEmpty) ...[
("${LocaleKeys.itemType.tr()}: " "${shippingRequest.vehicleType}" ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
],
if (shippingRequest.comment != null && shippingRequest.comment!.isNotEmpty) ...[
("${LocaleKeys.comment.tr()}: ${shippingRequest.comment ?? ""}").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
],

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:developer';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -21,7 +22,9 @@ import 'package:provider/provider.dart';
import '../../utils/enums.dart';
class LoginWithPassword extends StatefulWidget {
const LoginWithPassword({Key? key}) : super(key: key);
final bool isRemoveBackButton;
const LoginWithPassword({super.key, this.isRemoveBackButton = true});
@override
State<LoginWithPassword> createState() => _LoginWithPasswordState();
@ -84,7 +87,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(isRemoveBackButton: true, title: ""),
appBar: CustomAppBar(isRemoveBackButton: widget.isRemoveBackButton, title: ""),
body: Container(
width: double.infinity,
height: double.infinity,

@ -22,7 +22,7 @@ import 'package:sizer/sizer.dart';
import '../../theme/colors.dart';
class RegisterSelectionPage extends StatefulWidget {
const RegisterSelectionPage({Key? key}) : super(key: key);
const RegisterSelectionPage({super.key});
@override
State<RegisterSelectionPage> createState() => _RegisterSelectionPageState();
@ -59,14 +59,14 @@ class _RegisterSelectionPageState extends State<RegisterSelectionPage> {
SvgPicture.asset(MyAssets.logo),
Utils.mFlex(4),
LocaleKeys.welcomeMessage.tr().toText(
fontSize: 20,
letterSpacing: -1.44,
fontSize: 22,
letterSpacing: -1,
),
10.height,
LocaleKeys.welcomeDes.tr().toText(
color: MyColors.lightTextColor,
fontSize: 14,
fontSize: 16,
height: 23 / 24,
letterSpacing: -0.48,
),
Utils.mFlex(1),
ShowFillButton(
@ -93,30 +93,22 @@ class _RegisterSelectionPageState extends State<RegisterSelectionPage> {
),
20.height,
ShowFillButton(
title: "Guest View",
maxWidth: double.infinity,
horizontalMargin: 20,
onPressed: () {
appState.setIsViewOnly = true;
AppState().setUser = User(data: UserData(userInfo: GuestConsts().userInfo, accessToken: null, expiryDate: DateTime.now()));
navigateReplaceWithName(context, AppRoutes.dashboard);
},
),
10.height,
Utils.mFlex(3),
// TextButton(
// onPressed: () {},
// child: const Text(
// "Continue as Guest",
// style: TextStyle(
// color: MyColors.darkPrimaryColor,
// fontWeight: FontWeight.bold,
// decoration: TextDecoration.underline,
// ),
// ),
// ),
// 10.height,
if (AppState().currentAppType == AppType.customer) ...[
TextButton(
onPressed: () {
appState.setIsViewOnly = true;
AppState().setUser = User(data: UserData(userInfo: GuestConsts().userInfo, accessToken: null, expiryDate: DateTime.now()));
navigateReplaceWithName(context, AppRoutes.dashboard);
},
child: LocaleKeys.continueAsGuest.tr().toText(color: MyColors.darkTextColor, fontSize: 18),
),
10.height,
],
TextButton(
onPressed: () {},
child: Text(

@ -9,9 +9,9 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomBottomNavbar extends StatelessWidget {
final int selectedNavbarBarIndex;
final Function(int) onSelected;
bool isProvider;
final bool isProvider;
CustomBottomNavbar({Key? key, required this.onSelected, required this.selectedNavbarBarIndex, this.isProvider = false}) : super(key: key);
const CustomBottomNavbar({super.key, required this.onSelected, required this.selectedNavbarBarIndex, this.isProvider = false});
@override
Widget build(BuildContext context) {

@ -18,7 +18,7 @@ class FiltersList extends StatelessWidget {
this.padding,
required this.filterList,
this.needLeftPadding = true,
this.showImages = true,
this.showImages = false,
required this.onFilterTapped,
});
@ -56,7 +56,7 @@ class FiltersList extends StatelessWidget {
children: [
// Icon before the text
if (showImages) ...[
if (index != 0 && filterList[index].iconUrl.isNotEmpty) ...[
if (index != 0 && filterList[index].iconUrl.isNotEmpty) ...[
filterList[index].iconUrl.buildNetworkImage(height: 25, width: 25, fit: BoxFit.contain),
const SizedBox(width: 4), // Space between icon and text
],

@ -440,7 +440,7 @@ extension ViewOnlyExtension on Widget {
extension PreferredSizeWidgetViewOnlyExtension on PreferredSizeWidget {
PreferredSizeWidget toViewOnly(BuildContext context, {required Function() onTap}) {
return PreferredSize(
preferredSize: this.preferredSize,
preferredSize: preferredSize,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {

Loading…
Cancel
Save