From 9d0c242a10aef77820c989d961a8ef6c37a17e2e Mon Sep 17 00:00:00 2001 From: Mo2Hefny Date: Mon, 23 Dec 2024 18:29:53 +0200 Subject: [PATCH] perf: fix reloading of chat screen with draft --- .../chat/view/screens/chat_screen.dart | 28 +++++-------------- .../chat/view_model/chatting_controller.dart | 24 ++++++++++------ 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/lib/features/chat/view/screens/chat_screen.dart b/lib/features/chat/view/screens/chat_screen.dart index 6c0806e..0bd893c 100644 --- a/lib/features/chat/view/screens/chat_screen.dart +++ b/lib/features/chat/view/screens/chat_screen.dart @@ -68,8 +68,6 @@ class _ChatScreen extends ConsumerState List pinnedMessages = []; int indexInPinnedMessage = 0; - late Timer _draftTimer; - late ChatModel chatModel; bool isSearching = false; bool isShowAsList = false; @@ -79,7 +77,6 @@ class _ChatScreen extends ConsumerState bool isTextEmpty = true; bool showMuteOptions = false; bool isAllowedToSend = true; - String _previousDraft = ""; // ignore: prefer_final_fields int _currentMatch = 1; @@ -89,17 +86,14 @@ class _ChatScreen extends ConsumerState Map>> _messageMatches = {}; List _messageIndices = []; - late DateTime _lastTypeTimer; - late ChatType type; @override void initState() { super.initState(); - _lastTypeTimer = DateTime.now(); _messageController.text = widget.chatModel?.draft ?? ""; _messageController.addListener(() { - _lastTypeTimer = DateTime.now(); + _updateDraft(false); }); WidgetsBinding.instance.addObserver(this); @@ -111,12 +105,6 @@ class _ChatScreen extends ConsumerState _chosenAnimation = utils.getRandomLottieAnimation(); // Initialize the AudioRecorderService _audioRecorderService = AudioRecorderService(updateUI: setState); - _draftTimer = Timer.periodic(const Duration(milliseconds: 50), (timer) { - if (_previousDraft != _messageController.text) { - _updateDraft(); - _previousDraft = _messageController.text; - } - }); } @override @@ -126,17 +114,16 @@ class _ChatScreen extends ConsumerState _audioRecorderService.dispose(); SystemChannels.textInput.invokeMethod('TextInput.hide'); WidgetsBinding.instance.removeObserver(this); // Remove the observer + super.dispose(); } - void _updateDraft() async { - // TODO : server return 500 status code every time try to fix it ASAP + void _updateDraft(bool saveLocal) { if (!mounted) return; final currentDraft = _messageController.text; ref .read(chattingControllerProvider) - .updateDraft(chatModel, currentDraft); - return; + .updateDraft(chatModel, currentDraft, saveLocal); } void _updateChatMessages(List messages) async { @@ -294,7 +281,7 @@ class _ChatScreen extends ConsumerState parentMessage: replyMessage?.id, ); _messageController.clear(); - _updateDraft(); + _updateDraft(true); ref.read(chattingControllerProvider).sendMsg( content: newMessage.content!, msgType: newMessage.messageType, @@ -435,8 +422,7 @@ class _ChatScreen extends ConsumerState : "$membersNumber subscribers${membersNumber > 1 ? "s" : ""}"; _isMuted = chatModel.isMuted; - if (chatModel.draft != null && chatModel.draft!.isNotEmpty && - _lastTypeTimer.isBefore(DateTime.now().subtract(const Duration(seconds: 1)))) { + if (chatModel.draft != null && chatModel.draft!.isNotEmpty) { _messageController.text = chatModel.draft ?? ''; } chatContent = _generateChatContentWithDateLabels(messages); @@ -469,7 +455,7 @@ class _ChatScreen extends ConsumerState _messageMatches.clear(); }); } else { - _updateDraft(); + _updateDraft(true); context.pop(); } }, diff --git a/lib/features/chat/view_model/chatting_controller.dart b/lib/features/chat/view_model/chatting_controller.dart index 0ac9d69..54f86af 100644 --- a/lib/features/chat/view_model/chatting_controller.dart +++ b/lib/features/chat/view_model/chatting_controller.dart @@ -51,6 +51,7 @@ class ChattingController { late final EventHandler _eventHandler; final ChatRemoteRepository _remoteRepository; final ChatLocalRepository _localRepository; + String? _lastOpenedChatId; final Ref _ref; List> unreadMsgsQuery = []; bool isProcessingUnreadMsgs = false; @@ -665,7 +666,8 @@ class ChattingController { _localRepository.setEventQueue(queue, _ref.read(userProvider)!.id!); } - void updateDraft(ChatModel chatModel, String draft) { + void updateDraft(ChatModel chatModel, String draft, bool updateLocal) { + _lastOpenedChatId = chatModel.id; debugPrint('!!! updateDraft called'); final String? chatID = chatModel.id; final String userId = _ref.read(userProvider)!.id!; @@ -686,6 +688,7 @@ class ChattingController { } if (USE_MOCK_DATA) { + _lastOpenedChatId = null; final chats = _localRepository.getChats(userId); final chat = chats.firstWhere((element) => element.id == chatID); final updatedChat = chat.copyWith(draft: draft); @@ -702,17 +705,20 @@ class ChattingController { 'content': draft, }, controller: this, msgId: '', chatId: chatID); _eventHandler.addEvent(msgEvent); - final chats = _localRepository.getChats(userId); - final chat = chats.firstWhere((element) => element.id == chatID); - final updatedChat = chat.copyWith(draft: draft); - final updatedChats = - chats.map((e) => e.id == chatID ? updatedChat : e).toList(); - _localRepository.setChats(updatedChats, userId); - _ref.read(chatsViewModelProvider.notifier).setChats(updatedChats); - debugPrint('!!! draft updated remotely and locally: ${updatedChat.draft}'); + if (updateLocal) { + _lastOpenedChatId = null; + final chats = _localRepository.getChats(userId); + final chat = chats.firstWhere((element) => element.id == chatID); + final updatedChat = chat.copyWith(draft: draft); + final updatedChats = + chats.map((e) => e.id == chatID ? updatedChat : e).toList(); + _localRepository.setChats(updatedChats, userId); + _ref.read(chatsViewModelProvider.notifier).setChats(updatedChats); + } } void receiveUpdatedDraft(String chatID, String draft) { + if (chatID == _lastOpenedChatId) return; final String userId = _ref.read(userProvider)!.id!; final chats = _localRepository.getChats(userId); final chat = chats.firstWhere((element) => element.id == chatID);