Skip to content

Commit 4b4bc65

Browse files
chrisbobbegnprice
authored andcommitted
home: Show unread counts in main menu
Fixes-partly: zulip#1088
1 parent 857b975 commit 4b4bc65

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

lib/widgets/home.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import 'store.dart';
2424
import 'subscription_list.dart';
2525
import 'text.dart';
2626
import 'theme.dart';
27+
import 'unread_count_badge.dart';
2728
import 'user.dart';
2829

2930
enum _HomePageTab {
@@ -506,6 +507,8 @@ abstract class _MenuButton extends StatelessWidget {
506507
color: selected ? designVariables.iconSelected : designVariables.icon);
507508
}
508509

510+
Widget? buildTrailing(BuildContext context) => null;
511+
509512
void onPressed(BuildContext context);
510513

511514
void _handlePress(BuildContext context) {
@@ -546,6 +549,8 @@ abstract class _MenuButton extends StatelessWidget {
546549
~WidgetState.pressed: selected ? borderSideSelected : null,
547550
}));
548551

552+
final trailing = buildTrailing(context);
553+
549554
return AnimatedScaleOnTap(
550555
duration: const Duration(milliseconds: 100),
551556
scaleEnd: 0.95,
@@ -562,6 +567,7 @@ abstract class _MenuButton extends StatelessWidget {
562567
overflow: TextOverflow.ellipsis,
563568
style: const TextStyle(fontSize: 19, height: 26 / 19)
564569
.merge(weightVariableTextStyle(context, wght: selected ? 600 : 400)))),
570+
?trailing,
565571
]))));
566572
}
567573
}
@@ -612,6 +618,18 @@ class _InboxButton extends _NavigationBarMenuButton {
612618
return zulipLocalizations.inboxPageTitle;
613619
}
614620

621+
@override
622+
Widget? buildTrailing(BuildContext context) {
623+
final store = PerAccountStoreWidget.of(context);
624+
final unreadCount = store.unreads.countInCombinedFeedNarrow();
625+
if (unreadCount == 0) return null;
626+
return UnreadCountBadge(
627+
style: UnreadCountBadgeStyle.mainMenu,
628+
count: unreadCount,
629+
channelIdForBackground: null,
630+
);
631+
}
632+
615633
@override
616634
_HomePageTab get navigationTarget => _HomePageTab.inbox;
617635
}
@@ -627,6 +645,18 @@ class _MentionsButton extends _MenuButton {
627645
return zulipLocalizations.mentionsPageTitle;
628646
}
629647

648+
@override
649+
Widget? buildTrailing(BuildContext context) {
650+
final store = PerAccountStoreWidget.of(context);
651+
final unreadCount = store.unreads.countInMentionsNarrow();
652+
if (unreadCount == 0) return null;
653+
return UnreadCountBadge(
654+
style: UnreadCountBadgeStyle.mainMenu,
655+
count: unreadCount,
656+
channelIdForBackground: null,
657+
);
658+
}
659+
630660
@override
631661
void onPressed(BuildContext context) {
632662
Navigator.of(context).push(MessageListPage.buildRoute(
@@ -696,6 +726,18 @@ class _DirectMessagesButton extends _NavigationBarMenuButton {
696726
return zulipLocalizations.recentDmConversationsPageTitle;
697727
}
698728

729+
@override
730+
Widget? buildTrailing(BuildContext context) {
731+
final store = PerAccountStoreWidget.of(context);
732+
final unreadCount = store.unreads.countInDms();
733+
if (unreadCount == 0) return null;
734+
return UnreadCountBadge(
735+
style: UnreadCountBadgeStyle.mainMenu,
736+
count: unreadCount,
737+
channelIdForBackground: null,
738+
);
739+
}
740+
699741
@override
700742
_HomePageTab get navigationTarget => _HomePageTab.directMessages;
701743
}

lib/widgets/unread_count_badge.dart

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,20 @@ import 'theme.dart';
1010
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=2037-186671&m=dev
1111
/// It looks like that component was created for the main menu,
1212
/// then adapted for various other contexts, like the Inbox page.
13+
/// See [UnreadCountBadgeStyle].
1314
///
14-
/// Currently this widget supports only those other contexts (not the main menu)
15-
/// and only the component's "kind=unread" variant (not "kind=quantity").
16-
/// For example, the "Channels" page and the topic-list page:
17-
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6205-26001&m=dev
18-
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6823-37113&m=dev
19-
/// (We use this for the topic-list page even though the Figma makes it a bit
20-
/// more compact there…the inconsistency seems worse and might be accidental.)
21-
// TODO support the main-menu context, update dartdoc
15+
/// Currently this widget supports only the component's "kind=unread" variant,
16+
/// not "kind=quantity".
2217
// TODO support the "kind=quantity" variant, update dartdoc
2318
class UnreadCountBadge extends StatelessWidget {
2419
const UnreadCountBadge({
2520
super.key,
21+
this.style = UnreadCountBadgeStyle.other,
2622
required this.count,
2723
required this.channelIdForBackground,
2824
});
2925

26+
final UnreadCountBadgeStyle style;
3027
final int count;
3128

3229
/// An optional [Subscription.streamId], for a channel-colorized background.
@@ -55,23 +52,52 @@ class UnreadCountBadge extends StatelessWidget {
5552
backgroundColor = designVariables.bgCounterUnread;
5653
}
5754

55+
final padding = switch (style) {
56+
UnreadCountBadgeStyle.mainMenu =>
57+
const EdgeInsets.symmetric(horizontal: 5, vertical: 4),
58+
UnreadCountBadgeStyle.other =>
59+
const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
60+
};
61+
62+
final double wght = switch (style) {
63+
UnreadCountBadgeStyle.mainMenu => 600,
64+
UnreadCountBadgeStyle.other => 500,
65+
};
66+
5867
return DecoratedBox(
5968
decoration: BoxDecoration(
6069
borderRadius: BorderRadius.circular(5),
6170
color: backgroundColor,
6271
),
6372
child: Padding(
64-
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
73+
padding: padding,
6574
child: Text(
6675
style: TextStyle(
6776
fontSize: 16,
6877
height: (16 / 16),
6978
color: textColor,
70-
).merge(weightVariableTextStyle(context, wght: 500)),
79+
).merge(weightVariableTextStyle(context, wght: wght)),
7180
count.toString())));
7281
}
7382
}
7483

84+
enum UnreadCountBadgeStyle {
85+
/// The style to use in the main menu.
86+
///
87+
/// Figma:
88+
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=2037-185126&m=dev
89+
mainMenu,
90+
91+
/// The style to use in other contexts besides the main menu.
92+
///
93+
/// Other contexts include the "Channels" page and the topic-list page:
94+
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6205-26001&m=dev
95+
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6823-37113&m=dev
96+
/// (We use this for the topic-list page even though the Figma makes it a bit
97+
/// more compact there…the inconsistency seems worse and might be accidental.)
98+
other,
99+
}
100+
75101
class MutedUnreadBadge extends StatelessWidget {
76102
const MutedUnreadBadge({super.key});
77103

0 commit comments

Comments
 (0)