update and fix

dev_sultan
Sultan khan 4 hours ago
parent 086df4cdd8
commit 256537cfb3

@ -1238,7 +1238,7 @@
"healthCalculatorsServices": "حاسبات\nالصحة",
"healthConvertersServices": "محولات\nالصحة",
"smartWatchesServices": "الساعات\nالذكية",
"exploreServices": "قائمة الخدمات او الخدمات",
"exploreServices": "تصفح الخدمات",
"medicalAndCareServices": "خدمات الرعاية الطبية",
"hmgServices": "خدمات مجموعة الحبيب الطبية",
"personalServices": "الخدمات الشخصية",
@ -1471,7 +1471,7 @@
"covered": "مغطى",
"vatPercent": "ضريبة القيمة المضافة (15%)",
"proceedToPayment": "المتابعة للدفع",
"supportedSmartWatches": "الساعات الذكية المدعومة",
"supportedSmartWatches": "كيف تعمل؟",
"pleaseMakeSureSamsungWatchConnected": "يرجى التأكد من أن ساعة Samsung الخاصة بك متصلة بهاتفك، ومتزامنة ومحدثة بشكل نشط.",
"beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.",
"viewWatchInstructions": "عرض تعليمات الساعة",
@ -1768,6 +1768,12 @@
"locationServicesDisabled": "حالة الطقس غير متوفرة لتعطيل خدمات الموقع. يرجى تفعيل خدمات الموقع لتتمكن من رؤية معلومات الطقس.",
"selectDateTimeKey": "اختيار",
"medicalKey": "الطبية",
"convertBloodcholesterolInfo":"حول قيمة كوليسترول الدم بين ملجم/ديسيلتر و مليمول/لتر"
"convertBloodcholesterolInfo":"حول قيمة كوليسترول الدم بين ملجم/ديسيلتر و مليمول/لتر",
"mldl": "مليجرام لكل ديسيلتر",
"mmol": "ملي مول لكل لتر",
"triglycerideInfo": "تغيير وحدات القياس بين مليجرام لكل ديسيلتر و ملي مول لكل لتر",
"selectSmartWatch": "تعيين",
"selectBloodDonationCity": "اختر المدينة",
"selectBloodDonationGender": "اختر الجنس",
"selectBloodType": "اختر الفصيلة"
}

@ -1756,9 +1756,15 @@
"selectCriteria": "Select Criteria",
"locationServicesDisabled": "Weather is unavailable because location services are disabled. Please enable location services to see the weather information.",
"selectDateTimeKey": "Select",
"medicalKey": "Medical"
,
"convertBloodcholesterolInfo": "Convert blood cholesterol values between mg/dL and mmol/L. "
"medicalKey": "Medical",
"convertBloodcholesterolInfo": "Convert blood cholesterol values between mg/dL and mmol/L. ",
"mldl": "مليجرام لكل ديسيلتر",
"mmol": "ملي مول لكل لتر",
"triglycerideInfo": "Convert triglyceride values between mg/dL and mmol/L.",
"selectSmartWatch": "Select",
"selectBloodDonationCity": "Select City",
"selectBloodDonationGender": "Select Gender",
"selectBloodType": "Select Blood Type"
}

@ -172,6 +172,7 @@ class ApiClientImp implements ApiClient {
// body['VersionID'] = ApiConsts.appVersionID.toString();
if (!isExternal) {
body['VersionID'] = ApiConsts.appVersionID.toString();
if(!isRCService)
body['Channel'] = ApiConsts.appChannelId.toString();
body['IPAdress'] = ApiConsts.appIpAddress;
body['generalid'] = ApiConsts.appGeneralId;

@ -189,6 +189,7 @@ class ApiConsts {
static final createEReferral = "Services/Patients.svc/REST/CreateEReferral";
static final getEReferrals = "Services/Patients.svc/REST/GetEReferrals";
//WATER CONSUMPTION
static String h2oGetUserProgress = "Services/H2ORemainder.svc/REST/H2O_GetUserProgress";
static String h2oInsertUserActivity = "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity";

@ -401,7 +401,7 @@ class AppAssets {
static const String lockIcon = '$pngBasePath/lock-icon.png';
static const String dummyUser = '$pngBasePath/dummy_user.png';
static const String comprehensiveCheckupEn = '$pngBasePath/cc_en.png';
static const String comprehensiveCheckupAr = '$pngBasePath/cc_er.png';
static const String comprehensiveCheckupAr = '$pngBasePath/cc_ar.png';
static const String maleIcon = '$pngBasePath/male_icon.png';
static const String femaleIcon = '$pngBasePath/female_icon.png';

@ -9,17 +9,27 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming/entities/android_params.dart';
import 'package:flutter_callkit_incoming/entities/call_event.dart';
import 'package:flutter_callkit_incoming/entities/call_kit_params.dart';
import 'package:flutter_callkit_incoming/entities/ios_params.dart';
import 'package:flutter_callkit_incoming/entities/notification_params.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:flutter_ios_voip_kit_karmm/call_state_type.dart';
import 'package:flutter_ios_voip_kit_karmm/flutter_ios_voip_kit.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
// Global tracking variables for call state
bool _isCallInProgress = false;
String? _currentCallId;
Timer? _callTimeoutTimer;
String? _currentSessionId; // Store session ID for API call
// |--> Push Notification Background
@pragma('vm:entry-point')
Future<dynamic> backgroundMessageHandler(dynamic message) async {
@ -39,34 +49,36 @@ callPage(String sessionID, String token) async {}
_incomingCall(Map<String, dynamic> data) async {
print('the value of the _incomingCall remote message is $data');
// LandingPage.incomingCallData = IncomingCallData.fromJson(data);
// var dataItem = await AppSharedPreferences().getObject('call_data');
// if(dataItem != null ) return; // to stop repeated attempt to invoke the call
// if (LandingPage.isOpenCallPage == false) {
// LandingPage.isOpenCallPage = true;
// Check if there's already a call in progress to prevent duplicates
if (_isCallInProgress && _currentCallId != null) {
print('⚠️ Call already in progress (ID: $_currentCallId), ignoring duplicate notification');
return;
}
String roomID = data['session_id'] ?? '';
String callTypeID = data['AppointmentNo'] ?? '';
// GetIt.instance<CacheService>().saveString(key: CacheConst.zoomRoomID, value: roomID);
// GetIt.instance<CacheService>().saveBool(key: CacheConst.isAppOpenedFromCall, value: true);
// Generate unique call ID
var _currentUuid = Uuid().v4();
_currentCallId = _currentUuid;
_isCallInProgress = true;
_currentSessionId = roomID; // Store session ID for decline API call
print('📞 Starting new call with ID: $_currentCallId, Session: $_currentSessionId');
await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, roomID);
await Utils.saveStringFromPrefs(CacheConst.callTypeID, callTypeID);
await Utils.saveBoolFromPrefs(CacheConst.isAppOpenedFromCall, true);
WidgetsFlutterBinding.ensureInitialized();
int callKitType = callTypeID == '2' ? 0 : 1;
var _currentUuid = Uuid().v4();
CallKitParams callKitParams = CallKitParams(
id: _currentUuid,
nameCaller: "Dr Al Habib",
appName: 'Dr Al Habib',
avatar: 'https://play-lh.googleusercontent.com/FBNNpxb7m6eM6wtW7MV1Ffp6OXOGLI38q47zcvP29OCYA1yhYH5mZzl5itZi0TgOyZpG',
// handle: LandingPage.incomingCallData.name,
type: callKitType,
textAccept: 'Accept',
textDecline: 'Decline',
@ -85,8 +97,8 @@ _incomingCall(Map<String, dynamic> data) async {
duration: 30000,
extra: <String, dynamic>{
'userId': '1a2b3c4d',
'callTypeID': callTypeID, // Store actual callTypeID here
'roomID': roomID, // Store roomID here for backup
'callTypeID': callTypeID,
'roomID': roomID,
},
headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
android: const AndroidParams(
@ -96,10 +108,10 @@ _incomingCall(Map<String, dynamic> data) async {
isShowLogo: false,
logoUrl: "https://play-lh.googleusercontent.com/FBNNpxb7m6eM6wtW7MV1Ffp6OXOGLI38q47zcvP29OCYA1yhYH5mZzl5itZi0TgOyZpG",
ringtonePath: 'system_ringtone_default',
backgroundColor: '#ED1C2B',
backgroundColor: '#2E3039',
backgroundUrl: 'https://saudipedia.com/en/saudipediaen/uploads/images/2024/08/02/97358.jpg',
actionColor: '#4CAF50',
textColor: '#000000',
textColor: '#FFFFFF',
incomingCallNotificationChannelName: "Incoming Call",
missedCallNotificationChannelName: "Missed Call",
isShowCallID: false),
@ -120,12 +132,89 @@ _incomingCall(Map<String, dynamic> data) async {
ringtonePath: 'system_ringtone_default',
),
);
FlutterCallkitIncoming.unsilenceEvents();
await FlutterCallkitIncoming.showCallkitIncoming(callKitParams);
// Start 60-second timeout timer to auto-dismiss call
_callTimeoutTimer?.cancel(); // Cancel any existing timer
_callTimeoutTimer = Timer(Duration(seconds: 40), () async {
print('⏱️ Call timeout (60 seconds) - auto dismissing call notification');
await _endCallAndCleanup(_currentUuid);
});
await Future.delayed(Duration(milliseconds: 500));
}
// Helper method to end call and cleanup
Future<void> _endCallAndCleanup(String callId, {bool isDeclined = false}) async {
try {
print('🧹 Cleaning up call: $callId');
// If call was declined, update session status via API
if (isDeclined && _currentSessionId != null && _currentSessionId!.isNotEmpty) {
await _updateSessionStatus(_currentSessionId!, 3, 'Patient');
}
// End the specific call
await FlutterCallkitIncoming.endCall(callId);
// Clear all calls to ensure clean state
await FlutterCallkitIncoming.endAllCalls();
// Reset tracking flags
_isCallInProgress = false;
_currentCallId = null;
_currentSessionId = null;
// Cancel timer
_callTimeoutTimer?.cancel();
_callTimeoutTimer = null;
// Clear cache
await Utils.saveBoolFromPrefs(CacheConst.isAppOpenedFromCall, false);
await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, '');
await Utils.saveStringFromPrefs(CacheConst.callTypeID, '');
print('✅ Call and push notification cleanup completed successfully');
} catch (e) {
print('❌ Error during call cleanup: $e');
// Force reset flags even if there's an error
_isCallInProgress = false;
_currentCallId = null;
_currentSessionId = null;
_callTimeoutTimer?.cancel();
_callTimeoutTimer = null;
}
}
// Helper method to update session status via API
Future<void> _updateSessionStatus(String sessionId, int sessionStatus, String sessionEndedBy) async {
try {
final apiClient = getIt.get<ApiClient>();
Map<String, dynamic> 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');
}
}
Future<void> openCallPage(BuildContext context) async {
try {
// if (incomingCallData!.background == "0") {
@ -291,6 +380,10 @@ class PushNotificationHandler {
try {
print('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
timeOutTimer.cancel();
// Cleanup on reject with API call
if (_currentCallId != null) {
await _endCallAndCleanup(_currentCallId!, isDeclined: true);
}
} catch (err) {}
};
@ -301,6 +394,12 @@ class PushNotificationHandler {
print('🎈 example: onDidAcceptIncomingCall $uuid - $callerId');
await voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
await voIPKit.callConnected();
// Cleanup on accept - cancel timer and reset flags
_callTimeoutTimer?.cancel();
_callTimeoutTimer = null;
_isCallInProgress = false;
_currentCallId = null;
await Future.delayed(Duration(seconds: 2)).then((val) async {
await voIPKit.endCall();
});

@ -306,6 +306,23 @@ class PrescriptionsViewModel extends ChangeNotifier {
} else if (apiResponse.messageStatus == 1) {
isPrescriptionsDeliveryOrdersLoading = false;
prescriptionsOrderList = apiResponse.data!;
// Sort by created date (newest first)
prescriptionsOrderList.sort((a, b) {
try {
if (a.created == null && b.created == null) return 0;
if (a.created == null) return 1;
if (b.created == null) return -1;
DateTime dateA = DateTime.parse(a.created!);
DateTime dateB = DateTime.parse(b.created!);
return dateB.compareTo(dateA); // Descending order (newest first)
} catch (e) {
print('Error parsing date for sorting: $e');
return 0;
}
});
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);

@ -1759,5 +1759,13 @@ abstract class LocaleKeys {
static const locationServicesDisabled = 'locationServicesDisabled';
static const selectDateTimeKey = 'selectDateTimeKey';
static const medicalKey = 'medicalKey';
static const convertBloodcholesterolInfo = 'convertBloodcholesterolInfo';
static const mldl = 'mldl';
static const mmol = 'mmol';
static const triglycerideInfo = 'triglycerideInfo';
static const selectSmartWatch = 'selectSmartWatch';
static const selectBloodDonationCity = 'selectBloodDonationCity';
static const selectBloodDonationGender = 'selectBloodDonationGender';
static const selectBloodType = 'selectBloodType';
}

@ -148,8 +148,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
children: [
LocaleKeys.city.tr().toText16(color: AppColors.textColor, isBold: true),
(appState.isArabic()
? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.select.tr())
: bloodDonationVM.selectedCity?.description ?? LocaleKeys.select.tr(context: context))
? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.selectBloodDonationCity.tr())
: bloodDonationVM.selectedCity?.description ?? LocaleKeys.selectBloodDonationCity.tr(context: context))
.toText14(color: AppColors.greyTextColor, isBold: true),
],
),
@ -176,8 +176,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
children: [
LocaleKeys.gender.tr().toText16(color: AppColors.textColor, isBold: true),
(appState.isArabic()
? (bloodDonationVM.selectedGender?.typeAr ?? LocaleKeys.select.tr())
: bloodDonationVM.selectedGender?.type ?? LocaleKeys.select.tr(context: context))
? (bloodDonationVM.selectedGender?.typeAr ?? LocaleKeys.selectBloodDonationGender.tr())
: bloodDonationVM.selectedGender?.type ?? LocaleKeys.selectBloodDonationGender.tr(context: context))
.toText14(color: AppColors.greyTextColor, isBold: true),
],
),
@ -208,8 +208,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
LocaleKeys.bloodType.tr().toText16(color: AppColors.textColor, isBold: true),
// bloodDonationVM.selectedBloodType?.toText14(color: AppColors.greyTextColor, isBold: true),
(appState.isArabic()
? (bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr())
: bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr(context: context))
? (bloodDonationVM.selectedBloodType ?? LocaleKeys.selectBloodType.tr())
: bloodDonationVM.selectedBloodType ?? LocaleKeys.selectBloodType.tr(context: context))
.toText14(color: AppColors.greyTextColor, isBold: true)
],
),

@ -37,7 +37,12 @@ class SelectGenderWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8.h,
children: [GenderTypeEnum.values[index].name.toCamelCase.toText16(color: AppColors.textColor, isBold: true)],
children: [
(isArabic
? GenderTypeEnum.values[index].typeAr
: GenderTypeEnum.values[index].type)
.toText16(color: AppColors.textColor, isBold: true)
],
),
),
Transform.flip(
@ -52,7 +57,10 @@ class SelectGenderWidget extends StatelessWidget {
),
],
).paddingSymmetrical(16.h, 16.h).onPress(() {
bloodDonationViewModel.onGenderChange(GenderTypeEnum.values[index].name.toCamelCase);
final genderValue = isArabic
? GenderTypeEnum.values[index].typeAr
: GenderTypeEnum.values[index].type;
bloodDonationViewModel.onGenderChange(genderValue);
Navigator.of(context).pop();
}));
},

@ -240,6 +240,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget {
],
).paddingSymmetrical(24.h, 0.h),
(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0" || immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total == "0.0")
// (true)
? CustomButton(
text: LocaleKeys.confirmLiveCare.tr(context: context),
onPressed: () async {

@ -250,7 +250,10 @@ class _ComprehensiveCheckupPageState extends State<ComprehensiveCheckupPage> {
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
final service = services[index];
final serviceName = service.text ?? service.textN ?? '';
final appStateLocal = getIt.get<AppState>();
final serviceName = appStateLocal.isArabic()
? (service.textN ?? service.text ?? '')
: (service.text ?? service.textN ?? '');
final price = service.priceTotal ?? 0.0;
return RadioListTileWidget<int>(
value: service.iD ?? 0,

@ -78,7 +78,7 @@ class _BloodCholesterolWidgetState extends State<BloodCholesterolWidget> {
child: Column(
children: [
_buildInputField(
label: "MG/DL",
label: LocaleKeys.mldl.tr(),
hint: "120",
controller: _mgdlController,
focusNode: _mgdlFocus,
@ -107,7 +107,7 @@ class _BloodCholesterolWidgetState extends State<BloodCholesterolWidget> {
],
),
_buildInputField(
label: "MMOL/L",
label:LocaleKeys.mmol.tr(),
hint: "3.1",
controller: _mmolController,
focusNode: _mmolFocus,

@ -1,4 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:provider/provider.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
@ -80,7 +82,7 @@ class _TriglyceridesWidgetState extends State<TriglyceridesWidget> {
child: Column(
children: [
_buildInputField(
label: "MG/DL",
label: LocaleKeys.mldl.tr(),
hint: "150",
controller: _mgdlController,
focusNode: _mgdlFocus,
@ -111,7 +113,7 @@ class _TriglyceridesWidgetState extends State<TriglyceridesWidget> {
),
_buildInputField(
label: "MMOL/L",
label: LocaleKeys.mmol,
hint: "1.7",
controller: _mmolController,
focusNode: _mmolFocus,
@ -134,7 +136,7 @@ class _TriglyceridesWidgetState extends State<TriglyceridesWidget> {
SizedBox(width: 12.w),
Expanded(
child:
"Convert triglyceride values between mg/dL and mmol/L."
LocaleKeys.triglycerideInfo.tr()
.toText12(
isBold: true,
color: AppColors.inputLabelTextColor,

@ -105,51 +105,51 @@ class _ServicesPageState extends State<ServicesPage> {
);
}
}),
HmgServicesComponentModel(
11,
LocaleKeys.indoorNavigation.tr(),
"",
AppAssets.indoor_nav_icon,
bgColor: Color(0xff45A2F8),
true,
route: null,
onTap: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.selectHospital.tr(),
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: ChangeNotifierProvider(
create: (context) => HospitalSelectionBottomSheetViewModel(getIt()),
child: Consumer<HospitalSelectionBottomSheetViewModel>(
builder: (_, vm, __) => HospitalBottomSheetBody(
searchText: vm.searchController,
displayList: vm.displayList,
onFacilityClicked: (value) {
vm.setSelectedFacility(value);
vm.getDisplayList();
},
onHospitalClicked: (hospital) {
Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
vm.openPenguin(hospital);
},
onHospitalSearch: (value) {
vm.searchHospitals(value ?? "");
},
selectedFacility: vm.selectedFacility,
hmcCount: vm.hmcCount,
hmgCount: vm.hmgCount,
),
),
),
isFullScreen: false,
isCloseButtonVisible: true,
hasBottomPadding: false,
backgroundColor: AppColors.bottomSheetBgColor,
callBackFunc: () {
GetIt.instance<NavigationService>().navigatorKey.currentContext!.read<EmergencyServicesViewModel>().clearSearchText();
},
);
},
),
// HmgServicesComponentModel(
// 11,
// LocaleKeys.indoorNavigation.tr(),
// "",
// AppAssets.indoor_nav_icon,
// bgColor: Color(0xff45A2F8),
// true,
// route: null,
// onTap: () {
// showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.selectHospital.tr(),
// GetIt.instance<NavigationService>().navigatorKey.currentContext!,
// child: ChangeNotifierProvider(
// create: (context) => HospitalSelectionBottomSheetViewModel(getIt()),
// child: Consumer<HospitalSelectionBottomSheetViewModel>(
// builder: (_, vm, __) => HospitalBottomSheetBody(
// searchText: vm.searchController,
// displayList: vm.displayList,
// onFacilityClicked: (value) {
// vm.setSelectedFacility(value);
// vm.getDisplayList();
// },
// onHospitalClicked: (hospital) {
// Navigator.pop(GetIt.instance<NavigationService>().navigatorKey.currentContext!);
// vm.openPenguin(hospital);
// },
// onHospitalSearch: (value) {
// vm.searchHospitals(value ?? "");
// },
// selectedFacility: vm.selectedFacility,
// hmcCount: vm.hmcCount,
// hmgCount: vm.hmgCount,
// ),
// ),
// ),
// isFullScreen: false,
// isCloseButtonVisible: true,
// hasBottomPadding: false,
// backgroundColor: AppColors.bottomSheetBgColor,
// callBackFunc: () {
// GetIt.instance<NavigationService>().navigatorKey.currentContext!.read<EmergencyServicesViewModel>().clearSearchText();
// },
// );
// },
// ),
HmgServicesComponentModel(11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async {
if (getIt.get<AppState>().isAuthenticated) {
getIt.get<NavigationService>().pushPageRoute(AppRoutes.eReferralPage);

@ -85,7 +85,7 @@ class SmartwatchHomePage extends StatelessWidget {
Image.asset("assets/images/png/smartwatches/apple-watch-5.jpg", width: 136.w, height: 136.h).paddingSymmetrical(24.w, 8.h),
"Apple Watch".needTranslation.toText16(isBold: true),
CustomButton(
text: LocaleKeys.select.tr(context: context),
text: LocaleKeys.selectSmartWatch.tr(context: context),
onPressed: () {
context.read<HealthProvider>().setSelectedWatchType(SmartWatchTypes.apple, "assets/images/png/smartwatches/apple-watch-5.jpg");
getIt.get<NavigationService>().pushPage(page: SmartwatchInstructionsPage(

@ -5,6 +5,7 @@ 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';
@ -182,9 +183,22 @@ class _SplashScreenState extends State<SplashPage> {
}
break;
case Event.actionCallDecline:
print('actionCallConnected Event Received: ------->');
print('actionCallDecline Event Received: ------->');
// Get session ID from cache
String sessionId = await Utils.getStringFromPrefs(CacheConst.zoomRoomID);
//
// // Update session status to 3 (declined by patient)
// if (sessionId.isNotEmpty) {
await _updateSessionStatus(sessionId, 3, 'Patient');
// }
await FlutterCallkitIncoming.endAllCalls();
GetIt.instance<CacheService>().remove(key: CacheConst.isAppOpenedFromCall);
// Clear cache
await Utils.saveStringFromPrefs(CacheConst.zoomRoomID, '');
await Utils.saveStringFromPrefs(CacheConst.callTypeID, '');
break;
case Event.actionCallEnded:
break;
@ -220,20 +234,35 @@ class _SplashScreenState extends State<SplashPage> {
/// load the Privilege from service
Future loadPrivilege() async {
// ProjectViewModel projectProvider = Provider.of<ProjectViewModel>(context, listen: false);
// projectProvider.setPrivilegeModelList(privilege: _privilegeService.privilegeModelList);
// projectProvider.setVidaPlusProjectList(_privilegeService.vidaPlusProjectListModel);
// projectProvider.setHMCProjectList(_privilegeService.hMCProjectListModel);
// projectProvider.setProjectsDetailList(_privilegeService.projectDetailListModel);
// double lat = await AppSharedPreferences().getDouble(USER_LAT) ?? 0.0;
// double long = await AppSharedPreferences().getDouble(USER_LONG) ?? 0.0;
// AppSharedPreferences().clear(); // Clearing Shared Preferences On App Launch
// await AppSharedPreferences().setDouble(USER_LAT, lat);
// await AppSharedPreferences().setDouble(USER_LONG, long);
// AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en");
// var themeNotifier = Provider.of<ThemeNotifier>(context, listen: false);
// themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins'));
// PushNotificationHandler().init(context); // Asyncronously
// ...existing code...
}
/// Update session status when call is declined
Future<void> _updateSessionStatus(String sessionId, int sessionStatus, String sessionEndedBy) async {
try {
print('📡 Updating session status - SessionID: $sessionId, Status: $sessionStatus, EndedBy: $sessionEndedBy');
final apiClient = getIt.get<ApiClient>();
String sessionID = await Utils.getStringFromPrefs(CacheConst.zoomRoomID);
Map<String, dynamic> 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

Loading…
Cancel
Save