import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; /// Navigation bar widget /// /// @author Pierre HUBERT typedef OnSelectMenuAction = void Function(BarCallbackActions); /// Callback actions enum BarCallbackActions { OPEN_NOTIFICATIONS, OPEN_CONVERSATIONS, OPEN_NEWEST_POSTS, OPEN_FRIENDS, OPEN_MY_PAGE, OPEN_GROUPS, OPEN_GROUP_PAGE, OPEN_APP_SETTINGS, NONE, ACTION_LOGOUT } Color _primaryColor() => darkTheme() ? Colors.black : Colors.blue; Color _secondaryColor() => darkTheme() ? darkAccentColor : Colors.white; /// Menu item information class _MenuItem { final String label; final Widget icon; final BarCallbackActions action; final bool isMenu; const _MenuItem({ @required this.label, @required this.icon, @required this.action, this.isMenu = false, }) : assert(label != null), assert(icon != null || isMenu), assert(action != null), assert(isMenu != null); } /// Item of action menu class _ActionMenuItem { final String label; final BarCallbackActions action; const _ActionMenuItem({@required this.label, @required this.action}) : assert(label != null), assert(action != null); } /// List of menu items to show final _menuItems = <_MenuItem>[ _MenuItem( label: tr("Notifications"), icon: Icon(Icons.notifications), action: BarCallbackActions.OPEN_NOTIFICATIONS), _MenuItem( label: tr("Conversations"), icon: Icon(Icons.comment), action: BarCallbackActions.OPEN_CONVERSATIONS), _MenuItem( label: tr("Newest"), icon: Icon(Icons.refresh), action: BarCallbackActions.OPEN_NEWEST_POSTS), _MenuItem( label: tr("Friends"), icon: Icon(Icons.group), action: BarCallbackActions.OPEN_FRIENDS), _MenuItem( label: tr("Menu"), icon: Icon(Icons.more_vert), isMenu: true, action: BarCallbackActions.NONE) ]; /// List of menu actions items final _menuActionsItem = <_ActionMenuItem>[ _ActionMenuItem( label: tr("My Page"), action: BarCallbackActions.OPEN_MY_PAGE), _ActionMenuItem(label: tr("Groups"), action: BarCallbackActions.OPEN_GROUPS), _ActionMenuItem( label: tr("App settings"), action: BarCallbackActions.OPEN_APP_SETTINGS), _ActionMenuItem( label: tr("Sign out"), action: BarCallbackActions.ACTION_LOGOUT), ]; /// Public widget class ComunicAppBar extends StatelessWidget implements PreferredSizeWidget { final OnSelectMenuAction onTap; final BarCallbackActions selectedAction; const ComunicAppBar( {Key key, @required this.onTap, @required this.selectedAction}) : assert(onTap != null), super(key: key); @override Widget build(BuildContext context) { return Material( color: darkTheme() ? Colors.black : Colors.blue, child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: List.generate( _menuItems.length, (i) => _MenuItemWidget( item: _menuItems[i], onTap: onTap, isSelected: _menuItems[i].action == selectedAction, ), ), ), ); } @override Size get preferredSize => Size.fromHeight(40); } /// The [Widget] part of a menu item class _MenuItemWidget extends StatelessWidget { final _MenuItem item; final OnSelectMenuAction onTap; final bool isSelected; const _MenuItemWidget( {Key key, @required this.item, @required this.onTap, @required this.isSelected}) : assert(item != null), assert(onTap != null), assert(isSelected != null), super(key: key); @override Widget build(BuildContext context) { assert(debugCheckHasMaterial(context)); return Expanded( child: Material( color: isSelected ? _secondaryColor() : _primaryColor(), child: !item.isMenu ? InkWell( child: _buildIconContainer(), onTap: () => onTap(item.action), ) : _buildContextMenuPopupButton(), ), ); } Widget _buildIconContainer() { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ IconTheme( data: IconThemeData( color: isSelected ? _primaryColor() : _secondaryColor()), child: item.icon, ) ], ); } // Build context menu Widget _buildContextMenuPopupButton() { return PopupMenuButton( child: _buildIconContainer(), itemBuilder: (i) => _menuActionsItem .map((f) => PopupMenuItem( child: Text(f.label), value: f.action, )) .toList(), onSelected: onTap, ); } }