Skip to content

Commit c7a5cbc

Browse files
sm-sayedichrisbobbe
authored andcommitted
user: Add UserStore.mutedUsers with helper methods, updating with events
1 parent d822c63 commit c7a5cbc

File tree

5 files changed

+76
-3
lines changed

5 files changed

+76
-3
lines changed

lib/model/store.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,13 @@ class PerAccountStore extends PerAccountStoreBase with ChangeNotifier, EmojiStor
645645
@override
646646
Iterable<User> get allUsers => _users.allUsers;
647647

648+
@override
649+
Set<int> get mutedUsers => _users.mutedUsers;
650+
651+
@override
652+
bool isUserMuted(int id, {Set<int>? mutedUsers}) =>
653+
_users.isUserMuted(id, mutedUsers: mutedUsers);
654+
648655
final UserStoreImpl _users;
649656

650657
final TypingStatus typingStatus;
@@ -950,8 +957,9 @@ class PerAccountStore extends PerAccountStoreBase with ChangeNotifier, EmojiStor
950957
_messages.handleReactionEvent(event);
951958

952959
case MutedUsersEvent():
953-
// TODO handle
954-
break;
960+
assert(debugLog("server event: muted_users"));
961+
_users.handleMutedUsersEvent(event);
962+
notifyListeners();
955963

956964
case UnexpectedEvent():
957965
assert(debugLog("server event: ${jsonEncode(event.toJson())}")); // TODO log better

lib/model/user.dart

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'package:flutter/foundation.dart';
2+
13
import '../api/model/events.dart';
24
import '../api/model/initial_snapshot.dart';
35
import '../api/model/model.dart';
@@ -66,6 +68,16 @@ mixin UserStore on PerAccountStoreBase {
6668
return getUser(message.senderId)?.fullName
6769
?? message.senderFullName;
6870
}
71+
72+
/// Ids of all the users muted by [selfUser].
73+
@visibleForTesting
74+
Set<int> get mutedUsers;
75+
76+
/// Whether the user with the given [id] is muted by [selfUser].
77+
///
78+
/// By default, looks for the user id in [UserStore.mutedUsers] unless
79+
/// [mutedUsers] is non-null, in which case looks in the latter.
80+
bool isUserMuted(int id, {Set<int>? mutedUsers});
6981
}
7082

7183
/// The implementation of [UserStore] that does the work.
@@ -81,7 +93,8 @@ class UserStoreImpl extends PerAccountStoreBase with UserStore {
8193
initialSnapshot.realmUsers
8294
.followedBy(initialSnapshot.realmNonActiveUsers)
8395
.followedBy(initialSnapshot.crossRealmBots)
84-
.map((user) => MapEntry(user.userId, user)));
96+
.map((user) => MapEntry(user.userId, user))),
97+
mutedUsers = _toUserIds(initialSnapshot.mutedUsers);
8598

8699
final Map<int, User> _users;
87100

@@ -91,6 +104,18 @@ class UserStoreImpl extends PerAccountStoreBase with UserStore {
91104
@override
92105
Iterable<User> get allUsers => _users.values;
93106

107+
@override
108+
final Set<int> mutedUsers;
109+
110+
@override
111+
bool isUserMuted(int id, {Set<int>? mutedUsers}) {
112+
return (mutedUsers ?? this.mutedUsers).contains(id);
113+
}
114+
115+
static Set<int> _toUserIds(List<MutedUserItem> mutedUserItems) {
116+
return Set.from(mutedUserItems.map((item) => item.id));
117+
}
118+
94119
void handleRealmUserEvent(RealmUserEvent event) {
95120
switch (event) {
96121
case RealmUserAddEvent():
@@ -129,4 +154,9 @@ class UserStoreImpl extends PerAccountStoreBase with UserStore {
129154
}
130155
}
131156
}
157+
158+
void handleMutedUsersEvent(MutedUsersEvent event) {
159+
mutedUsers.clear();
160+
mutedUsers.addAll(_toUserIds(event.mutedUsers));
161+
}
132162
}

test/model/store_checks.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ extension PerAccountStoreChecks on Subject<PerAccountStore> {
5757
Subject<int> get selfUserId => has((x) => x.selfUserId, 'selfUserId');
5858
Subject<UserSettings?> get userSettings => has((x) => x.userSettings, 'userSettings');
5959
Subject<Map<int, SavedSnippet>> get savedSnippets => has((x) => x.savedSnippets, 'savedSnippets');
60+
Subject<Set<int>> get mutedUsers => has((x) => x.mutedUsers, 'mutedUsers');
6061
Subject<Map<int, ZulipStream>> get streams => has((x) => x.streams, 'streams');
6162
Subject<Map<String, ZulipStream>> get streamsByName => has((x) => x.streamsByName, 'streamsByName');
6263
Subject<Map<int, Subscription>> get subscriptions => has((x) => x.subscriptions, 'subscriptions');

test/model/test_store.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:collection/collection.dart';
12
import 'package:zulip/api/model/events.dart';
23
import 'package:zulip/api/model/initial_snapshot.dart';
34
import 'package:zulip/api/model/model.dart';
@@ -267,6 +268,21 @@ extension PerAccountStoreTestExtension on PerAccountStore {
267268
}
268269
}
269270

271+
Future<void> muteUser(int id) async {
272+
await handleEvent(eg.mutedUsersEvent([...mutedUsers, id]));
273+
}
274+
275+
Future<void> muteUsers(List<int> ids) async {
276+
for (final id in ids) {
277+
await muteUser(id);
278+
}
279+
}
280+
281+
Future<void> unmuteUser(int id) async {
282+
await handleEvent(eg.mutedUsersEvent(
283+
mutedUsers.whereNot((userId) => userId == id).toList()));
284+
}
285+
270286
Future<void> addStream(ZulipStream stream) async {
271287
await addStreams([stream]);
272288
}

test/model/user_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:zulip/api/model/model.dart';
55

66
import '../api/model/model_checks.dart';
77
import '../example_data.dart' as eg;
8+
import 'store_checks.dart';
89
import 'test_store.dart';
910

1011
void main() {
@@ -79,4 +80,21 @@ void main() {
7980
check(getUser()).deliveryEmail.equals('[email protected]');
8081
});
8182
});
83+
84+
testWidgets('MutedUsersEvent', (tester) async {
85+
final user1 = eg.user(userId: 1);
86+
final user2 = eg.user(userId: 2);
87+
final user3 = eg.user(userId: 3);
88+
89+
final store = eg.store(initialSnapshot: eg.initialSnapshot(
90+
realmUsers: [user1, user2, user3],
91+
mutedUsers: [MutedUserItem(id: 2), MutedUserItem(id: 1)]));
92+
check(store).mutedUsers.deepEquals({2, 1});
93+
94+
await store.handleEvent(eg.mutedUsersEvent([2, 1, 3]));
95+
check(store).mutedUsers.deepEquals({2, 1, 3});
96+
97+
await store.handleEvent(eg.mutedUsersEvent([2, 3]));
98+
check(store).mutedUsers.deepEquals({2, 3});
99+
});
82100
}

0 commit comments

Comments
 (0)