Skip to content

Commit 98cab71

Browse files
committed
WIP model: Add Unreads model, for tracking unread-message counts
TODO: - improve tests: - seems like an issue when the test passes a Message object to the model, but the integrity of the test depends on the model not mutating it? could be a problem but I've found it makes certain things convenient - reducing repetitiveness? - several TODOs are scattered through the tests; can postpone most of those? - stopwatching For the "TODO assert sorted?" comments in initial_snapshot.dart, see: https://chat.zulip.org/#narrow/stream/412-api-documentation/topic/register.3A.20.60unread_message_ids.60.20sorted.3F/near/1647932 (before merging we should make sure the doc will guarantee sorting)
1 parent f4685a5 commit 98cab71

File tree

7 files changed

+1318
-7
lines changed

7 files changed

+1318
-7
lines changed

lib/api/model/initial_snapshot.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class UnreadMessagesSnapshot {
230230
final List<int> mentions;
231231
final bool oldUnreadsMissing;
232232

233-
UnreadMessagesSnapshot({
233+
const UnreadMessagesSnapshot({
234234
required this.count,
235235
required this.dms,
236236
required this.streams,
@@ -259,7 +259,7 @@ class UnreadDmSnapshot {
259259

260260
UnreadDmSnapshot({
261261
required this.otherUserId,
262-
required this.unreadMessageIds,
262+
required this.unreadMessageIds, // TODO assert sorted?
263263
});
264264

265265
factory UnreadDmSnapshot.fromJson(Map<String, dynamic> json) =>
@@ -278,7 +278,7 @@ class UnreadStreamSnapshot {
278278
UnreadStreamSnapshot({
279279
required this.topic,
280280
required this.streamId,
281-
required this.unreadMessageIds,
281+
required this.unreadMessageIds, // TODO assert sorted?
282282
});
283283

284284
factory UnreadStreamSnapshot.fromJson(Map<String, dynamic> json) =>
@@ -295,7 +295,7 @@ class UnreadHuddleSnapshot {
295295

296296
UnreadHuddleSnapshot({
297297
required this.userIdsString,
298-
required this.unreadMessageIds,
298+
required this.unreadMessageIds, // TODO assert sorted?
299299
});
300300

301301
factory UnreadHuddleSnapshot.fromJson(Map<String, dynamic> json) =>

lib/model/narrow.dart

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
import '../api/model/events.dart';
23
import '../api/model/initial_snapshot.dart';
34
import '../api/model/model.dart';
45
import '../api/model/narrow.dart';
@@ -168,6 +169,23 @@ class DmNarrow extends Narrow implements SendableNarrow {
168169
);
169170
}
170171

172+
/// A [DmNarrow] from an [UnreadHuddleSnapshot].
173+
factory DmNarrow.ofUnreadHuddleSnapshot(UnreadHuddleSnapshot snapshot, {required int selfUserId}) {
174+
final userIds = snapshot.userIdsString.split(',').map((id) => int.parse(id));
175+
return DmNarrow(selfUserId: selfUserId,
176+
// (already sorted; see API doc)
177+
allRecipientIds: userIds.toList(growable: false));
178+
}
179+
180+
factory DmNarrow.ofUpdateMessageFlagsMessageDetail(
181+
UpdateMessageFlagsMessageDetail detail, {
182+
required int selfUserId,
183+
}) {
184+
assert(detail.type == MessageType.private);
185+
return DmNarrow(selfUserId: selfUserId,
186+
allRecipientIds: [...detail.userIds!, selfUserId]..sort());
187+
}
188+
171189
/// The user IDs of everyone in the conversation, sorted.
172190
///
173191
/// Each message in the conversation is sent by one of these users

lib/model/store.dart

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import 'autocomplete.dart';
1717
import 'database.dart';
1818
import 'message_list.dart';
1919
import 'recent_dm_conversations.dart';
20+
import 'unreads.dart';
2021

2122
export 'package:drift/drift.dart' show Value;
2223
export 'database.dart' show Account, AccountsCompanion;
@@ -154,6 +155,7 @@ class PerAccountStore extends ChangeNotifier {
154155
realmDefaultExternalAccounts = initialSnapshot.realmDefaultExternalAccounts,
155156
customProfileFields = _sortCustomProfileFields(initialSnapshot.customProfileFields),
156157
userSettings = initialSnapshot.userSettings,
158+
unreads = Unreads(initial: initialSnapshot.unreadMsgs, selfUserId: account.userId),
157159
users = Map.fromEntries(
158160
initialSnapshot.realmUsers
159161
.followedBy(initialSnapshot.realmNonActiveUsers)
@@ -179,6 +181,7 @@ class PerAccountStore extends ChangeNotifier {
179181

180182
// Data attached to the self-account on the realm.
181183
final UserSettings? userSettings; // TODO(server-5)
184+
final Unreads unreads;
182185

183186
// Users and data about them.
184187
final Map<int, User> users;
@@ -301,19 +304,23 @@ class PerAccountStore extends ChangeNotifier {
301304
for (final view in _messageListViews) {
302305
view.maybeAddMessage(event.message);
303306
}
307+
unreads.handleMessageEvent(event);
304308
} else if (event is UpdateMessageEvent) {
305309
assert(debugLog("server event: update_message ${event.messageId}"));
306310
for (final view in _messageListViews) {
307311
view.maybeUpdateMessage(event);
308312
}
313+
unreads.handleUpdateMessageEvent(event);
309314
} else if (event is DeleteMessageEvent) {
310315
assert(debugLog("server event: delete_message ${event.messageIds}"));
311-
// TODO handle
316+
// TODO handle in message lists
317+
unreads.handleDeleteMessageEvent(event);
312318
} else if (event is UpdateMessageFlagsEvent) {
313319
assert(debugLog("server event: update_message_flags/${event.op} ${event.flag.toJson()}"));
314320
for (final view in _messageListViews) {
315321
view.maybeUpdateMessageFlags(event);
316322
}
323+
unreads.handleUpdateMessageFlagsEvent(event);
317324
} else if (event is ReactionEvent) {
318325
assert(debugLog("server event: reaction/${event.op}"));
319326
for (final view in _messageListViews) {

0 commit comments

Comments
 (0)