optimized avatar and linkify performance, refined navigation to preserve popups, implemented read marker caching, and added file size limits for saving, minor timetable details changes

This commit is contained in:
2026-05-10 16:40:39 +02:00
parent 1458d8ce49
commit a0bc46f522
12 changed files with 234 additions and 64 deletions
+18 -3
View File
@@ -36,6 +36,12 @@ class ChatBloc
/// popping a stacked chat.
bool _chatViewActive = false;
/// True only while a ChatView is actually mounted and tracking its room.
/// Read by the notification controller to decide whether an incoming push
/// belongs to the chat the user is currently looking at — `currentToken`
/// alone would yield false-positives for the last opened chat.
bool get hasOpenChat => _chatViewActive;
DateTime _lastTokenSet = DateTime.fromMillisecondsSinceEpoch(0);
ChatBloc({ChatListBloc? chatListBloc}) : _chatListBloc = chatListBloc {
@@ -166,10 +172,19 @@ class ChatBloc
},
onNetworkData: (data) {
// Server-side mark runs unconditionally with the freshly-fetched
// maxId. Skipping it on stillCurrent==false would leave the
// server cursor wherever a quick navigation away left it.
// maxId — skipping it on stillCurrent==false would leave the
// server cursor wherever a quick navigation away left it. The
// cache check below avoids a redundant POST when the long-poll
// (setReadMarker=on) or a previous open already moved the cursor
// to this exact id; without it every chat-open did one extra
// round-trip even when there was nothing to mark.
final maxId = _maxMessageId(data);
if (maxId > 0) unawaited(sendServerReadMarker(token, maxId));
if (maxId > 0) {
final cached = _chatListBloc?.lastReadMessageFor(token);
if (cached == null || cached < maxId) {
unawaited(sendServerReadMarker(token, maxId));
}
}
if (!stillCurrent()) return;
_applyChatResponse(data);
if (maxId > 0) _chatListBloc?.markRoomAsRead(token, maxId);