import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_callkit_incoming/entities/call_event.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/onboarding/onboarding_screen.dart'; import 'package:hmg_patient_app_new/presentation/onboarding/splash_animation_screen.dart'; import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/notification_service.dart'; import 'package:hmg_patient_app_new/services/zoom_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:lottie/lottie.dart'; import 'core/cache_consts.dart'; import 'core/utils/push_notification_handler.dart'; class SplashPage extends StatefulWidget { const SplashPage({super.key}); @override _SplashScreenState createState() => _SplashScreenState(); } class _SplashScreenState extends State { late AuthenticationViewModel authVm; Future initializeStuff() async { listenerEvent(); Timer( Duration(milliseconds: 500), () async { ApiConsts.setBackendURLs(); PushNotificationHandler().init(context); // Asyncronously }, ); // TODO: This next line should be tested. This stops the app at this step, sometimes await authVm.getServicePrivilege(); Timer(Duration(seconds: 2, milliseconds: 500), () async { bool isAppOpenedFromCall = getIt.get().getBool(key: CacheConst.isAppOpenedFromCall) ?? false; // Initialize NotificationService using dependency injection final notificationService = getIt.get(); await notificationService.initialize(onNotificationClick: (payload) { // Handle notification click here }); ZoomService().initializeZoomSDK(); if (isAppOpenedFromCall) { navigateToTeleConsult(); } else { if (await Utils.getBoolFromPrefs(CacheConst.firstLaunch)) { // Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: OnboardingScreen()))); Navigator.of(context).pushReplacement(FadePage(page: OnboardingScreen())); } else { // Navigator.of(context).pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation()))); Navigator.of(context).pushReplacement(FadePage(page: LandingNavigation())); } } }); // var zoom = ZoomVideoSdk(); // InitConfig initConfig = InitConfig( // domain: "zoom.us", // enableLog: false, // ); // zoom.initSdk(initConfig); } navigateToTeleConsult() async { String roomID = await Utils.getStringFromPrefs(CacheConst.zoomRoomID); String callTypeID = await Utils.getStringFromPrefs(CacheConst.callTypeID); // GetIt.instance().remove(key: CacheConst.isAppOpenedFromCall); Utils.removeFromPrefs(CacheConst.isAppOpenedFromCall); Navigator.of(GetIt.instance().navigatorKey.currentContext!) .pushReplacement(FadePage(page: SplashAnimationScreen(routeWidget: LandingNavigation()))); Navigator.pushReplacementNamed( // context, GetIt.instance().navigatorKey.currentContext!, AppRoutes.zoomCallPage, // arguments: CallArguments(appointmentID, "111", "Patient", "40", "1", true, 1), arguments: CallArguments(roomID, "123", "Patient", "40", "0", true, int.parse(callTypeID)), // arguments: CallArguments("SmallDailyStandup9875", "123", "Patient", "40", "0", false, int.parse(widget.incomingCallData!.appointmentNo!)), ); } Future listenerEvent() async { print('Call Canceled : ------->'); try { FlutterCallkitIncoming.unsilenceEvents(); FlutterCallkitIncoming.onEvent.listen((event) async { switch (event!.event) { case Event.actionCallIncoming: print('actionCallIncoming Event Received: ------->'); break; case Event.actionCallStart: print('actionCallStart Event Received: ------->'); break; case Event.actionCallAccept: print('actionCallAccept Event Received: ------->'); FlutterCallkitIncoming.endAllCalls(); try { // Get callTypeID and roomID from event's extra data String? eventCallTypeID = event.body['extra']?['callTypeID']; String? eventRoomID = event.body['extra']?['roomID']; // Re-save to SharedPreferences to ensure they're available if (eventCallTypeID != null && eventCallTypeID.isNotEmpty) { await Utils.saveStringFromPrefs(CacheConst.callTypeID, eventCallTypeID); } if (eventRoomID != null && eventRoomID.isNotEmpty) { await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, eventRoomID); } navigateToTeleConsult(); // String roomID = await Utils.getStringFromPrefs(SharedPrefsConsts.ZOOM_ROOM_ID); // String roomPass = await Utils.getStringFromPrefs(SharedPrefsConsts.ZOOM_ROOM_PASS); // print('RoomID: $roomID'); // print('RoomPass: $roomPass'); // Future.delayed(const Duration(milliseconds: 3000), () async { // // try { // // String teleConsultURL = "https://teleconsult.meena-health.com/api/videocall/doVideoCall?roomid="; // // await Utils.getStringFromPrefs(SharedPrefsConsts.PATIENT_MRN).then((value) { // // teleConsultURL = teleConsultURL + value; // // print("TeleConsult URL: $teleConsultURL"); // // Uri uri = Uri.parse(teleConsultURL); // // launchUrl(uri, mode: LaunchMode.externalApplication, webOnlyWindowName: "TeleConsult"); // // }); // // // var cameraStatus = await Permission.camera.request(); // // var micStatus = await Permission.microphone.request(); // // var permissionStatus = await [Permission.microphone, Permission.camera, Permission.notification].request(); // // if (permissionStatus[1]?.isDenied == true) { // // await Permission.camera.request(); // // } // // if (permissionStatus[0]?.isDenied == true) { // // await Permission.microphone.request(); // // } // // Navigator.pushNamed( // // context, // navigatorKey.currentContext!, // AppRoutes.zoomCallPage, // // arguments: CallArguments(appointmentID, "111", "Patient", "40", "1", true, 1), // arguments: CallArguments(roomID, roomPass, "Patient", "40", "0", true, 1), // // arguments: CallArguments("SmallDailyStandup9875", "123", "Patient", "40", "0", false, int.parse(widget.incomingCallData!.appointmentNo!)), // ); // // } catch (err) { // // print(err); // // } // }); // String teleConsultURL = "https://teleconsult.meena-health.com/api/videocall/doVideoCall?roomid="; // await Utils.getStringFromPrefs(SharedPrefsConsts.PATIENT_MRN).then((value) { // teleConsultURL = teleConsultURL + value; // print("TeleConsult URL: $teleConsultURL"); // Uri uri = Uri.parse(teleConsultURL); // launchUrl(uri, mode: LaunchMode.inAppBrowserView, webOnlyWindowName: "Test"); // }); // navigatorKey.currentState!.pushNamed(AppRoutes.incomingCallScreenRoute); // await Navigator.pushNamed(context, AppRoutes.incomingCallScreenRoute).then((value) {}); } catch (e) { print("ERRORRRR!!! ${e.toString()}"); // await AppSharedPreferences().setObject('call_data', data); // var data1 = await AppSharedPreferences().getObject('call_data'); } break; case Event.actionCallDecline: print('actionCallDecline Event Received: ------->'); // Try to get session ID from event data first String? sessionIdFromEvent = event.body['extra']?['roomID']; // Get session ID from cache as backup String sessionIdFromCache = await Utils.getStringFromPrefs(CacheConst.zoomRoomID); // Use event data if available, otherwise use cache String sessionId = (sessionIdFromEvent != null && sessionIdFromEvent.isNotEmpty) ? sessionIdFromEvent : sessionIdFromCache; print('🔍 Session ID from event: "$sessionIdFromEvent"'); print('🔍 Session ID from cache: "$sessionIdFromCache"'); print('🔍 Final session ID to use: "$sessionId"'); // Update session status to 3 (declined by patient) if (sessionId.isNotEmpty) { print('✅ Session ID found, calling API...'); await _updateSessionStatus(sessionId, 3, 'Patient'); } else { print('⚠️ Session ID is empty, skipping API call'); } await FlutterCallkitIncoming.endAllCalls(); GetIt.instance().remove(key: CacheConst.isAppOpenedFromCall); // Clear cache await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, ''); await Utils.saveStringFromPrefs(CacheConst.callTypeID, ''); break; case Event.actionCallEnded: break; case Event.actionCallTimeout: break; case Event.actionCallCallback: break; case Event.actionCallToggleHold: break; case Event.actionCallToggleMute: break; case Event.actionCallToggleDmtf: break; case Event.actionCallToggleGroup: break; case Event.actionCallToggleAudioSession: break; case Event.actionDidUpdateDevicePushTokenVoip: break; case Event.actionCallCustom: break; case Event.actionCallConnected: print('actionCallConnected Event Received: ------->'); await FlutterCallkitIncoming.endAllCalls(); break; } }); } on Exception catch (e) { print(e); print("ERRORRRR!!! ${e.toString()}"); } } /// load the Privilege from service Future loadPrivilege() async { // ...existing code... } /// Update session status when call is declined Future _updateSessionStatus(String sessionId, int sessionStatus, String sessionEndedBy) async { try { print('📡 Updating session status - SessionID: $sessionId, Status: $sessionStatus, EndedBy: $sessionEndedBy'); final apiClient = getIt.get(); Map requestBody = { "Open_SessionID": sessionId, "SessionStatus": sessionStatus, "SessionEndedBy": sessionEndedBy }; await apiClient.post( CHANGE_PATIENT_ER_SESSION, body: requestBody, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { print('✅ Session status updated successfully: $response'); }, onFailure: (error, statusCode, {messageStatus, failureType}) { print('❌ Failed to update session status: $error'); }, ); } catch (e) { print('❌ Exception updating session status: $e'); } } @override void initState() { authVm = getIt(); super.initState(); initializeStuff(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.whiteColor, body: Lottie.asset(AppAnimations.loadingAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 80.h, height: 80.h, fit: BoxFit.fill) .center); } }