announcement_unread_provider.dart 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import 'package:flutter_riverpod/flutter_riverpod.dart';
  2. import '../core/network/dio_client.dart';
  3. import '../data/services/announcement_service.dart';
  4. import 'auth_provider.dart';
  5. class AnnouncementUnreadState {
  6. final bool isLoaded;
  7. final int unreadCount;
  8. final bool hasUnread;
  9. final int? latestId;
  10. final List<int> readIds;
  11. const AnnouncementUnreadState({
  12. this.isLoaded = false,
  13. this.unreadCount = 0,
  14. this.hasUnread = false,
  15. this.latestId,
  16. this.readIds = const [],
  17. });
  18. /// 未加载成功时视为已读(两边都不显示红点,保持一致)
  19. bool isRead(int announcementId) =>
  20. !isLoaded || readIds.contains(announcementId);
  21. }
  22. /// 公告未读数 Provider —— 未登录返回零;登录后请求 unread-count
  23. final announcementUnreadProvider =
  24. FutureProvider<AnnouncementUnreadState>((ref) async {
  25. final loggedIn = ref.watch(isLoggedInProvider);
  26. if (!loggedIn) {
  27. return const AnnouncementUnreadState();
  28. }
  29. final dio = ref.read(dioClientProvider);
  30. try {
  31. final r = await AnnouncementService(dio).getUnreadCount();
  32. return AnnouncementUnreadState(
  33. isLoaded: true,
  34. unreadCount: r.unreadCount,
  35. hasUnread: r.hasUnread,
  36. latestId: r.latestId,
  37. readIds: r.readIds,
  38. );
  39. } catch (_) {
  40. return const AnnouncementUnreadState(); // isLoaded=false,两边都不显示红点
  41. }
  42. });
  43. /// 标记指定公告为已读并刷新未读数
  44. Future<void> markAnnouncementsRead(WidgetRef ref, {required int id}) async {
  45. final loggedIn = ref.read(isLoggedInProvider);
  46. if (!loggedIn) return;
  47. final dio = ref.read(dioClientProvider);
  48. try {
  49. await AnnouncementService(dio).markRead(id);
  50. } catch (_) {
  51. // ignore
  52. }
  53. ref.invalidate(announcementUnreadProvider);
  54. }