You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
9.5 KiB
Dart
223 lines
9.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:car_customer_app/config/customer_dependencies.dart';
|
|
import 'package:car_customer_app/config/customer_routes.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:mc_common_app/repositories/branch_repo.dart';
|
|
import 'package:mc_common_app/repositories/chat_repo.dart';
|
|
import 'package:mc_common_app/repositories/appointment_repo.dart';
|
|
import 'package:mc_common_app/repositories/request_repo.dart';
|
|
import 'package:mc_common_app/repositories/setting_options_repo.dart';
|
|
import 'package:mc_common_app/services/ad_deep_link_service.dart';
|
|
import 'package:mc_common_app/services/firebase_service.dart';
|
|
import 'package:mc_common_app/views/splash/splash_page.dart';
|
|
import 'package:mc_common_app/utils/location/Location.dart';
|
|
import 'package:mc_common_app/view_models/appointments_view_model.dart';
|
|
import 'package:mc_common_app/view_models/chat_view_model.dart';
|
|
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
|
|
import 'package:mc_common_app/view_models/requests_view_model.dart';
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
import 'package:flutter/material.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/models/general_models/post_params_model.dart';
|
|
import 'package:mc_common_app/repositories/ads_repo.dart';
|
|
import 'package:mc_common_app/repositories/common_repo.dart';
|
|
import 'package:mc_common_app/repositories/payments_repo.dart';
|
|
import 'package:mc_common_app/repositories/user_repo.dart';
|
|
import 'package:mc_common_app/services/common_services.dart';
|
|
import 'package:mc_common_app/services/payments_service.dart';
|
|
import 'package:mc_common_app/theme/app_theme.dart';
|
|
import 'package:mc_common_app/utils/enums.dart';
|
|
import 'package:mc_common_app/view_models/ad_view_model.dart';
|
|
import 'package:mc_common_app/view_models/base_view_model.dart';
|
|
import 'package:mc_common_app/view_models/payment_view_model.dart';
|
|
import 'package:mc_common_app/view_models/setting_options_view_model.dart';
|
|
import 'package:mc_common_app/view_models/user_view_model.dart';
|
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:provider/single_child_widget.dart';
|
|
import 'package:sizer/sizer.dart';
|
|
import 'package:intl/date_symbol_data_local.dart';
|
|
import 'package:firebase_core/firebase_core.dart';
|
|
import 'package:toastification/toastification.dart';
|
|
|
|
//test commit
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
await EasyLocalization.ensureInitialized();
|
|
if (Platform.isAndroid) {
|
|
await Firebase.initializeApp(
|
|
options: const FirebaseOptions(
|
|
apiKey: 'AIzaSyD1WNNGrbBiCNvCrI31d3DV5AOgToq-Lus',
|
|
appId: '1:294636898500:android:e93b7e5d1cc15ae6b0e191',
|
|
messagingSenderId: '294636898500',
|
|
projectId: 'mowater-2c81a',
|
|
),
|
|
);
|
|
} else {
|
|
await Firebase.initializeApp();
|
|
}
|
|
|
|
CustomerDependencies.addDependencies();
|
|
injector.get<FirebaseMessagingService>().initializeNotifications().whenComplete(() {
|
|
injector.get<Location>().handleLocationPermission();
|
|
});
|
|
CustomerAppRoutes.routes.addAll(AppRoutes.routes);
|
|
initializeDateFormatting().then(
|
|
(_) => runApp(
|
|
MultiProvider(
|
|
providers: <SingleChildWidget>[
|
|
ChangeNotifierProvider<BaseVM>(
|
|
create: (_) => BaseVM(),
|
|
),
|
|
ChangeNotifierProvider<DashboardVmCustomer>(
|
|
create: (_) => DashboardVmCustomer(
|
|
commonServices: injector.get<CommonAppServices>(),
|
|
userRepo: injector.get<UserRepo>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<UserVM>(
|
|
create: (_) => UserVM(
|
|
userRepo: injector.get<UserRepo>(),
|
|
commanServices: injector.get<CommonAppServices>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<AdVM>(
|
|
create: (_) => AdVM(
|
|
commonServices: injector.get<CommonAppServices>(),
|
|
commonRepo: injector.get<CommonRepo>(),
|
|
adsRepo: injector.get<AdsRepo>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<AppointmentsVM>(
|
|
create: (_) => AppointmentsVM(
|
|
appointmentRepo: injector.get<AppointmentRepo>(),
|
|
commonServices: injector.get<CommonAppServices>(),
|
|
commonRepo: injector.get<CommonRepo>(),
|
|
branchRepo: injector.get<BranchRepo>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<PaymentVM>(
|
|
create: (_) => PaymentVM(
|
|
paymentService: injector.get<PaymentService>(),
|
|
paymentRepo: injector.get<PaymentsRepo>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<ChatVM>(
|
|
create: (_) => ChatVM(
|
|
chatRepo: injector.get<ChatRepo>(),
|
|
requestRepo: injector.get<RequestRepo>(),
|
|
commonServices: injector.get<CommonAppServices>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<RequestsVM>(
|
|
create: (_) => RequestsVM(
|
|
requestRepo: injector.get<RequestRepo>(),
|
|
commonServices: injector.get<CommonAppServices>(),
|
|
commonRepo: injector.get<CommonRepo>(),
|
|
),
|
|
),
|
|
ChangeNotifierProvider<SettingOptionsVM>(
|
|
create: (_) => SettingOptionsVM(
|
|
settingOptionsRepo: injector.get<SettingOptionsRepo>(),
|
|
),
|
|
),
|
|
],
|
|
child: MyApp(),
|
|
).setupLocale(),
|
|
),
|
|
);
|
|
}
|
|
|
|
// todo terminal command to generate translation files
|
|
// flutter pub run easy_localization:generate --source-dir ./assets/langs
|
|
// todo terminal command to generate translation keys
|
|
// flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart
|
|
// command to generate languages data from json
|
|
|
|
class MyApp extends StatefulWidget {
|
|
const MyApp({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<MyApp> createState() => _MyAppState();
|
|
}
|
|
|
|
class _MyAppState extends State<MyApp> {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
AdDeepLinkService.init();
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
SystemChrome.setPreferredOrientations([
|
|
DeviceOrientation.portraitUp,
|
|
DeviceOrientation.portraitDown,
|
|
]);
|
|
return Sizer(
|
|
builder: (context, orientation, deviceType) {
|
|
injector.get<AppState>().setAppType(AppType.customer);
|
|
AppState().setPostParamsModel(
|
|
PostParamsModel(
|
|
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
|
|
),
|
|
);
|
|
|
|
return ToastificationWrapper(
|
|
child: MaterialApp(
|
|
navigatorKey: navigatorKey,
|
|
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
|
|
debugShowCheckedModeBanner: false,
|
|
localizationsDelegates: context.localizationDelegates,
|
|
supportedLocales: context.supportedLocales,
|
|
locale: context.locale,
|
|
initialRoute: AppRoutes.initialRoute,
|
|
routes: CustomerAppRoutes.routes,
|
|
navigatorObservers: [AdDeepLinkService.routeObserver],
|
|
// Confirmed on a real device, two different unknown-route cases land here:
|
|
// 1) Cold-start restoration can try to regenerate a bare "/" instead of
|
|
// respecting initialRoute -- uncaught, that's a "Could not find a generator
|
|
// for route" crash before AdDeepLinkService ever runs. Splash is a real,
|
|
// correct landing page for this one.
|
|
// 2) On an ALREADY-RUNNING app, Android's Flutter embedding auto-forwards the
|
|
// incoming deep-link intent's path as its own route push (e.g. "/1541" from
|
|
// mowatercustomer://ad/1541) independently of app_links/AdDeepLinkService,
|
|
// which already handles that same uri correctly. Since "/1541" isn't a real
|
|
// route, it used to fall into case 1 and push Splash right over whatever
|
|
// screen (e.g. the dashboard) was already showing -- looking exactly like the
|
|
// app had restarted. Anything other than bare "/" must be a no-op here: push
|
|
// something inert that removes itself immediately instead of a real page.
|
|
onUnknownRoute: (settings) {
|
|
if (settings.name == '/') {
|
|
return MaterialPageRoute(builder: (_) => const SplashPage());
|
|
}
|
|
// Remove THIS specific route once inserted, not just "whatever is on top" --
|
|
// AdDeepLinkService's own (legitimate) push can land after this one, and a
|
|
// plain Navigator.pop() would close that instead of this inert placeholder.
|
|
late final PageRoute<void> route;
|
|
route = PageRouteBuilder<void>(
|
|
settings: const RouteSettings(name: AdDeepLinkService.ignoredPlaceholderRouteName),
|
|
opaque: false,
|
|
transitionDuration: Duration.zero,
|
|
reverseTransitionDuration: Duration.zero,
|
|
pageBuilder: (context, __, ___) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
if (route.isActive) route.navigator?.removeRoute(route);
|
|
});
|
|
return const SizedBox.shrink();
|
|
},
|
|
);
|
|
return route;
|
|
},
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|