|
|
|
|
import 'dart:io';
|
|
|
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
|
import 'package:mc_common_app/classes/app_state.dart';
|
|
|
|
|
import 'package:mc_common_app/config/dependency_injection.dart';
|
|
|
|
|
import 'package:mc_common_app/config/routes.dart';
|
|
|
|
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:mc_common_app/main.dart';
|
|
|
|
|
import 'package:mc_common_app/models/user_models/image_response.dart';
|
|
|
|
|
import 'package:mc_common_app/repositories/user_repo.dart';
|
|
|
|
|
import 'package:mc_common_app/services/common_services.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/navigator.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/shipping_management_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/widgets/common_widgets/add_phone_num_wiget.dart';
|
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
import 'package:mc_common_app/utils/utils.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/ad_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/base_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/widgets/bottom_sheet.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/chat_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/requests_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/service_view_model.dart';
|
|
|
|
|
import 'package:mc_common_app/view_models/subscriptions_view_model.dart';
|
|
|
|
|
|
|
|
|
|
class DashboardVMProvider extends BaseVM with WidgetsBindingObserver {
|
|
|
|
|
final CommonAppServices commonServices;
|
|
|
|
|
final UserRepo userRepo;
|
|
|
|
|
BuildContext? _context; // Store context for lifecycle events
|
|
|
|
|
|
|
|
|
|
DashboardVMProvider({required this.commonServices, required this.userRepo}) {
|
|
|
|
|
// Register as lifecycle observer
|
|
|
|
|
WidgetsBinding.instance.addObserver(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store context when dashboard is initialized
|
|
|
|
|
void setContext(BuildContext context) {
|
|
|
|
|
_context = context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
WidgetsBinding.instance.removeObserver(this);
|
|
|
|
|
_context = null;
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
|
|
|
super.didChangeAppLifecycleState(state);
|
|
|
|
|
logger.i("App lifecycle state changed to: $state");
|
|
|
|
|
|
|
|
|
|
if (_context == null) return;
|
|
|
|
|
|
|
|
|
|
final chatVM = Provider.of<ChatVM>(_context!, listen: false);
|
|
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
|
case AppLifecycleState.resumed:
|
|
|
|
|
// App came back to foreground - ensure SignalR is connected
|
|
|
|
|
logger.i("App resumed - checking SignalR connection");
|
|
|
|
|
chatVM.buildHubConnection(context: _context);
|
|
|
|
|
break;
|
|
|
|
|
case AppLifecycleState.paused:
|
|
|
|
|
// App went to background - keep connection alive (as per user requirement)
|
|
|
|
|
logger.i("App paused - SignalR staying connected");
|
|
|
|
|
break;
|
|
|
|
|
case AppLifecycleState.inactive:
|
|
|
|
|
case AppLifecycleState.detached:
|
|
|
|
|
case AppLifecycleState.hidden:
|
|
|
|
|
// Other states - no action needed
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String pickedImage = "";
|
|
|
|
|
|
|
|
|
|
int selectedNavbarBarIndex = 2;
|
|
|
|
|
|
|
|
|
|
void onNavbarTapped(int index) async {
|
|
|
|
|
logger.i(AppState().getDeviceToken);
|
|
|
|
|
|
|
|
|
|
selectedNavbarBarIndex = index;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pickImageFromPhone(BuildContext context, int sourceFlag) async {
|
|
|
|
|
final File? pickedImageFile = await commonServices.pickImageFromPhone(sourceFlag);
|
|
|
|
|
if (pickedImageFile == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int sizeInBytes = pickedImageFile.lengthSync();
|
|
|
|
|
if (sizeInBytes > 1000000) {
|
|
|
|
|
Utils.showToast(LocaleKeys.fileLarger.tr());
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
String image64 = Utils.convertFileToBase64(pickedImageFile);
|
|
|
|
|
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
ImageResponse response = await userRepo.updateUserImage(image64);
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
if (response.messageStatus == 1) {
|
|
|
|
|
Utils.showToast(LocaleKeys.imageUploaded.tr());
|
|
|
|
|
AppState().getUser.data!.userInfo!.userImageUrl = response.data;
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(response.message ?? "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<ImageResponse> updateUserImage(String image) async {
|
|
|
|
|
return await userRepo.updateUserImage(image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> onRefresh(BuildContext context, {DashboardRouteEnum dashboardRouteEnum = DashboardRouteEnum.none}) async {
|
|
|
|
|
final requestsVM = context.read<RequestsVM>();
|
|
|
|
|
final chatVM = context.read<ChatVM>();
|
|
|
|
|
final appointmentVM = context.read<AppointmentsVM>();
|
|
|
|
|
final shippingManagementVM = context.read<ShippingManagementVM>();
|
|
|
|
|
final serviceVM = context.read<ServiceVM>();
|
|
|
|
|
final adVM = context.read<AdVM>();
|
|
|
|
|
final subscriptionsVM = context.read<SubscriptionsVM>();
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit) {
|
|
|
|
|
await adVM.getMyAds();
|
|
|
|
|
await adVM.getExploreAds();
|
|
|
|
|
}
|
|
|
|
|
await shippingManagementVM.populateShippingRequestFilterList();
|
|
|
|
|
await shippingManagementVM.populateSelfPickupRequestFilterList();
|
|
|
|
|
await appointmentVM.applyFilterOnAppointmentsVMForProviders(
|
|
|
|
|
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
|
|
|
|
|
isNeedCustomerFilter: true,
|
|
|
|
|
shouldPopulateUpcoming: true,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await adVM.getVehicleTypes();
|
|
|
|
|
await adVM.getVehicleAdsDuration();
|
|
|
|
|
await chatVM.buildHubConnection(context: context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void checkUserSubscription(SubscriptionActionTypeEnum actionType, BuildContext context, {required Function() callback}) async {
|
|
|
|
|
switch (actionType) {
|
|
|
|
|
case SubscriptionActionTypeEnum.ads:
|
|
|
|
|
performCheckOnAds(context);
|
|
|
|
|
break;
|
|
|
|
|
case SubscriptionActionTypeEnum.users:
|
|
|
|
|
performCheckOnUsers(context, callback);
|
|
|
|
|
break;
|
|
|
|
|
case SubscriptionActionTypeEnum.branches:
|
|
|
|
|
performCheckOnBranches(context);
|
|
|
|
|
break;
|
|
|
|
|
case SubscriptionActionTypeEnum.subscription:
|
|
|
|
|
performCheckSubscription(context, callback);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void performCheckOnBranches(BuildContext context) async {
|
|
|
|
|
if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.branchesRemaining! > 0) {
|
|
|
|
|
await navigateWithName(context, AppRoutes.defineBranch);
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(LocaleKeys.upgradeBranches.tr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void performCheckSubscription(BuildContext context, Function() callBack) async {
|
|
|
|
|
if (AppState().getproviderSubscription.isNotEmpty && !AppState().getproviderSubscription.first.isExpired!) {
|
|
|
|
|
callBack();
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(LocaleKeys.upgradeSubscription.tr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void performCheckOnAds(BuildContext context) async {
|
|
|
|
|
if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.adsRemaining! > 0) {
|
|
|
|
|
await navigateWithName(context, AppRoutes.defineBranch);
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(LocaleKeys.upgradeAds.tr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void performCheckOnUsers(BuildContext context, Function() callBack) async {
|
|
|
|
|
if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.subUsersRemaining! > 0) {
|
|
|
|
|
showMyBottomSheet(context, isDismissible: false, isScrollControlled: true, child: AddPhoneNumWidget(), callBackFunc: callBack);
|
|
|
|
|
} else {
|
|
|
|
|
Utils.showToast(LocaleKeys.upgradeSubUsers.tr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|