From df100249754cf3083a849fb4665dd98b99748fac Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 <50428976+WaseemAbbasi22@users.noreply.github.com> Date: Mon, 20 Jul 2026 16:23:31 +0300 Subject: [PATCH] bug fixes --- lib/controllers/api_routes/urls.dart | 1 + .../firebase_notification_manger.dart | 10 ++++ .../providers/api/notifications_provider.dart | 57 ++++++++++++++++--- .../widgets/app_bar_widget.dart | 30 +++++++++- .../notifications/notifications_page.dart | 6 +- 5 files changed, 91 insertions(+), 13 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index d427ca8d..501df4b8 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -247,6 +247,7 @@ class URLs { static get getNotificationInbox => "$_baseUrl/NotificationNew/Inbox"; // get notifications with filters static get markAllNotificationsAsRead => "$_baseUrl/NotificationNew/MarkAllRead"; // mark all as read static get markOneNotificationAsRead => "$_baseUrl/NotificationNew/MarkAsReadOneNotification"; // mark one notification as read + static get getUnreadNotificationCount => "$_baseUrl/NotificationNew/GetUnread"; // mark one notification as read // Notification Filter Lookups static get getNotificationPriorityLookup => "$_baseUrl/Lookups/GetLookup?lookupEnum=5021"; // notification priority filter diff --git a/lib/controllers/notification/firebase_notification_manger.dart b/lib/controllers/notification/firebase_notification_manger.dart index 76468734..361a29e1 100644 --- a/lib/controllers/notification/firebase_notification_manger.dart +++ b/lib/controllers/notification/firebase_notification_manger.dart @@ -6,7 +6,9 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:google_api_availability/google_api_availability.dart'; import 'package:huawei_push/huawei_push.dart' as h_push; +import 'package:provider/provider.dart'; import 'package:test_sa/controllers/notification/notification_manger.dart'; +import 'package:test_sa/controllers/providers/api/notifications_provider.dart'; import 'package:test_sa/models/device/device_transfer.dart'; import 'package:test_sa/models/new_models/gas_refill_model.dart'; import 'package:test_sa/modules/cm_module/cm_detail_page.dart'; @@ -263,6 +265,14 @@ class FirebaseNotificationManger { hashcode: DateTime.now().millisecondsSinceEpoch.hashCode, payload: json.encode(message.data), context: context); + + // Update unread notification count badge when new notification arrives + try { + final notificationsProvider = Provider.of(context, listen: false); + notificationsProvider.getUnreadCount(); + } catch (e) { + log('Error updating notification count: $e'); + } } } return; diff --git a/lib/controllers/providers/api/notifications_provider.dart b/lib/controllers/providers/api/notifications_provider.dart index 5ddf1103..7b9d5188 100644 --- a/lib/controllers/providers/api/notifications_provider.dart +++ b/lib/controllers/providers/api/notifications_provider.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart'; @@ -120,8 +121,6 @@ class NotificationsProvider extends ChangeNotifier { } } - /// Mark all notifications as read - /// Returns a map with success status and message from API Future> markAllAsRead({required String userId}) async { try { final Map body = {"userId": userId}; @@ -159,8 +158,6 @@ class NotificationsProvider extends ChangeNotifier { } } - /// Mark one notification as read - /// Returns true if successful, false otherwise Future markOneAsRead({required String notificationId}) async { try { final response = await ApiManager.instance.get("${URLs.markOneNotificationAsRead}?NotificationId=$notificationId", enableToastMessage: false); @@ -188,11 +185,53 @@ class NotificationsProvider extends ChangeNotifier { } } - /// return -2 if request in progress - /// return -1 if error happen when sending request - /// return state code if request complete may be 200, 404 or 403 - /// for more details check http state manager - /// lib\controllers\http_status_manger\http_status_manger.dart + Future getUnreadCount() async { + int? count; + try { + final response = await ApiManager.instance.get(URLs.getUnreadNotificationCount, enableToastMessage: false); + if (response.statusCode >= 200 && response.statusCode < 300) { + final responseData = json.decode(response.body); + log('count response :: $responseData'); + count = responseData['data']; + // Update the totalNotificationUnread property + totalNotificationUnread = count ?? 0; + notifyListeners(); + } + return count; + } catch (error) { + print('Error getting unread notification count: $error'); + return count; + } + } + + /// Manually reset the unread count to zero + /// Useful when you want to clear the badge without making an API call + void resetUnreadCount() { + totalNotificationUnread = 0; + notifyListeners(); + } + + /// Update unread count manually (e.g., from push notification) + /// Useful when you receive a notification and want to increment the badge + void updateUnreadCount(int newCount) { + totalNotificationUnread = newCount; + notifyListeners(); + } + + /// Increment unread count by 1 (e.g., when receiving a new push notification) + void incrementUnreadCount() { + totalNotificationUnread++; + notifyListeners(); + } + + /// Decrement unread count by 1 (e.g., when marking one as read locally) + void decrementUnreadCount() { + if (totalNotificationUnread > 0) { + totalNotificationUnread--; + notifyListeners(); + } + } + Future?> getRecentNotifications({ required String host, required User user, diff --git a/lib/dashboard_latest/widgets/app_bar_widget.dart b/lib/dashboard_latest/widgets/app_bar_widget.dart index c2865647..78ffe1a0 100644 --- a/lib/dashboard_latest/widgets/app_bar_widget.dart +++ b/lib/dashboard_latest/widgets/app_bar_widget.dart @@ -1,7 +1,10 @@ +import 'dart:developer'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/providers/api/notifications_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; @@ -10,6 +13,7 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/custom_badge.dart'; import 'package:test_sa/views/pages/user/notifications/notifications_page.dart'; import 'package:test_sa/views/pages/user/notifications/unread_chat_list.dart'; @@ -38,6 +42,8 @@ class _AppBarWidgetState extends State with TickerProviderStateMix super.initState(); // Profile section animation (left to right with fade) + getUnreadCount(); + _leftController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, @@ -95,6 +101,12 @@ class _AppBarWidgetState extends State with TickerProviderStateMix super.dispose(); } + Future getUnreadCount () async{ + NotificationsProvider notificationsProvider = Provider.of(context,listen: false); + log('i am initstate'); + await notificationsProvider.getUnreadCount(); + } + @override Widget build(BuildContext context) { return AppBar( @@ -253,9 +265,21 @@ class _AppBarWidgetState extends State with TickerProviderStateMix }), 16.width, ], - ("dashboard/notification").toSvgAsset(height: 24, width: 24, color: AppColor.icon2Color(context)).paddingOnly(top: 0, end: 0).onPress(() { - Navigator.of(context).pushNamed(NotificationsPage.id); - }), + // Notification icon with unread count badge + Consumer( + builder: (context, notificationsProvider, child) { + final unreadCount = notificationsProvider.totalNotificationUnread; + return CustomBadge( + width: 20, + height: 20, + positionT: -10, + value: unreadCount, + child: ("dashboard/notification").toSvgAsset(height: 24, width: 24, color: AppColor.icon2Color(context)).paddingOnly(top: 0, end: 0), + ).onPress(() { + Navigator.of(context).pushNamed(NotificationsPage.id); + }); + }, + ), ], ), ), diff --git a/lib/views/pages/user/notifications/notifications_page.dart b/lib/views/pages/user/notifications/notifications_page.dart index 8025d0f0..d2510879 100644 --- a/lib/views/pages/user/notifications/notifications_page.dart +++ b/lib/views/pages/user/notifications/notifications_page.dart @@ -36,7 +36,7 @@ class _NotificationsPageState extends State with TickerProvid final TextEditingController _searchController = TextEditingController(); int _selectedTabIndex = 0; // 0: All, 1: Unread, 2: Read String _searchQuery = ''; - bool isAscending = false; + bool isAscending = true; NotificationFilterModel? _activeFilters; Timer? _debounceTimer; @@ -77,6 +77,10 @@ class _NotificationsPageState extends State with TickerProvid resetProvider: true, filters: _activeFilters, ); + + // Refresh the unread count after loading notifications + // This updates the badge on the app bar + await notificationsProvider.getUnreadCount(); } void _onSearchChanged(String value) {