1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-12-26 04:48:51 +00:00

Diplay the number of unread notifications / conversations

This commit is contained in:
Pierre HUBERT 2020-04-17 13:28:01 +02:00
parent 90d58bbee3
commit 003eb1efc2
3 changed files with 115 additions and 14 deletions

View File

@ -1,5 +1,6 @@
import 'package:comunic/lists/notifications_list.dart';
import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/count_unread_notifications.dart';
import 'package:comunic/models/notification.dart';
/// Notifications helper
@ -47,6 +48,22 @@ const _NotificationsTypeAPImapping = {
};
class NotificationsHelper {
/// Get the number of unread notifications
///
/// This method throws in case of error
Future<CountUnreadNotifications> countUnread() async {
final response =
await APIRequest(uri: "notifications/count_all_news", needLogin: true)
.exec();
final content = response.assertOk().getObject();
return CountUnreadNotifications(
notifications: content["notifications"],
conversations: content["conversations"],
);
}
/// Get the list of unread notifications of the user
Future<NotificationsList> getUnread() async {
final response =

View File

@ -0,0 +1,14 @@
/// Count the number of unread notifications
///
/// @author Pierre Hubert
class CountUnreadNotifications {
final int notifications;
final int conversations;
CountUnreadNotifications({
this.notifications,
this.conversations,
}) : assert(notifications != null),
assert(conversations != null);
}

View File

@ -1,3 +1,6 @@
import 'package:comunic/helpers/notifications_helper.dart';
import 'package:comunic/models/count_unread_notifications.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
@ -106,7 +109,7 @@ final _menuActionsItem = <_ActionMenuItem>[
];
/// Public widget
class ComunicAppBar extends StatelessWidget implements PreferredSizeWidget {
class ComunicAppBar extends StatefulWidget implements PreferredSizeWidget {
final OnSelectMenuAction onTap;
final BarCallbackActions selectedAction;
@ -115,6 +118,51 @@ class ComunicAppBar extends StatelessWidget implements PreferredSizeWidget {
: assert(onTap != null),
super(key: key);
@override
_ComunicAppBarState createState() => _ComunicAppBarState();
@override
Size get preferredSize => Size.fromHeight(40);
}
class _ComunicAppBarState extends SafeState<ComunicAppBar> {
CountUnreadNotifications _unreadNotifications;
@override
void initState() {
_refreshCountUnread();
super.initState();
}
void _refreshCountUnread() async {
try {
final count = await NotificationsHelper().countUnread();
setState(() {
_unreadNotifications = count;
});
} catch (e, stack) {
print("Could not refresh the number of unread notifications: $e");
print(stack);
}
}
/// Get the number of unread notifications for the selected notice
int getNumberUnread(BarCallbackActions action) {
if (_unreadNotifications == null) return 0;
switch (action) {
case BarCallbackActions.OPEN_NOTIFICATIONS:
return _unreadNotifications.notifications;
case BarCallbackActions.OPEN_CONVERSATIONS:
return _unreadNotifications.conversations;
default:
return 0;
}
}
@override
Widget build(BuildContext context) {
return Material(
@ -125,16 +173,14 @@ class ComunicAppBar extends StatelessWidget implements PreferredSizeWidget {
_menuItems.length,
(i) => _MenuItemWidget(
item: _menuItems[i],
onTap: onTap,
isSelected: _menuItems[i].action == selectedAction,
onTap: widget.onTap,
isSelected: _menuItems[i].action == widget.selectedAction,
newNotice: getNumberUnread(_menuItems[i].action),
),
),
),
);
}
@override
Size get preferredSize => Size.fromHeight(40);
}
/// The [Widget] part of a menu item
@ -143,12 +189,16 @@ class _MenuItemWidget extends StatelessWidget {
final OnSelectMenuAction onTap;
final bool isSelected;
const _MenuItemWidget(
{Key key,
@required this.item,
@required this.onTap,
@required this.isSelected})
: assert(item != null),
/// A number to notify of news.
final int newNotice;
const _MenuItemWidget({
Key key,
@required this.item,
@required this.onTap,
@required this.isSelected,
this.newNotice = 0,
}) : assert(item != null),
assert(onTap != null),
assert(isSelected != null),
super(key: key);
@ -171,14 +221,34 @@ class _MenuItemWidget extends StatelessWidget {
}
Widget _buildIconContainer() {
return Column(
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Spacer(
flex: 2,
),
IconTheme(
data: IconThemeData(
color: isSelected ? _primaryColor() : _secondaryColor()),
child: item.icon,
)
),
newNotice > 0 ? Spacer() : Container(),
newNotice == 0
? Container()
: Material(
color: Colors.red,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Text(" $newNotice ",
style: TextStyle(color: Colors.white)),
),
borderRadius: BorderRadius.all(
Radius.circular(50.0),
)),
Spacer(
flex: 2,
),
],
);
}