From 4981a23e8e16f7f97598a9469662ab2ed5b196f0 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 27 Sep 2025 17:07:19 +0800 Subject: [PATCH] :sparkles: Chat summary realtime updates --- lib/pods/chat_summary.dart | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/pods/chat_summary.dart b/lib/pods/chat_summary.dart index d754eec6..ac810417 100644 --- a/lib/pods/chat_summary.dart +++ b/lib/pods/chat_summary.dart @@ -1,6 +1,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:island/models/chat.dart'; import 'package:island/pods/network.dart'; +import 'package:island/pods/websocket.dart'; part 'chat_summary.g.dart'; @@ -12,9 +13,27 @@ class ChatSummary extends _$ChatSummary { final resp = await client.get('/sphere/chat/summary'); final Map data = resp.data; - return data.map( + final summaries = data.map( (key, value) => MapEntry(key, SnChatSummary.fromJson(value)), ); + + final ws = ref.watch(websocketProvider); + final subscription = ws.dataStream.listen((WebSocketPacket pkt) { + if (!pkt.type.startsWith('messages')) return; + if (pkt.type == 'messages.new') { + final message = SnChatMessage.fromJson(pkt.data!); + updateLastMessage(message.chatRoomId, message); + } else if (pkt.type == 'messages.update') { + final message = SnChatMessage.fromJson(pkt.data!); + updateMessageContent(message.chatRoomId, message); + } + }); + + ref.onDispose(() { + subscription.cancel(); + }); + + return summaries; } Future clearUnreadCount(String chatId) async { @@ -61,4 +80,19 @@ class ChatSummary extends _$ChatSummary { } }); } + + void updateMessageContent(String chatId, SnChatMessage message) { + state.whenData((summaries) { + final summary = summaries[chatId]; + if (summary != null && summary.lastMessage?.id == message.id) { + state = AsyncData({ + ...summaries, + chatId: SnChatSummary( + unreadCount: summary.unreadCount, + lastMessage: message, + ), + }); + } + }); + } }