tasq/lib/providers/notifications_provider.dart
2026-02-11 20:12:48 +08:00

99 lines
2.8 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/notification_item.dart';
import 'profile_provider.dart';
import 'supabase_provider.dart';
import '../utils/app_time.dart';
final notificationsProvider = StreamProvider<List<NotificationItem>>((ref) {
final userId = ref.watch(currentUserIdProvider);
if (userId == null) {
return const Stream.empty();
}
final client = ref.watch(supabaseClientProvider);
return client
.from('notifications')
.stream(primaryKey: ['id'])
.eq('user_id', userId)
.order('created_at', ascending: false)
.map((rows) => rows.map(NotificationItem.fromMap).toList());
});
final unreadNotificationsCountProvider = Provider<int>((ref) {
final notificationsAsync = ref.watch(notificationsProvider);
return notificationsAsync.maybeWhen(
data: (items) => items.where((item) => item.isUnread).length,
orElse: () => 0,
);
});
final notificationsControllerProvider = Provider<NotificationsController>((
ref,
) {
final client = ref.watch(supabaseClientProvider);
return NotificationsController(client);
});
class NotificationsController {
NotificationsController(this._client);
final SupabaseClient _client;
Future<void> createMentionNotifications({
required List<String> userIds,
required String actorId,
required int messageId,
String? ticketId,
String? taskId,
}) async {
if (userIds.isEmpty) return;
if ((ticketId == null || ticketId.isEmpty) &&
(taskId == null || taskId.isEmpty)) {
return;
}
final rows = userIds
.map(
(userId) => {
'user_id': userId,
'actor_id': actorId,
'ticket_id': ticketId,
'task_id': taskId,
'message_id': messageId,
'type': 'mention',
},
)
.toList();
await _client.from('notifications').insert(rows);
}
Future<void> markRead(String id) async {
await _client
.from('notifications')
.update({'read_at': AppTime.nowUtc().toIso8601String()})
.eq('id', id);
}
Future<void> markReadForTicket(String ticketId) async {
final userId = _client.auth.currentUser?.id;
if (userId == null) return;
await _client
.from('notifications')
.update({'read_at': AppTime.nowUtc().toIso8601String()})
.eq('ticket_id', ticketId)
.eq('user_id', userId)
.filter('read_at', 'is', null);
}
Future<void> markReadForTask(String taskId) async {
final userId = _client.auth.currentUser?.id;
if (userId == null) return;
await _client
.from('notifications')
.update({'read_at': AppTime.nowUtc().toIso8601String()})
.eq('task_id', taskId)
.eq('user_id', userId)
.filter('read_at', 'is', null);
}
}