diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart index e179a1ab..89f6969a 100644 --- a/lib/core/utils/push_notification_handler.dart +++ b/lib/core/utils/push_notification_handler.dart @@ -19,7 +19,12 @@ 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/cache_consts.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart'; +import 'package:hmg_patient_app_new/presentation/notifications/notification_details_page.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:uuid/uuid.dart'; @@ -523,6 +528,26 @@ class PushNotificationHandler { _incomingCall(remoteMessage.data); // showCallkitIncoming(); } else { + NotificationResponseModel notification = NotificationResponseModel(); + + notification.createdOn = DateUtil.convertDateToString(DateTime.now()); + notification.isSentOn = DateUtil.convertDateToString(DateTime.now()); + notification.messageTypeData = remoteMessage.data['picture']; + notification.messageType = notification.messageTypeData != null && notification.messageTypeData!.isNotEmpty ? "image" : ""; + notification.message = remoteMessage.data['message']; + notification.notificationType = remoteMessage.data["NotificationType"].toString(); + if (remoteMessage.data["NotificationType"] == "2") { + notification.videoURL = remoteMessage.data["VideoUrl"]; + } + + Navigator.of(getIt.get().navigatorKey.currentContext!).push( + CustomPageRoute( + page: NotificationDetailsPage( + notification: notification, + ), + ), + ); + // GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); // // notification.createdOn = DateUtil.convertDateToString(DateTime.now()); diff --git a/lib/presentation/notifications/notification_details_page.dart b/lib/presentation/notifications/notification_details_page.dart index ba78a298..70f87739 100644 --- a/lib/presentation/notifications/notification_details_page.dart +++ b/lib/presentation/notifications/notification_details_page.dart @@ -1,11 +1,13 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenshot_blocker/flutter_screenshot_blocker.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.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'; import 'package:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart'; +import 'package:hmg_patient_app_new/features/notifications/notifications_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; @@ -21,9 +23,10 @@ class NotificationDetailsPage extends StatelessWidget { @override Widget build(BuildContext context) { + getIt.get().markAsRead(notificationID: notification.id ?? 0); return ScreenshotBlockerWidget( - blockScreenshots: true, // makes this widget appear black in screenshots - detectScreenshots: true, // listen for screenshot attempts + blockScreenshots: true, // makes this widget appear black in screenshots + detectScreenshots: true, // listen for screenshot attempts onScreenshotDetected: (event) { // event.type → 'screenshot_taken' or 'screenshot_blocked' // ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/presentation/notifications/notifications_list_page.dart b/lib/presentation/notifications/notifications_list_page.dart index afea0fba..77f9a20a 100644 --- a/lib/presentation/notifications/notifications_list_page.dart +++ b/lib/presentation/notifications/notifications_list_page.dart @@ -49,187 +49,176 @@ class _NotificationsListPageState extends State { return CollapsingListView( title: LocaleKeys.notification.tr(context: context), child: Consumer(builder: (context, notificationsVM, child) { - return Column( - children: [ - Container( - margin: EdgeInsets.symmetric(vertical: 24.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: false, - ), - child: ListView.builder( - itemCount: notificationsVM.isNotificationsLoading - ? 4 - // : notificationsVM.notificationsList.length + (notificationsVM.hasMoreNotifications ? 1 : 0), - : notificationsVM.notificationsList.length, - physics: NeverScrollableScrollPhysics(), - shrinkWrap: true, - padding: EdgeInsetsGeometry.zero, - itemBuilder: (context, index) { - if (notificationsVM.isNotificationsLoading) { - return LabResultItemView( - onTap: () {}, - labOrder: null, - index: index, - isLoading: true, - ); - } - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 500), - child: SlideAnimation( - verticalOffset: 100.0, - child: FadeInAnimation( - child: GestureDetector( - onTap: () { - notificationsVM.markAsRead(notificationID: notificationsVM.notificationsList[index].id ?? 0); + return Column( + children: [ + Container( + margin: EdgeInsets.symmetric(vertical: 24.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: false, + ), + child: ListView.builder( + itemCount: notificationsVM.isNotificationsLoading + ? 4 + // : notificationsVM.notificationsList.length + (notificationsVM.hasMoreNotifications ? 1 : 0), + : notificationsVM.notificationsList.length, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsetsGeometry.zero, + itemBuilder: (context, index) { + if (notificationsVM.isNotificationsLoading) { + return LabResultItemView( + onTap: () {}, + labOrder: null, + index: index, + isLoading: true, + ); + } + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: GestureDetector( + onTap: () { + notificationsVM.markAsRead(notificationID: notificationsVM.notificationsList[index].id ?? 0); getIt.get().getPatientDashboard(); Navigator.push( - context, - MaterialPageRoute( - builder: (context) => NotificationDetailsPage( - notification: notificationsVM.notificationsList[index], + context, + MaterialPageRoute( + builder: (context) => NotificationDetailsPage( + notification: notificationsVM.notificationsList[index], + ), + ), + ); + }, + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 16.h), + // Message row with red dot for unread + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: notificationsVM.notificationsList[index].message!.toText16( + isBold: (notificationsVM.notificationsList[index].isRead == false), + weight: (notificationsVM.notificationsList[index].isRead == false) ? FontWeight.w600 : FontWeight.w400, + ), + ), + SizedBox(width: 8.w), + // Red dot for unread notifications ONLY + if (notificationsVM.notificationsList[index].isRead == false) + Container( + width: 8.w, + height: 8.w, + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, ), ), - ); - }, - child: AnimatedContainer( - duration: Duration(milliseconds: 300), - curve: Curves.easeInOut, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 16.h), - // Message row with red dot for unread - Row( - crossAxisAlignment: CrossAxisAlignment.start, + ], + ), + SizedBox(height: 12.h), + // First row: Time and Date chips with arrow + Row( + children: [ + // Time chip with clock icon + Container( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), + decoration: BoxDecoration( + color: AppColors.greyColor, + borderRadius: BorderRadius.circular(8), + ), + child: Directionality( + textDirection: ui.TextDirection.ltr, + child: Row( + mainAxisSize: MainAxisSize.min, children: [ - Expanded( - child: notificationsVM.notificationsList[index].message!.toText16( - isBold: (notificationsVM.notificationsList[index].isRead == false), - weight: (notificationsVM.notificationsList[index].isRead == false) - ? FontWeight.w600 - : FontWeight.w400, - ), - ), - SizedBox(width: 8.w), - // Red dot for unread notifications ONLY - if (notificationsVM.notificationsList[index].isRead == false) - Container( - width: 8.w, - height: 8.w, - decoration: BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, - ), - ), + Icon(Icons.access_time, size: 12.w, color: AppColors.textColor), + SizedBox(width: 4.w), + _formatTime(notificationsVM.notificationsList[index].isSentOn).toText10(weight: FontWeight.w600, color: AppColors.textColor, isEnglishOnly: true), ], ), - SizedBox(height: 12.h), - // First row: Time and Date chips with arrow - Row( + ), + ), + SizedBox(width: 8.w), + // Date chip with calendar icon + Container( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), + decoration: BoxDecoration( + color: AppColors.greyColor, + borderRadius: BorderRadius.circular(8), + ), + child: Directionality( + textDirection: ui.TextDirection.ltr, + child: Row( + mainAxisSize: MainAxisSize.min, children: [ - // Time chip with clock icon - Container( - padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), - decoration: BoxDecoration( - color: AppColors.greyColor, - borderRadius: BorderRadius.circular(8), - ), - child: Directionality( - textDirection: ui.TextDirection.ltr, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.access_time, size: 12.w, color: AppColors.textColor), - SizedBox(width: 4.w), - _formatTime(notificationsVM.notificationsList[index].isSentOn).toText10( - weight: FontWeight.w600, - color: AppColors.textColor, - isEnglishOnly: true - ), - ], - ), - ), - ), - SizedBox(width: 8.w), - // Date chip with calendar icon - Container( - padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), - decoration: BoxDecoration( - color: AppColors.greyColor, - borderRadius: BorderRadius.circular(8), - ), - child: Directionality( - textDirection: ui.TextDirection.ltr, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.calendar_today, size: 12.w, color: AppColors.textColor), - SizedBox(width: 4.w), - _formatDate(notificationsVM.notificationsList[index].isSentOn).toText10( - weight: FontWeight.w600, - color: AppColors.textColor, - isEnglishOnly: true - ), - ], - ), - ), - ), - Spacer(), - // Arrow icon - Transform.flip( - flipX: getIt.get().isArabic(), - child: Utils.buildSvgWithAssets( - icon: AppAssets.arrow_forward, - width: 16.w, - height: 16.h, - iconColor: AppColors.greyTextColor, - ), - ), + Icon(Icons.calendar_today, size: 12.w, color: AppColors.textColor), + SizedBox(width: 4.w), + _formatDate(notificationsVM.notificationsList[index].isSentOn).toText10(weight: FontWeight.w600, color: AppColors.textColor, isEnglishOnly: true), ], ), - // Second row: Contains Image chip (if MessageType is "image") - if (notificationsVM.notificationsList[index].messageType != null && - notificationsVM.notificationsList[index].messageType!.toLowerCase() == "image") - Padding( - padding: EdgeInsets.only(top: 8.h), - child: Row( - children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), - decoration: BoxDecoration( - color: AppColors.greyColor, - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.image_outlined, size: 12.w, color: AppColors.textColor), - SizedBox(width: 4.w), - LocaleKeys.containsImage.toText10( - weight: FontWeight.w600, - color: AppColors.textColor, - ), - ], - ), - ), - ], - ), + ), + ), + Spacer(), + // Arrow icon + Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.arrow_forward, + width: 16.w, + height: 16.h, + iconColor: AppColors.greyTextColor, + ), + ), + ], + ), + // Second row: Contains Image chip (if MessageType is "image") + if (notificationsVM.notificationsList[index].messageType != null && notificationsVM.notificationsList[index].messageType!.toLowerCase() == "image") + Padding( + padding: EdgeInsets.only(top: 8.h), + child: Row( + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), + decoration: BoxDecoration( + color: AppColors.greyColor, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.image_outlined, size: 12.w, color: AppColors.textColor), + SizedBox(width: 4.w), + LocaleKeys.containsImage.toText10( + weight: FontWeight.w600, + color: AppColors.textColor, + ), + ], ), - SizedBox(height: 16.h), - 1.divider, + ), ], ), ), - ), - ), + SizedBox(height: 16.h), + 1.divider, + ], ), - ); - }).paddingSymmetrical(16.w, 0.h), - ).paddingSymmetrical(24.w, 0.h), - SizedBox(height: 16.h), + ), + ), + ), + ), + ); + }).paddingSymmetrical(16.w, 0.h), + ).paddingSymmetrical(24.w, 0.h), + SizedBox(height: 16.h), // SizedBox( // key: _bottomKey, // child: "Show more notifications".toText16( @@ -242,9 +231,9 @@ class _NotificationsListPageState extends State { // _scrollToBottom(); // }), SizedBox(height: 24.h), - ], - ); - }), + ], + ); + }), ); }