From 1a1a3a5155d9e64f383d505fe717fe746c0a413f Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 18 Apr 2024 22:43:14 +0800 Subject: [PATCH] :sparkles: Handle more chat server events --- lib/i18n/app_en.arb | 1 + lib/i18n/app_zh.arb | 1 + lib/screens/chat/chat.dart | 22 ++++++++++--- lib/widgets/chat/maintainer.dart | 56 +++++++++++++++++++++++++------- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/lib/i18n/app_en.arb b/lib/i18n/app_en.arb index c4cfa51..aa25cda 100644 --- a/lib/i18n/app_en.arb +++ b/lib/i18n/app_en.arb @@ -28,6 +28,7 @@ "takeVideo": "Record video", "newMoment": "Record a moment", "newComment": "Leave a comment", + "connectingServer": "Connecting to server...", "postIdentityNotify": "You will create this post as", "postContentPlaceholder": "What's happened?!", "postDeleteConfirm": "Are you sure you want to delete this post? This operation cannot be revert!", diff --git a/lib/i18n/app_zh.arb b/lib/i18n/app_zh.arb index 5bb4924..3ad1ee8 100644 --- a/lib/i18n/app_zh.arb +++ b/lib/i18n/app_zh.arb @@ -28,6 +28,7 @@ "takeVideo": "拍摄视频", "newMoment": "记录时刻", "newComment": "留下评论", + "connectingServer": "正在连接至服务器……", "postIdentityNotify": "你将会以该身份发表本帖子", "postContentPlaceholder": "发生什么事了?!", "postDeleteConfirm": "你确定要删除这篇帖子吗?这意味着这个帖子将永远被我们丢弃在硬盘海中!该操作不可被反转!", diff --git a/lib/screens/chat/chat.dart b/lib/screens/chat/chat.dart index 5d0712b..318688f 100644 --- a/lib/screens/chat/chat.dart +++ b/lib/screens/chat/chat.dart @@ -79,10 +79,20 @@ class _ChatScreenState extends State { } void addMessage(Message item) { - WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() { - _pagingController.itemList?.insert(0, item); - }); + setState(() { + _pagingController.itemList?.insert(0, item); + }); + } + + void updateMessage(Message item) { + setState(() { + _pagingController.itemList = _pagingController.itemList?.map((x) => x.id == item.id ? item : x).toList(); + }); + } + + void deleteMessage(Message item) { + setState(() { + _pagingController.itemList = _pagingController.itemList?.where((x) => x.id != item.id).toList(); }); } @@ -138,7 +148,9 @@ class _ChatScreenState extends State { ChatMessageEditor(channel: widget.alias), ], ), - onNewMessage: (message) => addMessage(message), + onInsertMessage: (message) => addMessage(message), + onUpdateMessage: (message) => updateMessage(message), + onDeleteMessage: (message) => deleteMessage(message), ), ); } diff --git a/lib/widgets/chat/maintainer.dart b/lib/widgets/chat/maintainer.dart index db8403e..b32d44a 100644 --- a/lib/widgets/chat/maintainer.dart +++ b/lib/widgets/chat/maintainer.dart @@ -6,33 +6,65 @@ import 'package:solian/models/message.dart'; import 'package:solian/models/packet.dart'; import 'package:solian/providers/auth.dart'; import 'package:solian/providers/chat.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class ChatMaintainer extends StatefulWidget { final Widget child; - final Function(Message val) onNewMessage; + final Function(Message val) onInsertMessage; + final Function(Message val) onUpdateMessage; + final Function(Message val) onDeleteMessage; - const ChatMaintainer({super.key, required this.child, required this.onNewMessage}); + const ChatMaintainer({ + super.key, + required this.child, + required this.onInsertMessage, + required this.onUpdateMessage, + required this.onDeleteMessage, + }); @override State createState() => _ChatMaintainerState(); } class _ChatMaintainerState extends State { - @override - void initState() { - Future.delayed(Duration.zero, () { - final auth = context.read(); - final chat = context.read(); + void connect() { + final notify = ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.connectingServer), + duration: const Duration(days: 1), + ), + ); - chat.connect(auth).then((snapshot) { - snapshot!.stream.listen((event) { + final auth = context.read(); + final chat = context.read(); + + chat.connect(auth).then((snapshot) { + snapshot!.stream.listen( + (event) { final result = NetworkPackage.fromJson(jsonDecode(event)); switch (result.method) { case 'messages.new': - widget.onNewMessage(Message.fromJson(result.payload!)); + widget.onInsertMessage(Message.fromJson(result.payload!)); + break; + case 'messages.update': + widget.onUpdateMessage(Message.fromJson(result.payload!)); + break; + case 'messages.burnt': + widget.onDeleteMessage(Message.fromJson(result.payload!)); + break; } - }); - }); + }, + onError: (_, __) => connect(), + ); + + notify.close(); + }); + } + + @override + void initState() { + Future.delayed(Duration.zero, () { + connect(); }); super.initState();