From c7371acb1393cf6e85ece601c46e8359b46728f4 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Fri, 13 Mar 2020 20:09:32 +0100 Subject: [PATCH] Improve message bubble design --- lib/components/list_items/message.dart | 157 ++++++++++++------- lib/components/list_items/state_message.dart | 22 ++- lib/utils/event_extension.dart | 15 ++ pubspec.lock | 10 +- 4 files changed, 132 insertions(+), 72 deletions(-) diff --git a/lib/components/list_items/message.dart b/lib/components/list_items/message.dart index 02ea030..8967bb2 100644 --- a/lib/components/list_items/message.dart +++ b/lib/components/list_items/message.dart @@ -4,6 +4,7 @@ import 'package:fluffychat/components/message_content.dart'; import 'package:fluffychat/components/reply_content.dart'; import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; +import 'package:fluffychat/utils/event_extension.dart'; import 'package:fluffychat/utils/string_color.dart'; import 'package:fluffychat/views/image_viewer.dart'; import 'package:flutter/material.dart'; @@ -71,72 +72,71 @@ class Message extends StatelessWidget { margin: BubbleEdges.symmetric(horizontal: 4), color: color, nip: nip, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: Stack( children: [ - Row( + Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - ownMessage - ? I18n.of(context).you - : event.sender.calcDisplayname(), - style: TextStyle( - color: ownMessage - ? textColor - : event.sender.calcDisplayname().color, - fontWeight: FontWeight.bold, + if (event.isReply) + FutureBuilder( + future: event.getReplyEvent(timeline), + builder: (BuildContext context, snapshot) { + final Event replyEvent = snapshot.hasData + ? snapshot.data + : Event( + eventId: event.content['m.relates_to'] + ['m.in_reply_to']['event_id'], + content: {"msgtype": "m.text", "body": "..."}, + senderId: event.senderId, + typeKey: "m.room.message", + room: event.room, + roomId: event.roomId, + status: 1, + time: DateTime.now(), + ); + return Container( + margin: EdgeInsets.symmetric(vertical: 4.0), + child: + ReplyContent(replyEvent, lightText: ownMessage), + ); + }, ), + MessageContent( + event, + textColor: textColor, ), - SizedBox(width: 4), - Text( - event.time.localizedTime(context), - style: TextStyle( - color: textColor.withAlpha(180), + if (event.type == EventTypes.Encrypted && + event.messageType == MessageTypes.BadEncrypted && + event.content["body"] == DecryptError.UNKNOWN_SESSION) + RaisedButton( + color: color.withAlpha(100), + child: Text( + I18n.of(context).requestPermission, + style: TextStyle(color: textColor), + ), + onPressed: () => Matrix.of(context) + .tryRequestWithLoadingDialog(event.requestKey()), ), + SizedBox(height: 4), + _MetaRow( + event, + ownMessage, + textColor, + invisible: true, ), ], ), - if (event.isReply) - FutureBuilder( - future: event.getReplyEvent(timeline), - builder: (BuildContext context, snapshot) { - final Event replyEvent = snapshot.hasData - ? snapshot.data - : Event( - eventId: event.content['m.relates_to'] - ['m.in_reply_to']['event_id'], - content: {"msgtype": "m.text", "body": "..."}, - senderId: event.senderId, - typeKey: "m.room.message", - room: event.room, - roomId: event.roomId, - status: 1, - time: DateTime.now(), - ); - return Container( - margin: EdgeInsets.symmetric(vertical: 4.0), - child: ReplyContent(replyEvent, lightText: ownMessage), - ); - }, + Positioned( + bottom: 0, + right: ownMessage ? 0 : null, + left: !ownMessage ? 0 : null, + child: _MetaRow( + event, + ownMessage, + textColor, ), - MessageContent( - event, - textColor: textColor, ), - if (event.type == EventTypes.Encrypted && - event.messageType == MessageTypes.BadEncrypted && - event.content["body"] == DecryptError.UNKNOWN_SESSION) - RaisedButton( - color: color.withAlpha(100), - child: Text( - I18n.of(context).requestPermission, - style: TextStyle(color: textColor), - ), - onPressed: () => Matrix.of(context) - .tryRequestWithLoadingDialog(event.requestKey()), - ), ], ), ), @@ -179,3 +179,50 @@ class Message extends StatelessWidget { ); } } + +class _MetaRow extends StatelessWidget { + final Event event; + final bool invisible; + final bool ownMessage; + final Color color; + + const _MetaRow(this.event, this.ownMessage, this.color, + {this.invisible = false, Key key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final String displayname = event.sender.calcDisplayname(); + final bool showDisplayname = + !ownMessage && event.senderId != event.room.directChatMatrixID; + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (showDisplayname) + Text( + displayname, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.bold, + color: invisible ? Colors.transparent : displayname.color, + ), + ), + if (showDisplayname) SizedBox(width: 4), + Text( + event.time.localizedTime(context), + style: TextStyle( + color: invisible ? Colors.transparent : color, + fontSize: 11, + ), + ), + if (ownMessage) SizedBox(width: 2), + if (ownMessage) + Icon( + event.statusIcon, + size: 12, + color: invisible ? Colors.transparent : color, + ), + ], + ); + } +} diff --git a/lib/components/list_items/state_message.dart b/lib/components/list_items/state_message.dart index f50753a..bafb145 100644 --- a/lib/components/list_items/state_message.dart +++ b/lib/components/list_items/state_message.dart @@ -17,18 +17,16 @@ class StateMessage extends StatelessWidget { right: 8.0, bottom: 8.0, ), - child: Opacity( - opacity: 0.5, - child: Bubble( - elevation: 0, - color: Colors.black, - alignment: Alignment.center, - child: LinkText( - text: event.getLocalizedBody(context), - textStyle: TextStyle( - color: Colors.white, - decoration: event.redacted ? TextDecoration.lineThrough : null, - ), + child: Bubble( + elevation: 0, + color: Theme.of(context).backgroundColor.withOpacity(0.5), + alignment: Alignment.center, + child: LinkText( + text: event.getLocalizedBody(context), + textAlign: TextAlign.center, + textStyle: TextStyle( + color: Theme.of(context).primaryColor, + decoration: event.redacted ? TextDecoration.lineThrough : null, ), ), ), diff --git a/lib/utils/event_extension.dart b/lib/utils/event_extension.dart index dcbe3c3..6289b0e 100644 --- a/lib/utils/event_extension.dart +++ b/lib/utils/event_extension.dart @@ -245,4 +245,19 @@ extension LocalizedBody on Event { return localizedBody; } + + IconData get statusIcon { + switch (this.status) { + case -1: + return Icons.error_outline; + case 0: + return Icons.timer; + case 1: + return Icons.done; + case 2: + return Icons.done_all; + default: + return Icons.done; + } + } } diff --git a/pubspec.lock b/pubspec.lock index 40a7966..988d5f4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -124,8 +124,8 @@ packages: dependency: "direct main" description: path: "." - ref: "7c7f2a3dd80b4c40c1e3c106f75a0af985a2221b" - resolved-ref: "7c7f2a3dd80b4c40c1e3c106f75a0af985a2221b" + ref: eb84c2a0856af99527f00697cbed4eb67a47887d + resolved-ref: eb84c2a0856af99527f00697cbed4eb67a47887d url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" @@ -274,7 +274,7 @@ packages: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.16.1" + version: "0.16.0" intl_translation: dependency: "direct main" description: @@ -377,8 +377,8 @@ packages: dependency: transitive description: path: "." - ref: "307dc133867eb5bf80d4f5c7412e58621dfca3cf" - resolved-ref: "307dc133867eb5bf80d4f5c7412e58621dfca3cf" + ref: bbc7ce10a52be5d5c10d2eb6c3591aade71356e2 + resolved-ref: bbc7ce10a52be5d5c10d2eb6c3591aade71356e2 url: "https://gitlab.com/famedly/libraries/dart-olm.git" source: git version: "0.0.0"