Notification Tab Badge
Component Detail
Description
Unread count badge overlaid on the Notifications bottom navigation tab icon. Listens to the notification BLoC stream and updates the badge count in real time as Supabase Realtime delivers new notifications. Hides when count is zero. Announces count changes via accessibility announcements.
notification-tab-badge
Summaries
The Notification Tab Badge is a small but strategically significant component: it is the primary visual signal that draws users back into the notification feed when new information awaits them. An accurate, real-time unread count badge on the bottom navigation tab reduces the risk of users missing time-sensitive communications — such as new assignment deadlines or certificate expirations — and increases daily active engagement with the notifications feature. The Supabase Realtime integration means the count updates without requiring the user to manually refresh the app, delivering a modern, always-current experience that matches user expectations set by leading consumer apps. The 99+ cap and accessibility announcements ensure the component is both visually clean and inclusive.
This is a low-complexity component but it has an infrastructure dependency on Supabase Realtime being configured and stable before end-to-end testing is possible. The BLoC stream subscription must be carefully managed to avoid memory leaks — ensure the component's BlocBuilder is scoped within the BottomNavigationBar widget tree and disposes correctly on logout. The accessibility announcement behaviour (count change announcements to screen readers) requires dedicated testing on both VoiceOver and TalkBack and is easy to miss in standard QA flows. The 99+ formatting logic is trivial but should be covered by unit tests to prevent regression.
Badge visibility toggling (hide at zero) must be tested against the initial app load state when the user has no unread notifications.
NotificationTabBadge is a lightweight Flutter widget composed of a Stack layering the tab Icon with a positioned Badge widget (Flutter 3.x Material 3 Badge or a custom Container). It subscribes to NotificationBloc state via BlocBuilder
getAccessibilityLabel(int count) returns a localised string such as '$count unread notifications' passed to Semantics(label:). Count change announcements use a BlocListener calling SemanticsService.announce() only when unreadCount changes to a non-zero value to avoid noisy repeated announcements on state rebuilds.
Responsibilities
- Display unread notification count as a badge on the tab icon
- Hide badge when unread count is zero
- Update reactively from BLoC stream without full widget rebuild
- Announce count changes to screen readers
- Cap displayed count at 99+ for large values
Interfaces
build(BuildContext)
updateCount(int unreadCount)
formatBadgeLabel(int count)
getAccessibilityLabel(int count)