import 'package:flutter/material.dart'; import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/data/repositories/notification_repository.dart'; import 'package:tm_app/data/services/model/notification__response/notification_response_model.dart'; class NotificationViewModel with ChangeNotifier { final NotificationsRepository _repository; NotificationViewModel({required NotificationsRepository repositoryViewModel}) : _repository = repositoryViewModel { WidgetsBinding.instance.addPostFrameCallback((_) { getNotifications(); }); } 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? get errorMessage => _errorMessage; NotificationResponseModel? get notificationResponse => _notificationResponseModel; bool get hasMoreData => _hasMoreData; int get totalPages => _totalPages; /// Fetch notifications Future getNotifications({int page = 1, bool isMobile = false}) async { _isLoading = true; notifyListeners(); final int offset = _pageSize * page; final result = await _repository.getNotifications( limit: _pageSize, offset: offset, ); switch (result) { case Ok(): 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], ), ); } else { _notificationResponseModel = result.value; } currentPage = page; _hasMoreData = (result.value.data?.notifications?.length ?? 0) >= _pageSize; _totalPages = result.value.data?.meta?.pages ?? 1; break; case Error(): _errorMessage = result.error.toString(); break; } _isLoading = false; notifyListeners(); } /// Jump to page Future jumpToPage(int page) async { if (_totalPages == 0 || page < 1 || page > _totalPages) { return; } await getNotifications(page: page); } /// Mark all as read Future markAllAsRead() async { _errorMessage = null; notifyListeners(); final result = await _repository.markAllAsRead(); switch (result) { case Ok(): if (_notificationResponseModel?.data?.notifications != null) { final updatedNotifications = _notificationResponseModel!.data!.notifications! .map((n) => n.copyWith(seen: true)) .toList(); _notificationResponseModel = _notificationResponseModel!.copyWith( data: _notificationResponseModel!.data!.copyWith( notifications: updatedNotifications, ), ); } break; case Error(): _errorMessage = result.error.toString(); break; } notifyListeners(); } String timeAgo(String dateTimeString) { final createdAt = DateTime.parse(dateTimeString); final now = DateTime.now(); final difference = now.difference(createdAt); if (difference.inMinutes < 1) { return 'Now'; } else if (difference.inMinutes < 60) { return '${difference.inMinutes} Min '; } else if (difference.inHours < 24) { return '${difference.inHours} Hour '; } else if (difference.inDays == 1) { return 'Yesterday'; } else { return '${difference.inDays} days ago'; } } }