Fixed notification pagination for all and unread
This commit is contained in:
@@ -5,80 +5,80 @@ import 'package:tm_app/data/repositories/notification_repository.dart';
|
||||
import 'package:tm_app/data/services/model/notification__response/notification_response_model.dart';
|
||||
import 'package:tm_app/views/notification/strings/notification_strings.dart';
|
||||
|
||||
|
||||
class NotificationViewModel with ChangeNotifier {
|
||||
final NotificationsRepository _repository;
|
||||
|
||||
NotificationViewModel({required NotificationsRepository repositoryViewModel})
|
||||
: _repository = repositoryViewModel {
|
||||
: _repository = repositoryViewModel {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
getNotifications();
|
||||
getUnreadNotifications();
|
||||
getImportantNotifications();
|
||||
});
|
||||
}
|
||||
|
||||
bool _isLoading = false;
|
||||
String? _errorMessage;
|
||||
NotificationResponseModel? _notificationResponseModel;
|
||||
|
||||
int currentPage = 1;
|
||||
static const int _pageSize = 10;
|
||||
int _totalPages = 0;
|
||||
bool _hasMoreData = true;
|
||||
|
||||
bool get isLoading => _isLoading;
|
||||
String? _errorMessage;
|
||||
String? get errorMessage => _errorMessage;
|
||||
NotificationResponseModel? get notificationResponse =>
|
||||
_notificationResponseModel;
|
||||
bool get hasMoreData => _hasMoreData;
|
||||
int get totalPages => _totalPages;
|
||||
|
||||
NotificationResponseModel? _unreadNotificationResponse;
|
||||
bool _isUnreadLoading = false;
|
||||
// All
|
||||
NotificationResponseModel? allNotificationResponse;
|
||||
bool isLoadingAll = false;
|
||||
bool isMoreLoadingAll = false;
|
||||
bool hasMoreAll = true;
|
||||
int currentPageAll = 1;
|
||||
int totalPagesAll = 0;
|
||||
|
||||
NotificationResponseModel? get unreadNotificationResponse =>
|
||||
_unreadNotificationResponse;
|
||||
bool get isUnreadLoading => _isUnreadLoading;
|
||||
// Unread
|
||||
NotificationResponseModel? unreadNotificationResponse;
|
||||
bool isLoadingUnread = false;
|
||||
bool isMoreLoadingUnread = false;
|
||||
bool hasMoreUnread = true;
|
||||
int currentPageUnread = 1;
|
||||
int totalPagesUnread = 0;
|
||||
|
||||
bool _isMoreLoading = false;
|
||||
bool get isMoreLoading => _isMoreLoading;
|
||||
// Important
|
||||
NotificationResponseModel? importantNotificationResponse;
|
||||
bool isLoadingImportant = false;
|
||||
bool isMoreLoadingImportant = false;
|
||||
bool hasMoreImportant = true;
|
||||
int currentPageImportant = 1;
|
||||
int totalPagesImportant = 0;
|
||||
|
||||
/// Fetch notifications
|
||||
Future<void> getNotifications({int page = 1, bool isMobile = false}) async {
|
||||
if (isMobile && page > 1) {
|
||||
_isMoreLoading = true;
|
||||
|
||||
Future<void> getNotifications({int page = 1, bool isPagination = false}) async {
|
||||
if (isPagination) {
|
||||
isMoreLoadingAll = true;
|
||||
} else {
|
||||
_isLoading = true;
|
||||
isLoadingAll = true;
|
||||
}
|
||||
notifyListeners();
|
||||
|
||||
final int offset = _pageSize * page;
|
||||
|
||||
final result = await _repository.getNotifications(
|
||||
limit: _pageSize,
|
||||
offset: offset,
|
||||
);
|
||||
final int offset = (page - 1) * _pageSize;
|
||||
final result = await _repository.getNotifications(limit: _pageSize, offset: offset);
|
||||
|
||||
switch (result) {
|
||||
case Ok<NotificationResponseModel>():
|
||||
if (isMobile && page > 1) {
|
||||
final oldNotifications =
|
||||
_notificationResponseModel?.data?.notifications ?? [];
|
||||
|
||||
final newNotifications = result.value.data?.notifications ?? [];
|
||||
|
||||
_notificationResponseModel = result.value.copyWith(
|
||||
data: result.value.data?.copyWith(
|
||||
notifications: [...oldNotifications, ...newNotifications],
|
||||
final data = result.value;
|
||||
if (isPagination && allNotificationResponse != null) {
|
||||
final old = allNotificationResponse?.data?.notifications ?? [];
|
||||
final fresh = data.data?.notifications ?? [];
|
||||
allNotificationResponse = data.copyWith(
|
||||
data: data.data?.copyWith(
|
||||
notifications: [...old, ...fresh],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
_notificationResponseModel = result.value;
|
||||
allNotificationResponse = data;
|
||||
}
|
||||
|
||||
currentPage = page;
|
||||
_hasMoreData =
|
||||
(result.value.data?.notifications?.length ?? 0) >= _pageSize;
|
||||
_totalPages = result.value.data?.meta?.pages ?? 1;
|
||||
_updateImportantFromAll();
|
||||
|
||||
currentPageAll = page;
|
||||
totalPagesAll = data.data?.meta?.pages ?? 1;
|
||||
hasMoreAll = (data.data?.notifications?.length ?? 0) >= _pageSize;
|
||||
break;
|
||||
|
||||
case Error<NotificationResponseModel>():
|
||||
@@ -86,22 +86,136 @@ class NotificationViewModel with ChangeNotifier {
|
||||
break;
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
_isMoreLoading = false;
|
||||
isLoadingAll = false;
|
||||
isMoreLoadingAll = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Jump to page
|
||||
Future<void> jumpToPage(int page) async {
|
||||
if (_totalPages == 0 || page < 1 || page > _totalPages) {
|
||||
Future<void> getUnreadNotifications({int page = 1, bool isPagination = false}) async {
|
||||
if (isPagination) {
|
||||
isMoreLoadingUnread = true;
|
||||
} else {
|
||||
isLoadingUnread = true;
|
||||
}
|
||||
notifyListeners();
|
||||
|
||||
final int offset = (page - 1) * _pageSize;
|
||||
final result = await _repository.getUnreadNotifications(limit: _pageSize, offset: offset);
|
||||
|
||||
switch (result) {
|
||||
case Ok<NotificationResponseModel>():
|
||||
final data = result.value;
|
||||
if (isPagination && unreadNotificationResponse != null) {
|
||||
final old = unreadNotificationResponse?.data?.notifications ?? [];
|
||||
final fresh = data.data?.notifications ?? [];
|
||||
unreadNotificationResponse = data.copyWith(
|
||||
data: data.data?.copyWith(
|
||||
notifications: [...old, ...fresh],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
unreadNotificationResponse = data;
|
||||
}
|
||||
|
||||
currentPageUnread = page;
|
||||
totalPagesUnread = data.data?.meta?.pages ?? 1;
|
||||
hasMoreUnread = (data.data?.notifications?.length ?? 0) >= _pageSize;
|
||||
break;
|
||||
|
||||
case Error<NotificationResponseModel>():
|
||||
_errorMessage = result.error.toString();
|
||||
break;
|
||||
}
|
||||
|
||||
isLoadingUnread = false;
|
||||
isMoreLoadingUnread = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getImportantNotifications({int page = 1, bool isPagination = false}) async {
|
||||
if (isPagination) {
|
||||
isMoreLoadingImportant = true;
|
||||
} else {
|
||||
isLoadingImportant = true;
|
||||
}
|
||||
notifyListeners();
|
||||
|
||||
final int offset = (page - 1) * _pageSize;
|
||||
|
||||
final result = await _repository.getUnreadNotifications(limit: _pageSize, offset: offset);
|
||||
|
||||
switch (result) {
|
||||
case Ok<NotificationResponseModel>():
|
||||
final data = result.value;
|
||||
if (isPagination && importantNotificationResponse != null) {
|
||||
final old = importantNotificationResponse?.data?.notifications ?? [];
|
||||
final fresh = data.data?.notifications ?? [];
|
||||
importantNotificationResponse = data.copyWith(
|
||||
data: data.data?.copyWith(
|
||||
notifications: [...old, ...fresh],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
importantNotificationResponse = data;
|
||||
}
|
||||
|
||||
currentPageImportant = page;
|
||||
totalPagesImportant = data.data?.meta?.pages ?? 1;
|
||||
hasMoreImportant = (data.data?.notifications?.length ?? 0) >= _pageSize;
|
||||
break;
|
||||
|
||||
case Error<NotificationResponseModel>():
|
||||
|
||||
_errorMessage = result.error.toString();
|
||||
|
||||
_updateImportantFromAll();
|
||||
break;
|
||||
}
|
||||
|
||||
isLoadingImportant = false;
|
||||
isMoreLoadingImportant = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _updateImportantFromAll() {
|
||||
final all = allNotificationResponse?.data?.notifications ?? [];
|
||||
final filtered = (all.where((n) {
|
||||
final p = n.priority ?? '';
|
||||
return p.toLowerCase() == 'important';
|
||||
}).toList());
|
||||
|
||||
if (allNotificationResponse != null) {
|
||||
importantNotificationResponse = allNotificationResponse!.copyWith(
|
||||
data: allNotificationResponse!.data!.copyWith(notifications: filtered),
|
||||
);
|
||||
} else {
|
||||
importantNotificationResponse = null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> jumpToPageAll(int page) async {
|
||||
if (totalPagesAll == 0 || page < 1 || page > totalPagesAll) {
|
||||
return;
|
||||
}
|
||||
await getNotifications(page: page);
|
||||
}
|
||||
|
||||
/// Mark all as read
|
||||
Future<void> jumpToPageUnread(int page) async {
|
||||
if (totalPagesUnread == 0 || page < 1 || page > totalPagesUnread) {
|
||||
return;
|
||||
}
|
||||
await getUnreadNotifications(page: page);
|
||||
}
|
||||
|
||||
Future<void> jumpToPageImportant(int page) async {
|
||||
if (totalPagesImportant == 0 || page < 1 || page > totalPagesImportant) {
|
||||
return;
|
||||
}
|
||||
await getImportantNotifications(page: page);
|
||||
}
|
||||
|
||||
Future<void> markAllAsRead(BuildContext context) async {
|
||||
_isLoading = true;
|
||||
isLoadingAll = true;
|
||||
_errorMessage = null;
|
||||
notifyListeners();
|
||||
|
||||
@@ -115,35 +229,39 @@ class NotificationViewModel with ChangeNotifier {
|
||||
case Ok<Map<String, dynamic>>():
|
||||
final response = result.value;
|
||||
final success = response['success'] as bool? ?? false;
|
||||
final message =
|
||||
response['message'] as String? ??
|
||||
NotificationStrings.unknownResponse;
|
||||
final message = response['message'] as String? ?? NotificationStrings.unknownResponse;
|
||||
|
||||
if (success) {
|
||||
if (_notificationResponseModel?.data?.notifications != null) {
|
||||
final updatedNotifications =
|
||||
_notificationResponseModel!.data!.notifications!
|
||||
.map((n) => n.copyWith(seen: true))
|
||||
.toList();
|
||||
if (allNotificationResponse?.data?.notifications != null) {
|
||||
final updatedNotifications = allNotificationResponse!.data!.notifications!
|
||||
.map((n) => n.copyWith(seen: true))
|
||||
.toList();
|
||||
|
||||
_notificationResponseModel = _notificationResponseModel!.copyWith(
|
||||
data: _notificationResponseModel!.data!.copyWith(
|
||||
allNotificationResponse = allNotificationResponse!.copyWith(
|
||||
data: allNotificationResponse!.data!.copyWith(
|
||||
notifications: updatedNotifications,
|
||||
),
|
||||
);
|
||||
|
||||
_unreadNotificationResponse = _unreadNotificationResponse?.copyWith(
|
||||
data: _unreadNotificationResponse?.data?.copyWith(
|
||||
notifications: [],
|
||||
),
|
||||
unreadNotificationResponse = unreadNotificationResponse?.copyWith(
|
||||
data: unreadNotificationResponse?.data?.copyWith(notifications: []),
|
||||
);
|
||||
|
||||
if (importantNotificationResponse?.data?.notifications != null) {
|
||||
final updatedImportant = importantNotificationResponse!.data!.notifications!
|
||||
.map((n) => n.copyWith(seen: true))
|
||||
.toList();
|
||||
|
||||
importantNotificationResponse = importantNotificationResponse!.copyWith(
|
||||
data: importantNotificationResponse!.data!.copyWith(
|
||||
notifications: updatedImportant,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
AppToast.success(
|
||||
context,
|
||||
NotificationStrings.allNotificationMarkedAsRead,
|
||||
);
|
||||
AppToast.success(context, NotificationStrings.allNotificationMarkedAsRead);
|
||||
}
|
||||
} else {
|
||||
_errorMessage = message;
|
||||
@@ -161,7 +279,7 @@ class NotificationViewModel with ChangeNotifier {
|
||||
break;
|
||||
}
|
||||
|
||||
_isLoading = false;
|
||||
isLoadingAll = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -182,28 +300,4 @@ class NotificationViewModel with ChangeNotifier {
|
||||
return '${difference.inDays} ${NotificationStrings.daysAgo}';
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getUnreadNotifications({int page = 1}) async {
|
||||
_isUnreadLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final int offset = _pageSize * page;
|
||||
|
||||
final result = await _repository.getUnreadNotifications(
|
||||
limit: _pageSize,
|
||||
offset: offset,
|
||||
);
|
||||
|
||||
switch (result) {
|
||||
case Ok<NotificationResponseModel>():
|
||||
_unreadNotificationResponse = result.value;
|
||||
break;
|
||||
case Error<NotificationResponseModel>():
|
||||
_errorMessage = result.error.toString();
|
||||
break;
|
||||
}
|
||||
|
||||
_isUnreadLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user