import 'dart:convert'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:onufitness/constants/api_enum_constant.dart'; import 'package:onufitness/constants/constant.dart'; import 'package:onufitness/constants/data/bindings.dart'; import 'package:onufitness/constants/data_constant.dart'; import 'package:onufitness/environment/app_environment.dart'; import 'package:onufitness/firebase_options.dart'; import 'package:onufitness/routes/app_page_router.dart'; import 'package:onufitness/routes/route_constant.dart'; import 'package:onufitness/services/agora/call_services.dart'; import 'package:onufitness/services/local_storage_services/shared_services.dart'; import 'package:onufitness/services/logger_service.dart'; import 'package:onufitness/services/network_service/network_service.dart'; import 'package:onufitness/services/notification_services/navigation_controller.dart'; import 'package:onufitness/services/notification_services/notification_service.dart'; import 'package:onufitness/services/socket/socket_service.dart'; import 'package:onufitness/themes/app_theme.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() async { //...Maintain the order of the code in main method................................................ WidgetsFlutterBinding.ensureInitialized(); //................................................................................................. // Set Application Environment - Development AppEnvironment.setEnvironment(Environment.uat); final logger = LoggerService(); logger.log('App starting in ${AppEnvironment.environmentName} mode'); //................................................................................................. SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( systemNavigationBarColor: Colors.white, statusBarColor: Colors.white, statusBarIconBrightness: Brightness.dark, systemNavigationBarIconBrightness: Brightness.dark, ), ); //................................................................................................. // Initialize SharedPreferences preferences = await SharedPreferences.getInstance(); // Initialize services SharedServices.getLoginDetails(); SharedServices.getUserDetails(); //................................................................................................. // Initialize Firebase await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); //................................................................................................. FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); //................................................................................................. //................................................................................................. // Initialize NotificationController first final notifController = Get.put( NotificationNavigationController(), permanent: true, ); //................................................................................................. // Initialize AgoraCallService if logged in if (SharedServices.isLoggedIn()) { await Get.putAsync(() async { return await AgoraCallService().init(); }, permanent: true); } //................................................................................................. // Initialize NotificationService await Get.putAsync( () async => NotificationService(), permanent: true, ); //................................................................................................. // Initialize SocketService after a small delay Future.delayed(const Duration(seconds: 2), () { if (!Get.isRegistered()) { Get.put(SocketService(), permanent: true); } Get.find().connect(); }); //................................................................................................. //................................................................................................. // Handle app launch from terminated state //................................................................................................. final details = await globalNotificationsPlugin.getNotificationAppLaunchDetails(); if (details?.didNotificationLaunchApp ?? false) { final payload = details?.notificationResponse?.payload; final notificationId = details?.notificationResponse?.id; final actionId = details?.notificationResponse?.actionId; if (notificationId != null) { await globalNotificationsPlugin.cancel(notificationId); } if (payload != null) { try { final data = jsonDecode(payload); final notificationType = parseNotificationType( data['notificationType'], ); if (actionId == 'reject_call') { notifController.isCallingNotificationNavigation.value = false; // DON'T RETURN - just skip processing } else { // Only process normal incoming calls if (notificationType == ApiEnum.CallingNotification) { await globalNotificationsPlugin.cancelAll(); final channelName = extractChannelName(data); if (channelName != null) { activeCallNotifications.remove(channelName); } } notifController.setFlagsFromPayload(data); } } catch (e) { logger.error('Error decoding notification payload', error: e); } } } //................................................................................................. // Initialize NetworkController Get.put(NetworkController()); //................................................................................................. // Set orientation SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); //........................................................................... await SentryFlutter.init((options) { options.dsn = sentryDsnId; options.sendDefaultPii = true; options.attachScreenshot = true; options.enableAppLifecycleBreadcrumbs = true; options.enableNativeCrashHandling = true; options.attachStacktrace = true; options.tracesSampleRate = 0.01; options.debug = true; options.diagnosticLevel = SentryLevel.debug; options.enableLogs = true; options.replay.sessionSampleRate = 1.0; options.replay.onErrorSampleRate = 1.0; options.environment = kDebugMode ? sentryDevEnvironment : sentryReleaseEnvironment; }, appRunner: () => runApp(SentryWidget(child: MyApp()))); //...................................................................... // runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth >= 600) { return ScreenUtilInit( designSize: const Size(600, 960), minTextAdapt: true, splitScreenMode: true, builder: (context, child) { return GetMaterialApp( initialBinding: MyBinding(), debugShowCheckedModeBanner: false, initialRoute: RouteConstant.splashScreen, getPages: AppPageRouter().getPages, title: 'OnUFitness', theme: AppTheme.currentTheme, ); }, ); } else { return ScreenUtilInit( designSize: const Size(375, 812), minTextAdapt: true, splitScreenMode: true, builder: (context, child) { return GetMaterialApp( initialBinding: MyBinding(), debugShowCheckedModeBanner: false, initialRoute: RouteConstant.splashScreen, getPages: AppPageRouter().getPages, title: 'OnUFitness', theme: AppTheme.currentTheme, ); }, ); } }, ); } }