live_activities
haroon amjad 3 weeks ago
parent b00a37cabb
commit 83c78cbaf7

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.alhabib.patientApp</string>
</array>
</dict>
</plist>

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.alhabib.patientApp</string>
</array>
</dict>
</plist>

@ -476,166 +476,166 @@ class PushNotificationHandler {
} else if (status.isDenied) {
// Notification permissions denied
await requestPermissions();
await requestPermissions();
if (Platform.isIOS) {
voIPKit.getVoIPToken().then((value) {
log("🎈 APNS VOIP KIT TOKEN: $value");
Utils.saveStringFromPrefs(CacheConst.voipToken, value ?? "");
// AppSharedPreferences().setString(APNS_TOKEN, value!);
});
voIPKit.onDidUpdatePushToken = (String token) {
log('🎈 example: onDidUpdatePushToken: $token');
};
voIPKit.onDidReceiveIncomingPush = (
Map<String, dynamic> payload,
) async {
log('🎈 example: onDidReceiveIncomingPush $payload');
// _timeOut();
};
voIPKit.onDidRejectIncomingCall = (
String uuid,
String callerId,
) async {
try {
log('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
timeOutTimer.cancel();
// Cleanup on reject with API call
if (_currentCallId != null) {
await _endCallAndCleanup(_currentCallId!, isDeclined: true);
}
} catch (err) {
log(err.toString());
}
};
voIPKit.onDidAcceptIncomingCall = (
String uuid,
String callerId,
) async {
log('🎈 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();
if (Platform.isIOS) {
voIPKit.getVoIPToken().then((value) {
log("🎈 APNS VOIP KIT TOKEN: $value");
Utils.saveStringFromPrefs(CacheConst.voipToken, value ?? "");
// AppSharedPreferences().setString(APNS_TOKEN, value!);
});
// Navigator.pushNamed(
// locator<NavigationService>().navigatorKey.currentContext!,
// "zoom_call_page",
// arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false),
// );
// Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN,
// arguments: VideoArgus(
// reservationId: int.parse(callerId), token: null, isVideo: true));
voIPKit.onDidUpdatePushToken = (String token) {
log('🎈 example: onDidUpdatePushToken: $token');
};
voIPKit.onDidReceiveIncomingPush = (
Map<String, dynamic> payload,
) async {
log('🎈 example: onDidReceiveIncomingPush $payload');
// _timeOut();
};
voIPKit.onDidRejectIncomingCall = (
String uuid,
String callerId,
) async {
try {
log('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
timeOutTimer.cancel();
// Cleanup on reject with API call
if (_currentCallId != null) {
await _endCallAndCleanup(_currentCallId!, isDeclined: true);
}
} catch (err) {
log(err.toString());
}
};
voIPKit.onDidAcceptIncomingCall = (
String uuid,
String callerId,
) async {
log('🎈 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();
});
// Navigator.pushNamed(
// locator<NavigationService>().navigatorKey.currentContext!,
// "zoom_call_page",
// arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false),
// );
// Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN,
// arguments: VideoArgus(
// reservationId: int.parse(callerId), token: null, isVideo: true));
// timeOutTimer.cancel();
};
}
// timeOutTimer.cancel();
};
}
if (Platform.isAndroid) {
try {
final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
log(err);
});
if (fcmToken != null) onToken(fcmToken);
// }
} catch (ex) {
log("Notification Exception: $ex");
}
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
}
if (Platform.isAndroid) {
try {
final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
log(err);
if (Platform.isIOS) {
final permission = await FirebaseMessaging.instance.requestPermission();
await FirebaseMessaging.instance.getAPNSToken().then((value) async {
log("APNS token: $value");
await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString());
});
if (fcmToken != null) onToken(fcmToken);
// }
} catch (ex) {
log("Notification Exception: $ex");
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
// if (permission.authorizationStatus == AuthorizationStatus.denied) return;
} else {
final permission = await FirebaseMessaging.instance.requestPermission();
}
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
}
if (Platform.isIOS) {
final permission = await FirebaseMessaging.instance.requestPermission();
await FirebaseMessaging.instance.getAPNSToken().then((value) async {
log("APNS token: $value");
await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString());
});
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
// if (permission.authorizationStatus == AuthorizationStatus.denied) return;
} else {
final permission = await FirebaseMessaging.instance.requestPermission();
}
try {
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async {
if (message != null) {
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
if (message != null) newMessage(message);
});
} else if (message != null) newMessage(message);
try {
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async {
if (message != null) {
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
if (message != null) newMessage(message);
});
} else if (message != null) newMessage(message);
}
});
} catch (ex) {}
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
log("Firebase onMessage!!!");
// showCallkitIncoming();
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
});
} else {
newMessage(message);
}
});
} catch (ex) {}
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
log("Firebase onMessage!!!");
// showCallkitIncoming();
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
log("Firebase onMessageOpenedApp!!!");
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
});
} else {
newMessage(message);
});
} else {
newMessage(message);
}
});
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
log("Firebase onMessageOpenedApp!!!");
if (Platform.isIOS) {
await Future.delayed(Duration(milliseconds: 3000)).then((value) {
newMessage(message);
FirebaseMessaging.instance.getAPNSToken().then((String? token) {
log("Push Notification getAPNSToken: ${token!}");
}).catchError((err) {
log("Push Notification getAPNSToken ERR: ${err.toString()}");
});
} else {
newMessage(message);
}
});
if (Platform.isIOS) {
FirebaseMessaging.instance.getAPNSToken().then((String? token) {
log("Push Notification getAPNSToken: ${token!}");
FirebaseMessaging.instance.getToken().then((String? token) {
log("Push Notification getToken: ${token!}");
onToken(token!);
}).catchError((err) {
log("Push Notification getAPNSToken ERR: ${err.toString()}");
log(err.toString());
});
}
FirebaseMessaging.instance.getToken().then((String? token) {
log("Push Notification getToken: ${token!}");
onToken(token!);
}).catchError((err) {
log(err.toString());
});
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
log("Push Notification onTokenRefresh: $fcm_token");
onToken(fcm_token);
});
if (Platform.isAndroid) {
final deviceInfo = DeviceInfoPlugin();
final androidInfo = await deviceInfo.androidInfo;
// int sdkInt = androidInfo.version.sdkInt ?? 0;
// if (sdkInt >= 33) {
// await FlutterCallkitIncoming.requestFullIntentPermission();
// }
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
log("Push Notification onTokenRefresh: $fcm_token");
onToken(fcm_token);
});
if (Platform.isAndroid) {
final deviceInfo = DeviceInfoPlugin();
final androidInfo = await deviceInfo.androidInfo;
// int sdkInt = androidInfo.version.sdkInt ?? 0;
// if (sdkInt >= 33) {
// await FlutterCallkitIncoming.requestFullIntentPermission();
// }
}
}
}

@ -15,8 +15,11 @@ import 'package:get_it/get_it.dart';
import 'package:google_api_availability/google_api_availability.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/patient_queue.dart';
import 'package:hmg_patient_app_new/core/common_models/privilege/ProjectDetailListModel.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/live_activty_helper_channel.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
@ -30,6 +33,7 @@ import 'package:hmg_patient_app_new/widgets/dialogs/confirm_dialog.dart';
import 'package:hmg_patient_app_new/widgets/loading_dialog.dart';
import 'package:hmg_patient_app_new/widgets/accessibility/preserve_image_colors.dart';
import 'package:hmg_patient_app_new/widgets/accessibility/preserve_svg_colors.dart';
import 'package:live_activities/live_activities.dart';
import 'package:lottie/lottie.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -1172,4 +1176,51 @@ class Utils {
return normalized;
}
static addLiveNotification(dynamic data, {bool isBackgroundMessage = false}) async {
var liveActivity = LiveActivities();
liveActivity.init(appGroupId: "group.alhabib.patientApp");
if (Platform.isIOS) {
LiveActivityHelperChannel.removeData();
}
var queueNoForWhichActivityIdCreated = await Utils.getStringFromPrefs(CacheConst.patientQueueNoForLiveActivity);
var activityId = await Utils.getStringFromPrefs(data.data['queueNo'] ?? "");
var buttonText = Utils.getCardButtonText(int.parse(data.data['callType'] ?? "1"), data.data['roomNo']);
PatientQueue _patientQueue = PatientQueue(
queueNo: data.data['queueNo'] ?? "IME-1",
currentlyServingStatus: (data.data['servingCallType'] ?? 0) == "1" ? LocaleKeys.callForVitalSign.tr() : LocaleKeys.callForDoctor.tr(),
currentlyServingToken: data.data['servingQueueNo'] ?? "IME-3",
nextTicketStatus: buttonText,
callType: int.parse(data.data['callType'] ?? "1"),
currentlyServingCallType: int.parse(data.data['servingCallType'] ?? "1"),
yourTicketHeader: LocaleKeys.yourQueueNumber.tr(),
currentlyServingTitle: LocaleKeys.currentServing.tr());
if ((queueNoForWhichActivityIdCreated ?? "") != (_patientQueue.queueNo ?? "")) {
liveActivity.endActivity(activityId);
activityId = "";
}
if (activityId == "") {
String? id = await liveActivity.createActivity(
DateTime.now().millisecondsSinceEpoch.toString(),
_patientQueue.toMap(),
);
await Utils.saveStringFromPrefs(_patientQueue.queueNo ?? "", id ?? "");
await Utils.saveStringFromPrefs(CacheConst.patientQueueNoForLiveActivity ?? "", _patientQueue.queueNo ?? "");
return;
}
if (Platform.isIOS) {
await liveActivity.createOrUpdateActivity(
activityId,
_patientQueue.toMap(),
);
} else {
await liveActivity.updateActivity(
activityId,
_patientQueue.toMap(),
);
}
}
}

@ -0,0 +1,3 @@
class QueueLiveNotificationModel {
Map<String, dynamic> data = {};
}

@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_favorite_doctors_list.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/patient_queue_live_notification_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/reminder_type.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_parking_QR_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_rated_response_model.dart';
@ -1026,6 +1027,19 @@ class MyAppointmentsViewModel extends ChangeNotifier {
// if (patientQueueDetailsList.length > 1) {
patientQueueDetailsList.removeWhere((element) => element.patientID == patientArrivedAppointmentsHistoryList.first.patientID);
// }
QueueLiveNotificationModel queueLiveNotificationModel = QueueLiveNotificationModel();
queueLiveNotificationModel.data = {
"queueNo": currentPatientQueueDetails.queueNo,
"callType": currentPatientQueueDetails.callType.toString(),
"servingQueueNo": patientQueueDetailsList.isEmpty ? null : patientQueueDetailsList.first.queueNo,
"servingCallType": patientQueueDetailsList.isEmpty ? null : patientQueueDetailsList.first.callType.toString(),
"roomNo": patientQueueDetailsList.isEmpty ? "" : patientQueueDetailsList.first.roomNo,
"servingNow": "true"
};
Utils.addLiveNotification(queueLiveNotificationModel, isBackgroundMessage: false);
} else {
patientQueueDetailsList.clear();
isPatientHasQueueAppointment = false;

Loading…
Cancel
Save