From b0be88983314bbd797ee1a6242dd04fde57bafb4 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sun, 19 Apr 2020 13:42:47 +0200 Subject: [PATCH] Register to conversation updates --- lib/helpers/conversations_helper.dart | 26 ++++++++++++++++++ lib/ui/screens/conversation_screen.dart | 35 ++++++++++++------------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index 5547471..d7f003d 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -1,6 +1,7 @@ import 'package:comunic/helpers/database/conversation_messages_database_helper.dart'; import 'package:comunic/helpers/database/conversations_database_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; +import 'package:comunic/helpers/websocket_helper.dart'; import 'package:comunic/lists/conversation_messages_list.dart'; import 'package:comunic/lists/conversations_list.dart'; import 'package:comunic/lists/users_list.dart'; @@ -20,6 +21,8 @@ import 'package:meta/meta.dart'; enum SendMessageResult { SUCCESS, MESSAGE_REJECTED, FAILED } class ConversationsHelper { + static final _registeredConversations = Map(); + final ConversationsDatabaseHelper _conversationsDatabaseHelper = ConversationsDatabaseHelper(); final ConversationMessagesDatabaseHelper _conversationMessagesDatabaseHelper = @@ -356,6 +359,29 @@ class ConversationsHelper { return await _conversationMessagesDatabaseHelper.delete(id); } + /// Register a conversation : ask the server to notify about updates to the + /// conversation through WebSocket + Future registerConversationEvents(int id) async { + if (_registeredConversations.containsKey(id)) + _registeredConversations[id]++; + else { + _registeredConversations[id] = 1; + await ws("\$main/register_conv", {"convID": id}); + } + } + + /// Un-register to conversation update events + Future unregisterConversationEvents(int id) async { + if (!_registeredConversations.containsKey(id)) return; + + _registeredConversations[id]--; + + if (_registeredConversations[id] <= 0) { + _registeredConversations.remove(id); + await ws("\$main/unregister_conv", {"convID": id}); + } + } + /// Turn an API response into a ConversationMessage object ConversationMessage _apiToConversationMessage({ @required int conversationID, diff --git a/lib/ui/screens/conversation_screen.dart b/lib/ui/screens/conversation_screen.dart index 67a51d8..11e83b5 100644 --- a/lib/ui/screens/conversation_screen.dart +++ b/lib/ui/screens/conversation_screen.dart @@ -7,6 +7,7 @@ import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/conversation_message.dart'; import 'package:comunic/models/new_conversation_message.dart'; import 'package:comunic/ui/tiles/conversation_message_tile.dart'; +import 'package:comunic/ui/widgets/safe_state.dart'; import 'package:comunic/ui/widgets/scroll_watcher.dart'; import 'package:comunic/utils/files_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; @@ -32,7 +33,7 @@ class ConversationScreen extends StatefulWidget { State createState() => _ConversationScreenState(); } -class _ConversationScreenState extends State { +class _ConversationScreenState extends SafeState { //Helpers final ConversationsHelper _conversationsHelper = ConversationsHelper(); final UsersHelper _usersHelper = UsersHelper(); @@ -44,27 +45,19 @@ class _ConversationScreenState extends State { bool _isMessageValid = false; bool _isSendingMessage = false; TextEditingController _textEditingController = TextEditingController(); - Timer _refreshTime; ScrollWatcher _scrollController; _OlderMessagesLevel _loadingOlderMessages = _OlderMessagesLevel.NONE; @override void initState() { super.initState(); - _scrollController = ScrollWatcher(onReachBottom: _loadOlderMessages); + _init(); } @override - void didChangeDependencies() { - super.didChangeDependencies(); - _initializeLoading(); - } - - @override - void deactivate() { - super.deactivate(); - - if (_refreshTime != null) _refreshTime.cancel(); + void dispose() { + super.dispose(); + _deallocate(); } void _setError(ErrorLevel err) => setState(() => _error = err); @@ -81,14 +74,20 @@ class _ConversationScreenState extends State { } /// Load the first conversations - Future _initializeLoading() async { + Future _init() async { + _scrollController = ScrollWatcher(onReachBottom: _loadOlderMessages); + + // Fetch latest messages await _loadMessages(false); await _loadMessages(true); - // Set a timer to regularly update conversation messages - if (_refreshTime == null || !_refreshTime.isActive) - _refreshTime = Timer.periodic( - Duration(milliseconds: 1500), (t) => _loadMessages(true)); + await _conversationsHelper + .registerConversationEvents(widget.conversationID); + } + + /// Free resources when this conversation widget is no longer required + void _deallocate() { + _conversationsHelper.unregisterConversationEvents(widget.conversationID); } /// Load a list of messages