diff --git a/lib/widgets/inbox.dart b/lib/widgets/inbox.dart index 00c17841af..927dfeecdb 100644 --- a/lib/widgets/inbox.dart +++ b/lib/widgets/inbox.dart @@ -94,18 +94,22 @@ class _InboxPageState extends State with PerAccountStoreAwareStateMix // TODO efficiently include DM conversations that aren't recent enough // to appear in recentDmConversationsView, but still have unreads in // unreadsModel. - final dmItems = <(DmNarrow, int)>[]; + final dmItems = <(DmNarrow, int, bool)>[]; int allDmsCount = 0; + bool allDmsIsMentioned = false; for (final dmNarrow in recentDmConversationsModel!.sorted) { final countInNarrow = unreadsModel!.countInDmNarrow(dmNarrow); if (countInNarrow == 0) { continue; } - dmItems.add((dmNarrow, countInNarrow)); + final isMentioned = unreadsModel!.dms[dmNarrow]!.any( + (messageId) => unreadsModel!.mentions.contains(messageId)); + if (isMentioned) allDmsIsMentioned = true; + dmItems.add((dmNarrow, countInNarrow, isMentioned)); allDmsCount += countInNarrow; } if (allDmsCount > 0) { - sections.add(_AllDmsSectionData(allDmsCount, dmItems)); + sections.add(_AllDmsSectionData(allDmsCount, allDmsIsMentioned, dmItems)); } final sortedUnreadStreams = unreadsModel!.streams.entries @@ -184,9 +188,10 @@ sealed class _InboxSectionData { class _AllDmsSectionData extends _InboxSectionData { final int count; - final List<(DmNarrow, int)> items; + final bool isMentioned; + final List<(DmNarrow, int, bool)> items; - const _AllDmsSectionData(this.count, this.items); + const _AllDmsSectionData(this.count, this.isMentioned, this.items); } class _StreamSectionData extends _InboxSectionData { @@ -296,7 +301,7 @@ class _AllDmsSection extends StatelessWidget { Widget build(BuildContext context) { final header = _AllDmsHeaderItem( count: data.count, - isMentioned: false, + isMentioned: data.isMentioned, collapsed: collapsed, pageState: pageState, ); @@ -305,10 +310,11 @@ class _AllDmsSection extends StatelessWidget { child: Column(children: [ header, if (!collapsed) ...data.items.map((item) { - final (narrow, count) = item; + final (narrow, count, isMentioned) = item; return _DmItem( narrow: narrow, count: count, + isMentioned: isMentioned, allDmsCount: data.count, pageState: pageState, ); @@ -321,12 +327,14 @@ class _DmItem extends StatelessWidget { const _DmItem({ required this.narrow, required this.count, + required this.isMentioned, required this.allDmsCount, required this.pageState }); final DmNarrow narrow; final int count; + final bool isMentioned; final int allDmsCount; final _InboxPageState pageState; @@ -348,7 +356,7 @@ class _DmItem extends StatelessWidget { return StickyHeaderItem( header: _AllDmsHeaderItem( count: allDmsCount, - isMentioned: false, + isMentioned: isMentioned, collapsed: false, pageState: pageState, ), @@ -375,6 +383,7 @@ class _DmItem extends StatelessWidget { overflow: TextOverflow.ellipsis, title))), const SizedBox(width: 12), + if (isMentioned) const _AtMentionMarker(), Padding(padding: const EdgeInsetsDirectional.only(end: 16), child: UnreadCountBadge(backgroundColor: null, count: count)), diff --git a/test/widgets/inbox_test.dart b/test/widgets/inbox_test.dart index e908709a71..b3cda6613a 100644 --- a/test/widgets/inbox_test.dart +++ b/test/widgets/inbox_test.dart @@ -219,6 +219,26 @@ void main() { .isFalse(); check(hasAtSign(tester, findRowByLabel(tester, topic))).isFalse(); }); + + testWidgets('dm with a mention', (tester) async { + await setupPage(tester, + users: [eg.selfUser, eg.otherUser], + unreadMessages: [eg.dmMessage(from: eg.otherUser, to: [eg.selfUser], + flags: [MessageFlag.mentioned])]); + + check(hasAtSign(tester, findAllDmsHeaderRow(tester))).isTrue(); + check(hasAtSign(tester, findRowByLabel(tester, eg.otherUser.fullName))).isTrue(); + }); + + testWidgets('dm without mention', (tester) async { + await setupPage(tester, + users: [eg.selfUser, eg.otherUser], + unreadMessages: [eg.dmMessage(from: eg.otherUser, to: [eg.selfUser], + flags: [])]); + + check(hasAtSign(tester, findAllDmsHeaderRow(tester))).isFalse(); + check(hasAtSign(tester, findRowByLabel(tester, eg.otherUser.fullName))).isFalse(); + }); }); group('collapsing', () {