onufitness_mobile/lib/controller/notification_controller.dart
2026-01-13 11:36:24 +05:30

230 lines
6.7 KiB
Dart

import 'dart:developer';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:onufitness/constants/api_enum_constant.dart';
import 'package:onufitness/models/notification/get_all_notification_response_model.dart';
import 'package:onufitness/services/api_services/base_api_services.dart';
class NotificationController extends GetxController {
// Observables
var notificationResponse = Rxn<GetAllNotificationResponseModel>();
var isLoading = true.obs;
var isLoadingMore = false.obs;
var errorMessage = RxnString();
var hasReachedEnd = false.obs;
// Pagination variables
var currentPage = 1.obs;
static const int pageSize = 20;
var allNotifications = <NotificationItem>[].obs;
// Scroll controller for pagination
final ScrollController scrollController = ScrollController();
@override
void onInit() {
super.onInit();
_setupScrollListener();
fetchNotifications(isRefresh: true);
}
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
void _setupScrollListener() {
scrollController.addListener(() {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 200) {
if (!isLoadingMore.value && !hasReachedEnd.value) {
loadMore();
}
}
});
}
// Getters
List<NotificationItem> get notifications => allNotifications;
int get totalUnseenCount =>
notificationResponse.value?.data?.totalUnseenCount ?? 0;
bool get hasUnreadNotifications => totalUnseenCount > 0;
//fetch Notifications API Call ................................................................................
Future<void> fetchNotifications({bool isRefresh = false}) async {
try {
if (isRefresh) {
isLoading.value = true;
currentPage.value = 1;
hasReachedEnd.value = false;
allNotifications.clear();
}
errorMessage.value = null;
final response = await ApiBase.getRequest(
extendedURL:
"/api/Notifications/get-notifications-by-userID?PageNumber=${currentPage.value}&PageSize=$pageSize",
);
if (response.statusCode == 200) {
final responseModel = getAllNotificationResponseModelFromJson(
response.body,
);
notificationResponse.value = responseModel;
if (responseModel.data?.items != null) {
if (isRefresh) {
allNotifications.value = responseModel.data!.items!;
} else {
allNotifications.addAll(responseModel.data!.items!);
}
// Check if we've reached the end
if (responseModel.data!.items!.length < pageSize) {
hasReachedEnd.value = true;
}
} else {
hasReachedEnd.value = true;
}
} else {
errorMessage.value = 'Failed to load notifications';
}
} catch (e) {
errorMessage.value = 'Error: $e';
} finally {
isLoading.value = false;
isLoadingMore.value = false;
}
}
//..............................................................................................................
//..............................................................................................................
Future<void> loadMore() async {
if (hasReachedEnd.value || isLoadingMore.value) return;
isLoadingMore.value = true;
currentPage.value++;
await fetchNotifications(isRefresh: false);
}
Future<void> refreshNotifications() async {
await fetchNotifications(isRefresh: true);
}
Future<void> markNotificationAsRead(int notificationId) async {
log("Entered in markNotificationAsRead");
try {
final response = await ApiBase.patchRequest(
extendedURL: "/api/Notifications/update-notification/$notificationId",
);
log(response.statusCode.toString());
log(response.body.toString());
if (response.statusCode == 200) {
// Update local state
final itemIndex = allNotifications.indexWhere(
(item) => item.notificationId == notificationId,
);
if (itemIndex != -1) {
allNotifications[itemIndex].isSeen = true;
// Update unseen count
if (notificationResponse.value?.data != null) {
notificationResponse.value!.data!.totalUnseenCount =
(notificationResponse.value!.data!.totalUnseenCount ?? 1) - 1;
}
// Trigger reactive update
allNotifications.refresh();
notificationResponse.refresh();
}
}
} catch (e) {
log("Catch : Failed to Mark Read notification");
}
}
Future<void> markAllAsRead() async {
log("markAllAsRead");
try {
final response = await ApiBase.patchRequest(
extendedURL: "/api/Notifications/mark-all-as-read",
);
log(response.statusCode.toString());
log(response.body.toString());
if (response.statusCode == 200) {
// Update local state
for (var item in allNotifications) {
item.isSeen = true;
}
// Update unseen count
if (notificationResponse.value?.data != null) {
notificationResponse.value!.data!.totalUnseenCount = 0;
}
allNotifications.refresh();
notificationResponse.refresh();
}
} catch (e) {
log("Catch : Failed to Mark all Read notification");
}
}
// Utility Methods
IconData getNotificationIcon(int? notificationType) {
switch (notificationType) {
case ApiEnum.Goal:
return Icons.fitness_center;
case ApiEnum.Challenge:
return Icons.event;
case ApiEnum.ConnectionRequest:
return Icons.people;
case ApiEnum.Post:
return Icons.image;
case ApiEnum.RequestAccepted:
return Icons.person;
case ApiEnum.CoachRequest:
return Icons.notifications;
case ApiEnum.ReportPost:
return Icons.report;
case ApiEnum.ChallengeCompleted:
return Icons.event;
case ApiEnum.GoalCompleted:
return Icons.fitness_center;
default:
return Icons.notifications;
}
}
Color getNotificationColor(int? notificationType) {
switch (notificationType) {
case ApiEnum.Goal:
return Colors.blue;
case ApiEnum.Challenge:
return Colors.orange;
case ApiEnum.ConnectionRequest:
return Colors.green;
case ApiEnum.Post:
return Colors.red;
case ApiEnum.RequestAccepted:
return Colors.purple;
case ApiEnum.CoachRequest:
return Colors.brown;
case ApiEnum.ReportPost:
return Colors.grey;
case ApiEnum.ChallengeCompleted:
return Colors.purpleAccent;
case ApiEnum.GoalCompleted:
return Colors.deepPurple;
default:
return Colors.grey;
}
}
}