From 1fdbff77a1b7857861af63725fdb0d552d75586c Mon Sep 17 00:00:00 2001 From: llsajjad Date: Sat, 27 Sep 2025 15:27:45 +0330 Subject: [PATCH] fixed pagination --- lib/view_models/notification_view_model.dart | 16 ++++-- .../pages/m_notification_page.dart | 56 ++++++------------- .../strings/notification_strings.dart | 1 + .../widgets/notification_all_tab.dart | 15 ++++- .../widgets/notification_important_tab.dart | 14 +++-- .../widgets/notification_unread_tab.dart | 12 ++-- 6 files changed, 57 insertions(+), 57 deletions(-) diff --git a/lib/view_models/notification_view_model.dart b/lib/view_models/notification_view_model.dart index db48bbb..5be00ca 100644 --- a/lib/view_models/notification_view_model.dart +++ b/lib/view_models/notification_view_model.dart @@ -80,7 +80,8 @@ class NotificationViewModel with ChangeNotifier { } notifyListeners(); - final int offset = (page - 1) * _pageSize; + final int offset = page * _pageSize; + final result = await _repository.getNotifications( limit: _pageSize, offset: offset, @@ -89,10 +90,15 @@ class NotificationViewModel with ChangeNotifier { switch (result) { case Ok(): final data = result.value; + if (isPagination && allNotificationResponse != null) { final old = allNotificationResponse?.data ?? []; final fresh = data.data ?? []; - allNotificationResponse = data.copyWith(data: [...old, ...fresh]); + + allNotificationResponse = allNotificationResponse!.copyWith( + data: [...old, ...fresh], + meta: data.meta, + ); } else { allNotificationResponse = data; } @@ -101,7 +107,7 @@ class NotificationViewModel with ChangeNotifier { currentPageAll = page; totalPagesAll = data.meta?.pages ?? 1; - hasMoreAll = (data.data?.length ?? 0) >= _pageSize; + hasMoreAll = currentPageAll < totalPagesAll; break; case Error(): @@ -125,7 +131,7 @@ class NotificationViewModel with ChangeNotifier { } notifyListeners(); - final int offset = (page - 1) * _pageSize; + final int offset = page * _pageSize; final result = await _repository.getUnreadNotifications( limit: _pageSize, offset: offset, @@ -168,7 +174,7 @@ class NotificationViewModel with ChangeNotifier { } notifyListeners(); - final int offset = (page - 1) * _pageSize; + final int offset = page * _pageSize; final result = await _repository.getImportantNotifications( limit: _pageSize, diff --git a/lib/views/notification/pages/m_notification_page.dart b/lib/views/notification/pages/m_notification_page.dart index 9e91d32..dd94b67 100644 --- a/lib/views/notification/pages/m_notification_page.dart +++ b/lib/views/notification/pages/m_notification_page.dart @@ -24,6 +24,7 @@ class _MobileNotificationPageState extends State final ScrollController _scrollAll = ScrollController(); final ScrollController _scrollUnread = ScrollController(); + final ScrollController _scrollImportant = ScrollController(); @override void initState() { @@ -55,6 +56,18 @@ class _MobileNotificationPageState extends State ); } }); + + _scrollImportant.addListener(() { + if (_scrollImportant.position.pixels >= + _scrollImportant.position.maxScrollExtent - 100 && + !viewModel.isLoadingImportant && + viewModel.hasMoreImportant) { + viewModel.getImportantNotifications( + page: viewModel.currentPageImportant + 1, + isPagination: true, + ); + } + }); } @override @@ -62,6 +75,7 @@ class _MobileNotificationPageState extends State controller.dispose(); _scrollAll.dispose(); _scrollUnread.dispose(); + _scrollImportant.dispose(); super.dispose(); } @@ -83,45 +97,13 @@ class _MobileNotificationPageState extends State ], ), SizedBox(height: 12.0.h()), - Padding( - padding: EdgeInsetsDirectional.only(end: 24.0.w()), - child: Align( - alignment: Alignment.centerRight, - child: InkWell( - onTap: () { - viewModel.markAllAsRead(context); - }, - borderRadius: BorderRadius.circular(99), - child: Container( - width: 132.0.w(), - height: 32.0.h(), - decoration: BoxDecoration( - color: AppColors.primary20, - borderRadius: BorderRadius.circular(99), - ), - child: Center( - child: Text( - NotificationStrings.markAllAsReadButton, - style: TextStyle( - fontSize: 14.0.sp(), - fontWeight: FontWeight.w500, - color: AppColors.mainBlue, - ), - ), - ), - ), - ), - ), - ), - SizedBox(height: 12.0.h()), - Expanded( child: TabBarView( controller: controller, children: [ NotificationAllTab(scrollController: _scrollAll), NotificationUnreadTab(scrollController: _scrollUnread), - const NotificationImportantTab(), + NotificationImportantTab(scrollController: _scrollImportant), ], ), ), @@ -142,11 +124,9 @@ class _MobileNotificationPageState extends State ), ), - if ((viewModel.isLoadingAll && - (viewModel.allNotificationResponse?.data?.isEmpty ?? true)) || - (viewModel.isLoadingUnread && - (viewModel.unreadNotificationResponse?.data?.isEmpty ?? true))) - const Expanded( + if (viewModel.isMoreLoadingImportant) + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), child: Center( child: CircularProgressIndicator(color: AppColors.secondary50), ), diff --git a/lib/views/notification/strings/notification_strings.dart b/lib/views/notification/strings/notification_strings.dart index 32af793..2497f52 100644 --- a/lib/views/notification/strings/notification_strings.dart +++ b/lib/views/notification/strings/notification_strings.dart @@ -24,4 +24,5 @@ class NotificationStrings { static const String noUnreadNotifications = 'No unread notifications'; static const String noImportantNotifications = 'No important notifications'; static const String moreTextButton = 'More'; + static const String noNotifications = 'No notifications'; } diff --git a/lib/views/notification/widgets/notification_all_tab.dart b/lib/views/notification/widgets/notification_all_tab.dart index 6df4c93..d148ddd 100644 --- a/lib/views/notification/widgets/notification_all_tab.dart +++ b/lib/views/notification/widgets/notification_all_tab.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tm_app/view_models/notification_view_model.dart'; +import 'package:tm_app/views/notification/strings/notification_strings.dart'; import 'notification_card.dart'; @@ -12,8 +13,17 @@ class NotificationAllTab extends StatelessWidget { @override Widget build(BuildContext context) { final viewModel = context.watch(); - final notifications = - viewModel.allNotificationResponse?.data ?? []; + + if (viewModel.isLoadingAll && + (viewModel.allNotificationResponse?.data?.isEmpty ?? true)) { + return const Center(child: CircularProgressIndicator()); + } + + final notifications = viewModel.allNotificationResponse?.data ?? []; + + if (notifications.isEmpty) { + return const Center(child: Text(NotificationStrings.noNotifications)); + } return ListView.builder( controller: scrollController, @@ -28,3 +38,4 @@ class NotificationAllTab extends StatelessWidget { ); } } + diff --git a/lib/views/notification/widgets/notification_important_tab.dart b/lib/views/notification/widgets/notification_important_tab.dart index 9d5e417..93a7f01 100644 --- a/lib/views/notification/widgets/notification_important_tab.dart +++ b/lib/views/notification/widgets/notification_important_tab.dart @@ -13,14 +13,18 @@ class NotificationImportantTab extends StatelessWidget { Widget build(BuildContext context) { final viewModel = context.watch(); - if (viewModel.isLoadingImportant) { + if (viewModel.isLoadingImportant && + (viewModel.importantNotificationResponse?.data?.isEmpty ?? true)) { return const Center(child: CircularProgressIndicator()); } - final importantNotifications = viewModel.importantNotificationResponse?.data ?? []; + final importantNotifications = + viewModel.importantNotificationResponse?.data ?? []; if (importantNotifications.isEmpty) { - return const Center(child: Text(NotificationStrings.noImportantNotifications)); + return const Center( + child: Text(NotificationStrings.noImportantNotifications), + ); } return ListView.builder( @@ -30,9 +34,7 @@ class NotificationImportantTab extends StatelessWidget { final notification = importantNotifications[index]; return Padding( padding: const EdgeInsets.only(bottom: 16.0), - child: NotificationCard( - notification: notification, - ), + child: NotificationCard(notification: notification), ); }, ); diff --git a/lib/views/notification/widgets/notification_unread_tab.dart b/lib/views/notification/widgets/notification_unread_tab.dart index af714ce..a2990a7 100644 --- a/lib/views/notification/widgets/notification_unread_tab.dart +++ b/lib/views/notification/widgets/notification_unread_tab.dart @@ -3,7 +3,6 @@ import 'package:provider/provider.dart'; import 'package:tm_app/core/utils/size_config.dart'; import 'package:tm_app/view_models/notification_view_model.dart'; import 'package:tm_app/views/notification/strings/notification_strings.dart'; - import 'notification_card.dart'; class NotificationUnreadTab extends StatelessWidget { @@ -13,16 +12,17 @@ class NotificationUnreadTab extends StatelessWidget { @override Widget build(BuildContext context) { final viewModel = context.watch(); - - if (viewModel.isLoadingUnread){ + if (viewModel.isLoadingUnread && + (viewModel.unreadNotificationResponse?.data?.isEmpty ?? true)) { return const Center(child: CircularProgressIndicator()); } - final notifications = - viewModel.unreadNotificationResponse?.data ?? []; + final notifications = viewModel.unreadNotificationResponse?.data ?? []; if (notifications.isEmpty) { - return const Center(child: Text(NotificationStrings.noUnreadNotifications,)); + return const Center( + child: Text(NotificationStrings.noUnreadNotifications), + ); } return ListView.builder(