From 86575a1e866058c1d9b9fa635ad995c8a135e897 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 6 May 2020 18:52:35 +0200 Subject: [PATCH] Display the number of unread notifications --- lib/ui/routes/main_route/tablet_route.dart | 10 +-- lib/ui/widgets/icon_button_badge.dart | 50 +++++++++++++ .../tablet_mode/tablet_navbar_widget.dart | 71 +++++++++++++++++++ 3 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 lib/ui/widgets/icon_button_badge.dart create mode 100644 lib/ui/widgets/tablet_mode/tablet_navbar_widget.dart diff --git a/lib/ui/routes/main_route/tablet_route.dart b/lib/ui/routes/main_route/tablet_route.dart index 41e869d..61ad585 100644 --- a/lib/ui/routes/main_route/tablet_route.dart +++ b/lib/ui/routes/main_route/tablet_route.dart @@ -1,6 +1,7 @@ import 'package:comunic/ui/routes/main_route/main_route.dart'; import 'package:comunic/ui/widgets/tablet_mode/current_user_panel.dart'; import 'package:comunic/ui/widgets/tablet_mode/memberships_panel.dart'; +import 'package:comunic/ui/widgets/tablet_mode/tablet_navbar_widget.dart'; import 'package:flutter/material.dart'; /// Main tablet route @@ -21,14 +22,7 @@ class _TabletRouteState extends State { ); } - Widget _buildAppBar() => AppBar( - title: Text("Comunic"), - actions: [ - IconButton(icon: Icon(Icons.notifications), onPressed: () {}), - IconButton(icon: Icon(Icons.message), onPressed: () {}), - PopupMenuButton(itemBuilder: (c) => []), - ], - ); + Widget _buildAppBar() => ComunicTabletNavbarWidget(); Widget _buildBody() => Row( children: [_buildLeftPane(), _buildRightPane()], diff --git a/lib/ui/widgets/icon_button_badge.dart b/lib/ui/widgets/icon_button_badge.dart new file mode 100644 index 0000000..ada949b --- /dev/null +++ b/lib/ui/widgets/icon_button_badge.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +/// Display an icon button with a badge +/// +/// Based from Medium article called "Notification Badge in Flutter" +/// +/// @author Pierre Hubert + +class IconButtonWithBadge extends StatelessWidget { + final Widget icon; + final void Function() onPressed; + final int number; + + const IconButtonWithBadge({ + Key key, + @required this.icon, + @required this.onPressed, + this.number = 0, + }) : assert(icon != null), + assert(number != null), + super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: AlignmentDirectional.center, + children: [ + IconButton(icon: icon, onPressed: onPressed), + number != 0 + ? Positioned( + right: 6, + top: 6, + child: Container( + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(6), + ), + constraints: BoxConstraints(minWidth: 14, minHeight: 14), + child: Text( + "$number", + style: TextStyle(color: Colors.white, fontSize: 12), + textAlign: TextAlign.center, + ), + )) + : Container() + ], + ); + } +} diff --git a/lib/ui/widgets/tablet_mode/tablet_navbar_widget.dart b/lib/ui/widgets/tablet_mode/tablet_navbar_widget.dart new file mode 100644 index 0000000..33cba1e --- /dev/null +++ b/lib/ui/widgets/tablet_mode/tablet_navbar_widget.dart @@ -0,0 +1,71 @@ +import 'package:comunic/helpers/events_helper.dart'; +import 'package:comunic/helpers/notifications_helper.dart'; +import 'package:comunic/models/count_unread_notifications.dart'; +import 'package:comunic/ui/widgets/icon_button_badge.dart'; +import 'package:comunic/ui/widgets/safe_state.dart'; +import 'package:flutter/material.dart'; + +/// Comunic tablet navbar widget +/// +/// @author Pierre Hubert + +class ComunicTabletNavbarWidget extends StatefulWidget + implements PreferredSizeWidget { + @override + _ComunicTabletNavbarWidgetState createState() => + _ComunicTabletNavbarWidgetState(); + + @override + Size get preferredSize => Size.fromHeight(kToolbarHeight); +} + +class _ComunicTabletNavbarWidgetState + extends SafeState { + var _unreadNotifications = + CountUnreadNotifications(notifications: 0, conversations: 0); + + void _refreshCountUnread() async { + try { + final count = await NotificationsHelper().countUnread(); + + setState(() { + _unreadNotifications = count; + }); + } catch (e, s) { + print("Could not refresh the number of unread notifications: $e\n$s"); + } + } + + @override + void initState() { + super.initState(); + + _refreshCountUnread(); + + // Listen to notifications number update + this.listenChangeState( + (d) => _unreadNotifications.notifications = d.newNum); + this.listenChangeState( + (d) => _unreadNotifications.conversations = d.newNum); + } + + @override + Widget build(BuildContext context) { + return AppBar( + title: Text("Comunic"), + actions: [ + IconButtonWithBadge( + icon: Icon(Icons.notifications), + onPressed: () {}, + number: _unreadNotifications.notifications, + ), + IconButtonWithBadge( + icon: Icon(Icons.message), + onPressed: () {}, + number: _unreadNotifications.conversations, + ), + PopupMenuButton(itemBuilder: (c) => []), + ], + ); + } +}