diff --git a/lib/models/contact.dart b/lib/models/contact.dart index c0d3f792..ddccaa55 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -42,7 +42,7 @@ class ContactInfoState extends ChangeNotifier { late int _totalMessages = 0; late DateTime _lastMessageTime; late Map> keys; - int _newMarker = 0; + int _newMarkerMsgId = -1; DateTime _newMarkerClearAt = DateTime.now(); late MessageCache messageCache; @@ -148,35 +148,22 @@ class ContactInfoState extends ChangeNotifier { int get unreadMessages => this._unreadMessages; set unreadMessages(int newVal) { - // don't reset newMarker position when unreadMessages is being cleared - if (newVal > 0) { - this._newMarker = newVal; - } else { + if (newVal == 0) { + // conversation has been selected, start the countdown for the New Messager marker to be reset this._newMarkerClearAt = DateTime.now().add(const Duration(minutes: 2)); } this._unreadMessages = newVal; notifyListeners(); } - int get newMarker { + int get newMarkerMsgId { if (DateTime.now().isAfter(this._newMarkerClearAt)) { // perform heresy - this._newMarker = 0; + this._newMarkerMsgId = -1; // no need to notifyListeners() because presumably this getter is // being called from a renderer anyway } - return this._newMarker; - } - - // what's a getter that sometimes sets without a setter - // that sometimes doesn't set - set newMarker(int newVal) { - // only unreadMessages++ can set newMarker = 1; - // avoids drawing a marker when the convo is already open - if (newVal >= 1) { - this._newMarker = newVal; - notifyListeners(); - } + return this._newMarkerMsgId; } int get totalMessages => this._totalMessages; @@ -255,8 +242,9 @@ class ContactInfoState extends ChangeNotifier { void newMessage(int identifier, int messageID, DateTime timestamp, String senderHandle, String senderImage, bool isAuto, String data, String contenthash, bool selectedConversation) { if (!selectedConversation) { unreadMessages++; - } else { - newMarker++; + } + if (_newMarkerMsgId == -1) { + _newMarkerMsgId = messageID; } this._lastMessageTime = timestamp; diff --git a/lib/models/message.dart b/lib/models/message.dart index 89a380af..da2a9411 100644 --- a/lib/models/message.dart +++ b/lib/models/message.dart @@ -63,11 +63,7 @@ Message compileOverlay(MessageMetadata metadata, String messageData) { } abstract class CacheHandler { - //Future lookup(MessageCache cache); - //Future fetch(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache); - Future get(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache); - //void add(MessageCache cache, MessageInfo messageInfo); } class ByIndex implements CacheHandler { @@ -81,7 +77,9 @@ class ByIndex implements CacheHandler { } Future get( Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) async { + // observationally flutter future builder seemed to be reaching for 20-40 message on pane load, so we start trying to load up to that many messages in one request var chunk = 40; + // check that we aren't asking for messages beyond stored messages if (chunk > cache.storageMessageCount - index) { chunk = cache.storageMessageCount - index; } @@ -91,7 +89,7 @@ class ByIndex implements CacheHandler { } cache.lockIndexs(index, index+chunk); var msgs = await cwtch.GetMessages(profileOnion, conversationIdentifier, index, chunk); - int i = 0; // declared here for use in finally to unlock + int i = 0; // i used to loop through returned messages. if doesn't reach the requested count, we will use it in the finally stanza to error out the remaining asked for messages in the cache try { List messagesWrapper = jsonDecode(msgs); @@ -103,7 +101,6 @@ class ByIndex implements CacheHandler { } catch (e, stacktrace) { EnvironmentConfig.debugLog("Error: Getting indexed messages $index to ${index+chunk} failed parsing: " + e.toString() + " " + stacktrace.toString()); } finally { - // todo unlock remaining and mark malformed if (i != chunk) { cache.malformIndexes(index+i, index+chunk); } diff --git a/lib/models/messagecache.dart b/lib/models/messagecache.dart index d45b7036..51c61be2 100644 --- a/lib/models/messagecache.dart +++ b/lib/models/messagecache.dart @@ -113,6 +113,9 @@ class MessageCache extends ChangeNotifier { notifyListeners(); } + // inserts place holder values into the index cache that will block on .get() until .finishLoad() is called on them with message contents + // or .failLoad() is called on them to mark them malformed + // this prevents successive ui message build requests from triggering multiple GetMesssage requests to the backend, as the first one locks a block of messages and the rest wait on that void lockIndexs(int start, int end) { for(var i = start; i < end; i++) { this.cacheByIndex.insert(i, LocalIndexMessage(null, isLoading: true)); @@ -132,9 +135,7 @@ class MessageCache extends ChangeNotifier { } else { this.cacheByIndex.insert(index, LocalIndexMessage(messageInfo.metadata.messageID)); } - if (messageInfo.metadata.contenthash != "") { - this.cacheByHash[messageInfo.metadata.contenthash] = messageInfo.metadata.messageID; - } + this.cacheByHash[messageInfo.metadata.contenthash] = messageInfo.metadata.messageID; notifyListeners(); } diff --git a/lib/widgets/messagerow.dart b/lib/widgets/messagerow.dart index 14cf5393..710109e1 100644 --- a/lib/widgets/messagerow.dart +++ b/lib/widgets/messagerow.dart @@ -223,13 +223,9 @@ class MessageRowState extends State with SingleTickerProviderStateMi mainAxisAlignment: MainAxisAlignment.center, children: widgetRow, ))))); - // TODO calculate newMark ID in CIS so we dont have to get here - var mark = Provider.of(context).newMarker; - //var mi = await Provider.of(context).messageCache.getByIndex(mark - 1); - var markMatch = false; //mi?.metadata.messageID == Provider.of(context).messageID; - if (mark > 0 && - Provider.of(context).messageCache.indexedLength > mark && markMatch) - { + + var markMsgId = Provider.of(context).newMarkerMsgId; + if (markMsgId == Provider.of(context).messageID) { return Column(crossAxisAlignment: fromMe ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [Align(alignment: Alignment.center, child: _bubbleNew()), mr]); } else { return mr;