diff --git a/lib/src/app.dart b/lib/src/app.dart index aeb9022..d69291c 100644 --- a/lib/src/app.dart +++ b/lib/src/app.dart @@ -158,12 +158,12 @@ class _MyAppState extends State with WidgetsBindingObserver { } Future _stopService() async { - FlutterForegroundTask.sendDataToTask(""); - await FlutterForegroundTask.stopService(); if (context.mounted) { - context.read().init(); + context.read().init(afterPaused: true); context.read().update(); } + FlutterForegroundTask.sendDataToTask(""); + await FlutterForegroundTask.stopService(); if (!apiProvider.isAuthenticated) { apiProvider.connect(); } diff --git a/lib/src/providers/messages_change_provider.dart b/lib/src/providers/messages_change_provider.dart index b89e16b..fcc8661 100644 --- a/lib/src/providers/messages_change_provider.dart +++ b/lib/src/providers/messages_change_provider.dart @@ -7,10 +7,13 @@ import 'package:twonly/src/utils/misc.dart'; /// for every contact. class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin { final Map _lastMessage = {}; + final Map> _allMessagesFromUser = + >{}; final Map _changeCounter = {}; final Map _flamesCounter = {}; Map get lastMessage => _lastMessage; + Map> get allMessagesFromUser => _allMessagesFromUser; Map get changeCounter => _changeCounter; Map get flamesCounter => _flamesCounter; @@ -20,15 +23,20 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin { if (last != null) { _lastMessage[last.otherUserId] = last; } - if (!changeCounter.containsKey(targetUserId)) { - changeCounter[targetUserId] = 0; - } - changeCounter[targetUserId] = changeCounter[targetUserId]! + 1; flamesCounter[targetUserId] = await getFlamesForOtherUser(targetUserId); notifyListeners(); + + loadMessagesForUser(targetUserId, force: true); + } + + Future loadMessagesForUser(int targetUserId, {bool force = false}) async { + if (!force && _allMessagesFromUser[targetUserId] != null) return; + _allMessagesFromUser[targetUserId] = + await DbMessages.getAllMessagesForUser(targetUserId); + notifyListeners(); } - void init() async { + void init({bool afterPaused = false}) async { // load everything from the database List allContacts = await DbContacts.getUsers(); for (Contact contact in allContacts) { @@ -41,5 +49,10 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin { await getFlamesForOtherUser(contact.userId.toInt()); } notifyListeners(); + if (afterPaused) { + for (int targetUserId in _allMessagesFromUser.keys) { + loadMessagesForUser(targetUserId, force: true); + } + } } } diff --git a/lib/src/views/chats/chat_item_details_view.dart b/lib/src/views/chats/chat_item_details_view.dart index 7abf2fd..71831cb 100644 --- a/lib/src/views/chats/chat_item_details_view.dart +++ b/lib/src/views/chats/chat_item_details_view.dart @@ -129,64 +129,25 @@ class ChatItemDetailsView extends StatefulWidget { } class _ChatItemDetailsViewState extends State { - List _messages = []; int lastChangeCounter = 0; final TextEditingController newMessageController = TextEditingController(); HashSet alreadyReportedOpened = HashSet(); - int sendTextMessages = 0; late Contact user; @override void initState() { super.initState(); user = widget.user; - _loadAsync(updateOpenStatus: true); - } - - Future _loadAsync({bool updateOpenStatus = false}) async { - // if (_messages.isEmpty || updateOpenStatus) { - if (sendTextMessages <= 0) { - _messages = await DbMessages.getAllMessagesForUser(user.userId.toInt()); - } else { - sendTextMessages--; - // will not update older message states like when they now downloaded... - int lastMessageId = _messages.first.messageId; - List toAppend = - await DbMessages.getAllMessagesForUserWithHigherMessageId( - user.userId.toInt(), lastMessageId); - _messages.insertAll(0, toAppend); - } - - if (updateOpenStatus) { - _messages.where((x) => x.messageOpenedAt == null).forEach((message) { - if (message.messageOtherId != null && - message.messageContent is TextMessageContent) { - if (!alreadyReportedOpened.contains(message.messageOtherId!)) { - userOpenedOtherMessage( - message.otherUserId, message.messageOtherId!); - flutterLocalNotificationsPlugin.cancel(message.messageId); - alreadyReportedOpened.add(message.messageOtherId!); - } - } - }); - } - try { - if (context.mounted) { - setState(() {}); - } - } catch (e) { - // state should be disposed - return; - } + context + .read() + .loadMessagesForUser(user.userId.toInt()); } Future _sendMessage() async { - sendTextMessages++; - String text = newMessageController.text; - if (text == "") return; + if (newMessageController.text == "") return; + setState(() {}); await sendTextMessage(user.userId, newMessageController.text); newMessageController.clear(); - setState(() {}); } @override @@ -195,14 +156,27 @@ class _ChatItemDetailsViewState extends State { .watch() .allContacts .firstWhere((c) => c.userId == widget.user.userId); - final changeCounter = context.watch().changeCounter; - if (changeCounter.containsKey(user.userId.toInt())) { - if (changeCounter[user.userId.toInt()] != lastChangeCounter) { - _loadAsync(updateOpenStatus: true); - lastChangeCounter = changeCounter[user.userId.toInt()]!; - setState(() {}); + + List messages = context + .watch() + .allMessagesFromUser[user.userId.toInt()] ?? + []; + + messages.where((x) => x.messageOpenedAt == null).forEach((message) { + if (message.messageOtherId != null && + message.messageContent is TextMessageContent) { + if (!alreadyReportedOpened.contains(message.messageOtherId!)) { + setState(() { + // so the _loadAsync will not be called again by this update + lastChangeCounter++; + }); + userOpenedOtherMessage(message.otherUserId, message.messageOtherId!); + flutterLocalNotificationsPlugin.cancel(message.messageId); + alreadyReportedOpened.add(message.messageOtherId!); + } } - } + }); + return Scaffold( appBar: AppBar( title: GestureDetector( @@ -223,7 +197,7 @@ class _ChatItemDetailsViewState extends State { color: Colors.transparent, child: Row( children: [ - Text(user.displayName), + Text(user.userId.toString()), SizedBox(width: 10), VerifiedShield(user), ], @@ -238,27 +212,27 @@ class _ChatItemDetailsViewState extends State { children: [ Expanded( child: ListView.builder( - itemCount: _messages.length, // Number of items in the list + itemCount: messages.length, // Number of items in the list reverse: true, itemBuilder: (context, i) { bool lastMessageFromSameUser = false; if (i > 0) { lastMessageFromSameUser = - (_messages[i - 1].messageOtherId == null && - _messages[i].messageOtherId == null) || - (_messages[i - 1].messageOtherId != null && - _messages[i].messageOtherId != null); + (messages[i - 1].messageOtherId == null && + messages[i].messageOtherId == null) || + (messages[i - 1].messageOtherId != null && + messages[i].messageOtherId != null); } - if (_messages[i].messageOpenedAt != null) { + if (messages[i].messageOpenedAt != null) { if ((DateTime.now()) - .difference(_messages[i].messageOpenedAt!) + .difference(messages[i].messageOpenedAt!) .inHours >= 24) { return Container(); } } return ChatListEntry( - _messages[i], + messages[i], user, lastMessageFromSameUser, );