import 'package:clipboard/clipboard.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/conversation_message.dart'; import 'package:comunic/models/user.dart'; import 'package:comunic/ui/widgets/account_image_widget.dart'; import 'package:comunic/ui/widgets/conversation_file_tile.dart'; import 'package:comunic/ui/widgets/text_widget.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; /// Conversation message tile /// /// @author Pierre HUBERT enum _MenuChoices { COPY_URL, COPY_MESSAGE, DELETE, REQUEST_UPDATE_CONTENT, GET_STATS, } typedef OnRequestMessageStats = void Function(ConversationMessage); typedef OnRequestMessageUpdate = void Function(ConversationMessage); typedef OnRequestMessageDelete = void Function(ConversationMessage); class ConversationMessageTile extends StatelessWidget { final Conversation conversation; final ConversationMessage message; final User userInfo; final bool isLastMessage; final bool isFirstMessage; final OnRequestMessageStats onRequestMessageStats; final OnRequestMessageUpdate onRequestMessageUpdate; final OnRequestMessageDelete onRequestMessageDelete; const ConversationMessageTile({ Key key, @required this.conversation, @required this.message, @required this.userInfo, @required this.isLastMessage, @required this.isFirstMessage, @required this.onRequestMessageStats, @required this.onRequestMessageUpdate, @required this.onRequestMessageDelete, }) : assert(message != null), assert(userInfo != null), assert(isLastMessage != null), assert(isFirstMessage != null), assert(onRequestMessageStats != null), assert(onRequestMessageUpdate != null), assert(onRequestMessageDelete != null), super(key: key); Color get backgroundColor => message.isOwner ? conversation.color ?? Colors.blueAccent : darkTheme() ? Colors.white12 : Colors.black12; /// Build account image Widget _buildAccountImage(BuildContext context) { return Container( margin: EdgeInsets.all(10.0), child: PopupMenuButton<_MenuChoices>( child: AccountImageWidget( user: userInfo, width: 35.0, ), itemBuilder: (c) => >[ PopupMenuItem( enabled: (message.message?.content ?? "") != "", value: _MenuChoices.COPY_MESSAGE, child: Text(tr("Copy message")), ), PopupMenuItem( enabled: message.file != null, value: _MenuChoices.COPY_URL, child: Text(tr("Copy URL")), ), PopupMenuItem( value: _MenuChoices.GET_STATS, child: Text(tr("Statistics")), ), // Update message content PopupMenuItem( enabled: message.isOwner && message.message != null && message.message.content.isNotEmpty, value: _MenuChoices.REQUEST_UPDATE_CONTENT, child: Text(tr("Update")), ), // Delete the message PopupMenuItem( enabled: message.isOwner, value: _MenuChoices.DELETE, child: Text(tr("Delete")), ), ]..removeWhere((element) => !element.enabled), onSelected: _menuOptionSelected, ), ); } /// Build widget image Widget _buildMessageFile(BuildContext context) => ConversationFileWidget( messageID: message.id, file: message.file, defaultBackgroundColor: backgroundColor, ); /// Build message date Widget _buildMessageDate() { return isLastMessage ? Container( margin: EdgeInsets.only(top: 5.0), child: Text( dateTimeToString(message.date), style: TextStyle( color: darkTheme() ? Colors.white : Colors.black54, fontSize: 12.0), textAlign: TextAlign.center, ), ) : Container(); } /// Build a message of the current user Widget _buildRightMessage(BuildContext context) { return Container( margin: EdgeInsets.only(bottom: isLastMessage ? 20.0 : 2.0), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Column( children: [ Row( children: [ Column( children: [ // Text image Container( child: message.hasFile ? _buildMessageFile(context) : null, ), // Text message Container( child: message.hasMessage ? Container( width: 200.0, alignment: Alignment.centerRight, child: Container( child: TextWidget( content: message.message, textAlign: TextAlign.justify, style: TextStyle(color: Colors.white), linksColor: Colors.indigo, ), padding: EdgeInsets.fromLTRB( 15.0, 10.0, 15.0, 10.0), decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(8.0), ), ), ) : null, ), ], ), // Account image _buildAccountImage(context) ], ), // Date Container( child: _buildMessageDate(), margin: EdgeInsets.only(right: 45.0), ) ], ), ], ), ); // Text } /// Build a message of a peer user Widget _buildLeftMessage(BuildContext context) { return Container( margin: EdgeInsets.only(bottom: isLastMessage ? 20.0 : 5.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ //User name Container( margin: EdgeInsets.only(left: 55.0), child: isFirstMessage ? Text( userInfo.fullName, textAlign: TextAlign.left, style: TextStyle(fontSize: 12.0), ) : null, ), Row( children: [ // Account image _buildAccountImage(context), Column( children: [ // Text image Container( child: message.hasFile ? _buildMessageFile(context) : null, ), // Text message Container( child: message.hasMessage ? Container( width: 200.0, alignment: Alignment.centerLeft, child: Container( child: TextWidget( content: message.message, textAlign: TextAlign.justify, style: TextStyle( color: darkTheme() ? Colors.white : Colors.black), ), padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0), decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(8.0), ), ), ) : null, ), ], ), ], ), // Date Container( margin: EdgeInsets.only(left: 50.0), child: Align( alignment: Alignment.topLeft, child: _buildMessageDate(), ), ) ], ), ); } @override Widget build(BuildContext context) { return message.isOwner ? _buildRightMessage(context) : _buildLeftMessage(context); } /// Process menu choice void _menuOptionSelected(_MenuChoices value) { switch (value) { case _MenuChoices.COPY_MESSAGE: FlutterClipboard.copy(message.message.content); break; case _MenuChoices.COPY_URL: FlutterClipboard.copy(message.file.url); break; case _MenuChoices.GET_STATS: onRequestMessageStats(message); break; case _MenuChoices.REQUEST_UPDATE_CONTENT: onRequestMessageUpdate(message); break; case _MenuChoices.DELETE: onRequestMessageDelete(message); break; } } }