Skip to content

Commit 65d9b62

Browse files
committed
events: Sort recipientIds for TypingEvent.
DmNarrow expects them to be sorted, so doing it early during deserialization helps. Because of this TypingStatus no longer needs to modify the recipientIds list. Signed-off-by: Zixuan James Li <[email protected]>
1 parent 07ccb94 commit 65d9b62

File tree

4 files changed

+13
-21
lines changed

4 files changed

+13
-21
lines changed

lib/api/model/events.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:json_annotation/json_annotation.dart';
22

3+
import '../../model/algorithms.dart';
34
import 'json.dart';
45
import 'model.dart';
56

@@ -900,16 +901,16 @@ class TypingEvent extends Event {
900901
required this.recipientIds,
901902
required this.streamId,
902903
required this.topic,
903-
});
904+
}) : assert(isSortedWithoutDuplicates(recipientIds ?? []));
904905

905906
static Object? _readSenderId(Map<Object?, Object?> json, String key) {
906907
return (json['sender'] as Map<String, dynamic>)['user_id'];
907908
}
908909

909910
static List<int>? _recipientIdsFromJson(Object? json) {
910911
if (json == null) return null;
911-
return (json as List<Object?>).map(
912-
(item) => (item as Map<String, Object?>)['user_id'] as int).toList();
912+
return (json as Iterable<Object?>).map(
913+
(item) => (item as Map<String, Object?>)['user_id'] as int).toList()..sort();
913914
}
914915

915916
factory TypingEvent.fromJson(Map<String, dynamic> json) {

lib/model/typing_status.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:async';
33
import 'package:flutter/foundation.dart';
44

55
import '../api/model/events.dart';
6+
import '../log.dart';
67
import 'narrow.dart';
78

89
/// The model for tracking the typing status organized by narrows.
@@ -64,7 +65,7 @@ class TypingStatus extends ChangeNotifier {
6465
void handleTypingEvent(TypingEvent event) {
6566
SendableNarrow narrow = switch (event.messageType) {
6667
MessageType.direct => DmNarrow(
67-
allRecipientIds: event.recipientIds!..sort(), selfUserId: selfUserId),
68+
allRecipientIds: event.recipientIds!, selfUserId: selfUserId),
6869
MessageType.stream => TopicNarrow(event.streamId!, event.topic!),
6970
};
7071

test/api/model/events_test.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,12 @@ void main() {
241241
check(() => TypingEvent.fromJson({
242242
...baseJson, 'message_type': 'stream', 'stream_id': 123})).throws<void>();
243243
});
244+
245+
test('direct type sort recipient ids', () {
246+
check(TypingEvent.fromJson({
247+
...directMessageJson,
248+
'recipients': [4, 10, 8, 2, 1].map((e) => {'user_id': e, 'email': '$e@example.com'}),
249+
})).recipientIds.isNotNull().deepEquals([1, 2, 4, 8, 10]);
250+
});
244251
});
245252
}

test/model/typing_status_test.dart

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,6 @@ void main() {
9797
checkTypists({groupNarrow: [eg.otherUser, eg.thirdUser]});
9898
checkNotifiedOnce();
9999
});
100-
101-
test('sort dm recipients', () {
102-
prepareModel(selfUserId: 5);
103-
final recipientIds = [5, 4, 10, 8, 2, 1];
104-
105-
final eventUnsorted = TypingEvent(id: 1, op: TypingOp.start,
106-
senderId: 1,
107-
messageType: MessageType.direct,
108-
recipientIds: recipientIds,
109-
streamId: null, topic: null);
110-
// DmNarrow's constructor expects the recipient IDs to be sorted,
111-
// and [model.handleTypingEvent] should handle that.
112-
model.handleTypingEvent(eventUnsorted);
113-
check(model.typistIdsInNarrow(
114-
DmNarrow(allRecipientIds: recipientIds..sort(), selfUserId: 5),
115-
)).single.equals(1);
116-
});
117100
});
118101

119102
group('handle typing stop events', () {

0 commit comments

Comments
 (0)