import 'package:comunic/helpers/conversations_helper.dart'; import 'package:comunic/lists/groups_list.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/config.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/ui/routes/main_route/main_route.dart'; import 'package:comunic/ui/widgets/conversation_image_widget.dart'; import 'package:comunic/ui/widgets/custom_list_tile.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:flutter/material.dart'; /// Single conversation tile /// /// @author Pierre HUBERT typedef OpenConversationCallback = void Function(Conversation); typedef RequestLeaveConversationCallback = void Function(Conversation); typedef RequestUpdateConversationCallback = void Function(Conversation); enum _PopupMenuChoices { UPDATE, LEAVE } class ConversationTile extends StatelessWidget { final Conversation conversation; final UsersList usersList; final GroupsList? groupsList; final OpenConversationCallback onOpen; final RequestUpdateConversationCallback onRequestUpdate; final RequestLeaveConversationCallback onRequestLeave; const ConversationTile({ Key? key, required this.conversation, required this.usersList, required this.groupsList, required this.onOpen, required this.onRequestUpdate, required this.onRequestLeave, }) : assert(conversation != null), assert(usersList != null), assert(onOpen != null), assert(onRequestUpdate != null), assert(onRequestLeave != null), super(key: key); _buildSubInformation(IconData icon, String content) { return Row( children: [ Icon( icon, size: 15.0, color: Colors.grey, ), Text(" " + content), ], ); } @override Widget build(BuildContext context) => Column( children: [_buildMainTile(context), _buildCallTile(context)], ); Widget _buildMainTile(BuildContext context) => CustomListTile( onTap: () => onOpen(conversation), // Conversation name title: Text( ConversationsHelper.getConversationName( conversation, usersList, )!, style: TextStyle( fontWeight: conversation.sawLastMessage ? null : FontWeight.bold, ), ), // Tile color tileColor: conversation.sawLastMessage ? null : (conversation.color ?? config().unreadConversationColor ?? Colors.blue) .withOpacity(0.2), // Leading icon leading: ConversationImageWidget( conversation: conversation, users: usersList, group: conversation.isGroupConversation ? groupsList!.getGroup(conversation.groupID) : null, ), // Conversation information isThreeLine: true, subtitle: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildSubInformation(Icons.access_time, diffTimeFromNowToStr(conversation.lastActivity!)!), conversation.isGroupConversation ? _buildSubInformation( Icons.link, tr("Group: %group_name%", args: { "group_name": groupsList!.getGroup(conversation.groupID)!.name })!) : _buildSubInformation( Icons.group, conversation.members!.length == 1 ? tr("1 member")! : tr( "%num% members", args: { "num": conversation.members!.length.toString(), }, )!, ), ], ), onLongPressOpenMenu: (position) { showMenu<_PopupMenuChoices>( context: context, position: position, items: [ PopupMenuItem( child: Text(tr("Update")!), value: _PopupMenuChoices.UPDATE, ), PopupMenuItem( child: Text(tr("Leave")!), value: _PopupMenuChoices.LEAVE, ) ]).then(_conversationMenuCallback); }, ); /// Build call tile, in case of ongoing call Widget _buildCallTile(BuildContext context) { if (!conversation.isHavingCall) return Container(); return Padding( padding: EdgeInsets.only(bottom: 20), child: ListTile( onTap: () => MainController.of(context)!.startCall(conversation.id!), dense: true, title: Text(tr("Ongoing call")!), leading: Icon(Icons.call), tileColor: Colors.yellow.withOpacity(0.2), ), ); } /// Method called each time an option of the menu is selected void _conversationMenuCallback(_PopupMenuChoices? c) { switch (c) { case _PopupMenuChoices.UPDATE: onRequestUpdate(conversation); break; case _PopupMenuChoices.LEAVE: onRequestLeave(conversation); break; } } }