Files
voidea/flutter/lib/providers/notification_provider.dart
T

121 lines
3.3 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../core/api/client.dart';
import '../core/api/endpoints.dart';
import '../core/api/exceptions.dart';
import '../models/collaboration.dart';
class NotificationState {
final List<AppNotification> notifications;
final int unreadCount;
final bool isLoading;
final String? error;
NotificationState({
this.notifications = const [],
this.unreadCount = 0,
this.isLoading = false,
this.error,
});
NotificationState copyWith({
List<AppNotification>? notifications,
int? unreadCount,
bool? isLoading,
String? error,
}) =>
NotificationState(
notifications: notifications ?? this.notifications,
unreadCount: unreadCount ?? this.unreadCount,
isLoading: isLoading ?? this.isLoading,
error: error,
);
}
class NotificationNotifier extends StateNotifier<NotificationState> {
final ApiClient _api;
NotificationNotifier(this._api) : super(NotificationState());
Future<void> loadNotifications() async {
state = state.copyWith(isLoading: true);
try {
final response = await _api.get(Endpoints.notifications);
final list = (response.data as List<dynamic>)
.map((e) =>
AppNotification.fromJson(e as Map<String, dynamic>))
.toList();
state = state.copyWith(notifications: list, isLoading: false);
_updateUnreadCount();
} on ApiException catch (e) {
state = state.copyWith(isLoading: false, error: e.message);
}
}
Future<void> loadUnreadCount() async {
try {
final response =
await _api.get(Endpoints.notificationsUnreadCount);
state = state.copyWith(
unreadCount: response.data['count'] as int? ?? 0);
} catch (_) {}
}
Future<void> markAsRead(String id) async {
try {
await _api.patch(Endpoints.notification(id));
state = state.copyWith(
notifications: state.notifications.map((n) {
if (n.id == id) {
return AppNotification(
id: n.id,
userId: n.userId,
title: n.title,
body: n.body,
isRead: true,
ideaId: n.ideaId,
createdAt: n.createdAt,
);
}
return n;
}).toList(),
);
_updateUnreadCount();
} catch (_) {}
}
Future<void> markAllAsRead() async {
try {
await _api.post(Endpoints.notificationsReadAll);
state = state.copyWith(
notifications: state.notifications
.map((n) => AppNotification(
id: n.id,
userId: n.userId,
title: n.title,
body: n.body,
isRead: true,
ideaId: n.ideaId,
createdAt: n.createdAt,
))
.toList(),
unreadCount: 0,
);
} catch (_) {}
}
void _updateUnreadCount() {
state = state.copyWith(
unreadCount: state.notifications.where((n) => !n.isRead).length,
);
}
}
final notificationProvider = StateNotifierProvider<NotificationNotifier, NotificationState>((ref) {
final api = ref.read(apiClientProvider);
return NotificationNotifier(api);
});
final unreadCountProvider = Provider<int>((ref) {
return ref.watch(notificationProvider).unreadCount;
});