Skip to content

Commit 0d91cac

Browse files
committed
msglist: Exclude DMs with muted users from applicable narrows
Direct messages of those conversations are excluded where all the recipients are muted. Currently the applicable narrows are: - CombinedFeedNarrow - MentionsNarrow - StarredMessagesNarrow In the future, this will apply to the ReactionsNarrow from the Web app too, once we have it.
1 parent 29705f0 commit 0d91cac

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

lib/model/message.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,10 @@ class MessageStoreImpl extends PerAccountStoreBase with MessageStore {
435435
// [Poll] is responsible for notifying the affected listeners.
436436
poll.handleSubmessageEvent(event);
437437
}
438+
439+
void handleMutedUsersEvent(MutedUsersEvent event) {
440+
for (final view in _messageListViews) {
441+
view.handleMutedUsersEvent(event);
442+
}
443+
}
438444
}

lib/model/message_list.dart

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'channel.dart';
1212
import 'content.dart';
1313
import 'narrow.dart';
1414
import 'store.dart';
15+
import 'user.dart';
1516

1617
/// The number of messages to fetch in each request.
1718
const kMessageListFetchBatchSize = 100; // TODO tune
@@ -431,7 +432,10 @@ class MessageListView with ChangeNotifier, _MessageSequence {
431432
return switch (message.conversation) {
432433
StreamConversation(:final streamId, :final topic) =>
433434
store.isTopicVisible(streamId, topic),
434-
DmConversation() => true,
435+
DmConversation(:final allRecipientIds) => () {
436+
return !store.allRecipientsMuted(DmNarrow(
437+
allRecipientIds: allRecipientIds, selfUserId: store.selfUserId));
438+
}(),
435439
};
436440

437441
case ChannelNarrow(:final streamId):
@@ -442,8 +446,15 @@ class MessageListView with ChangeNotifier, _MessageSequence {
442446

443447
case TopicNarrow():
444448
case DmNarrow():
449+
return true;
450+
445451
case MentionsNarrow():
452+
// case ReactionsNarrow(): // TODO
446453
case StarredMessagesNarrow():
454+
if (message.conversation case DmConversation(:final allRecipientIds)) {
455+
return !store.allRecipientsMuted(DmNarrow(
456+
allRecipientIds: allRecipientIds, selfUserId: store.selfUserId));
457+
}
447458
return true;
448459
}
449460
}
@@ -455,12 +466,13 @@ class MessageListView with ChangeNotifier, _MessageSequence {
455466
switch (narrow) {
456467
case CombinedFeedNarrow():
457468
case ChannelNarrow():
469+
case MentionsNarrow():
470+
// case ReactionsNarrow(): // TODO
471+
case StarredMessagesNarrow():
458472
return false;
459473

460474
case TopicNarrow():
461475
case DmNarrow():
462-
case MentionsNarrow():
463-
case StarredMessagesNarrow():
464476
return true;
465477
}
466478
}
@@ -484,6 +496,22 @@ class MessageListView with ChangeNotifier, _MessageSequence {
484496
}
485497
}
486498

499+
/// Whether this event could affect the result that [_messageVisible]
500+
/// would ever have returned for any possible message in this message list.
501+
MutenessEffect? _canAffectMuteness(MutedUsersEvent event) {
502+
switch(narrow) {
503+
case CombinedFeedNarrow():
504+
case MentionsNarrow():
505+
case StarredMessagesNarrow():
506+
return store.willChangeIfRecipientMuted(event);
507+
508+
case ChannelNarrow():
509+
case TopicNarrow():
510+
case DmNarrow():
511+
return null;
512+
}
513+
}
514+
487515
/// Fetch messages, starting from scratch.
488516
Future<void> fetchInitial() async {
489517
// TODO(#80): fetch from anchor firstUnread, instead of newest
@@ -662,6 +690,33 @@ class MessageListView with ChangeNotifier, _MessageSequence {
662690
notifyListeners();
663691
}
664692

693+
void handleMutedUsersEvent(MutedUsersEvent event) {
694+
switch(_canAffectMuteness(event)) {
695+
case MutenessEffect.added:
696+
if (_removeMessagesWhere((message) =>
697+
(message is DmMessage
698+
&& store.allRecipientsMuted(
699+
DmNarrow.ofMessage(message, selfUserId: store.selfUserId),
700+
mutedUsers: event.mutedUsers,
701+
)))) {
702+
notifyListeners();
703+
}
704+
705+
case MutenessEffect.removed:
706+
// TODO get the newly-unmuted messages from the message store
707+
// For now, we simplify the task by just refetching this message list
708+
// from scratch.
709+
if (fetched) {
710+
_reset();
711+
notifyListeners();
712+
fetchInitial();
713+
}
714+
715+
default:
716+
return;
717+
}
718+
}
719+
665720
/// Update data derived from the content of the given message.
666721
///
667722
/// This does not notify listeners.

lib/model/store.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,8 @@ class PerAccountStore extends PerAccountStoreBase with ChangeNotifier, EmojiStor
942942

943943
case MutedUsersEvent():
944944
assert(debugLog("server event: muted_users"));
945+
_messages.handleMutedUsersEvent(event);
946+
// Update _users last, so other handlers can compare to the old value.
945947
_users.handleMutedUsersEvent(event);
946948
notifyListeners();
947949

lib/model/user.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,25 @@ mixin UserStore on PerAccountStoreBase {
8686
bool allRecipientsMuted(DmNarrow narrow, {List<MutedUserItem>? mutedUsers}) {
8787
return !narrow.otherRecipientIds.any((id) => !isUserMuted(id, mutedUsers: mutedUsers));
8888
}
89+
90+
/// Whether the given event will change the result of [allRecipientsMuted]
91+
/// for its mutedUsers, compared to the current state.
92+
MutenessEffect willChangeIfRecipientMuted(MutedUsersEvent event) {
93+
assert(mutedUsers.length != event.mutedUsers.length);
94+
return mutedUsers.length < event.mutedUsers.length
95+
? MutenessEffect.added
96+
: MutenessEffect.removed;
97+
}
98+
}
99+
100+
/// Whether a given [MutedUsersEvent] will affect the results
101+
/// that [UserStore.allRecipientsMuted] would give for some messages.
102+
enum MutenessEffect {
103+
/// A new user is added to the muted users list.
104+
added,
105+
106+
/// A new user is removed from the muted users list.
107+
removed,
89108
}
90109

91110
/// The implementation of [UserStore] that does the work.

0 commit comments

Comments
 (0)