Skip to content

Commit

Permalink
unreads: Add handleAllMessagesReadSuccess method, to be used soon
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbobbe committed Feb 12, 2024
1 parent c6508f0 commit 763995b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
36 changes: 35 additions & 1 deletion lib/model/unreads.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class Unreads extends ChangeNotifier {
/// Whether the model is missing data on old unread messages.
///
/// Initialized to the value of [UnreadMessagesSnapshot.oldUnreadsMissing].
/// Is set to false when the user clears out all unreads at once.
/// Is set to false when the user clears out all unreads.
bool oldUnreadsMissing;

final int selfUserId;
Expand Down Expand Up @@ -390,6 +390,40 @@ class Unreads extends ChangeNotifier {
notifyListeners();
}

/// To be called on success of a mark-all-as-read task in the modern protocol.
///
/// When the user successfully marks all messages as read,
/// there can't possibly be ancient unreads we don't know about.
/// So this updates [oldUnreadsMissing] to false and calls [notifyListeners].
///
/// When we use POST /messages/flags/narrow (FL 155+) for mark-all-as-read,
/// we don't expect to get a mark-as-read event with `all: true`,
/// even on completion of the last batch of unreads.
/// If we did get an event with `all: true` (as we do in the legacy mark-all-
/// as-read protocol), this would be handled naturally, in
/// [handleUpdateMessageFlagsEvent].
///
/// Discussion:
/// <https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/flutter.3A.20Mark-as-read/near/1680275>
// TODO(server-6) Delete mentions of legacy protocol.
void handleAllMessagesReadSuccess() {
oldUnreadsMissing = false;

// Best not to actually clear any unreads out of the model.
// That'll be handled naturally when the event comes in, with a list of which
// messages were marked as read. When a mark-all-as-read task is complete,
// I don't think the server will always have zero unreads in its state.
// For example, I assume a new unread message could arrive while the work is
// in progress, and not get caught and marked as read. We should faithfully
// match that state. (This point seems especially relevant when the
// mark-as-read work is done in batches.)
//
// Even considering races like that, it does seem basically impossible for
// `oldUnreadsMissing: false` to be the wrong state at this point.

notifyListeners();
}

// TODO use efficient lookups
bool _slowIsPresentInStreams(int messageId) {
return streams.values.any(
Expand Down
14 changes: 14 additions & 0 deletions test/model/unreads_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -985,4 +985,18 @@ void main() {
});
});
});

group('handleAllMessagesReadSuccess', () {
prepare();
fillWithMessages([]);

// We didn't fill the model with 50k unreads, so this is questionably
// realistic… but the 50k cap isn't actually API-guaranteed, and this is
// plausibly realistic for a hypothetical server that decides based on
// message age rather than the 50k cap.
model.oldUnreadsMissing = true;
model.handleAllMessagesReadSuccess();
checkNotifiedOnce();
check(model).oldUnreadsMissing.isFalse();
});
}

0 comments on commit 763995b

Please sign in to comment.