diff --git a/lib/components/list_items/message.dart b/lib/components/list_items/message.dart index f1c6d00a..8758bd63 100644 --- a/lib/components/list_items/message.dart +++ b/lib/components/list_items/message.dart @@ -1,6 +1,7 @@ import 'package:bubble/bubble.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/message_content.dart'; +import 'package:fluffychat/components/reply_content.dart'; import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; @@ -18,9 +19,14 @@ class Message extends StatelessWidget { final Function(Event) onSelect; final bool longPressSelect; final bool selected; + final Timeline timeline; const Message(this.event, - {this.nextEvent, this.longPressSelect, this.onSelect, this.selected}); + {this.nextEvent, + this.longPressSelect, + this.onSelect, + this.selected, + this.timeline}); @override Widget build(BuildContext context) { @@ -88,6 +94,30 @@ class Message extends StatelessWidget { ), ], ), + if (event.isReply) + FutureBuilder( + future: timeline.getEventById(event.content['m.relates_to'] + ['m.in_reply_to']['event_id']), + 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, diff --git a/lib/components/message_content.dart b/lib/components/message_content.dart index bc2b3a1b..1adcf16f 100644 --- a/lib/components/message_content.dart +++ b/lib/components/message_content.dart @@ -130,7 +130,7 @@ class MessageContent extends StatelessWidget { case MessageTypes.Notice: case MessageTypes.Emote: return LinkText( - text: event.getLocalizedBody(context), + text: event.getLocalizedBody(context, hideQuotes: true), textStyle: TextStyle( color: textColor, decoration: event.redacted ? TextDecoration.lineThrough : null, diff --git a/lib/components/reply_content.dart b/lib/components/reply_content.dart new file mode 100644 index 00000000..e03c04a6 --- /dev/null +++ b/lib/components/reply_content.dart @@ -0,0 +1,52 @@ +import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/utils/event_extension.dart'; +import 'package:flutter/material.dart'; + +class ReplyContent extends StatelessWidget { + final Event replyEvent; + final bool lightText; + + const ReplyContent(this.replyEvent, {this.lightText = false, Key key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Container( + width: 3, + height: 36, + color: lightText ? Colors.white : Theme.of(context).primaryColor, + ), + SizedBox(width: 6), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + (replyEvent?.sender?.calcDisplayname() ?? "") + ":", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontWeight: FontWeight.bold, + color: + lightText ? Colors.white : Theme.of(context).primaryColor, + ), + ), + Text( + replyEvent?.getLocalizedBody(context, + withSenderNamePrefix: false) ?? + "", + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: + TextStyle(color: lightText ? Colors.white : Colors.black), + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/views/chat.dart b/lib/views/chat.dart index 9631e7be..7e53b8f1 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -8,6 +8,7 @@ import 'package:fluffychat/components/chat_settings_popup_menu.dart'; import 'package:fluffychat/components/dialogs/confirm_dialog.dart'; import 'package:fluffychat/components/list_items/message.dart'; import 'package:fluffychat/components/matrix.dart'; +import 'package:fluffychat/components/reply_content.dart'; import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/event_extension.dart'; @@ -148,32 +149,11 @@ class _ChatState extends State<_Chat> { void send() { if (sendController.text.isEmpty) return; - Map textContent = { - "msgtype": "m.text", - "body": sendController.text, - }; + room.sendTextEvent(sendController.text, inReplyTo: replyEvent); + sendController.text = ""; if (replyEvent != null) { - String replyText = "<${replyEvent.senderId}> " + - replyEvent.getLocalizedBody( - context, - withSenderNamePrefix: false, - hideQuotes: true, - ); - List replyTextLines = replyText.split("\n"); - for (int i = 0; i < replyTextLines.length; i++) { - replyTextLines[i] = "> " + replyTextLines[i]; - } - replyText = replyTextLines.join("\n"); - textContent["body"] = replyText + "\n\n${sendController.text}"; - textContent["m.relates_to"] = { - "m.in_reply_to": { - "event_id": replyEvent.eventId, - }, - }; setState(() => replyEvent = null); } - room.sendEvent(textContent); - sendController.text = ""; } void sendFileAction(BuildContext context) async { @@ -454,6 +434,7 @@ class _ChatState extends State<_Chat> { longPressSelect: selectedEvents.isEmpty, selected: selectedEvents .contains(timeline.events[i - 1]), + timeline: timeline, nextEvent: i >= 2 ? timeline.events[i - 2] : null); }); @@ -471,35 +452,8 @@ class _ChatState extends State<_Chat> { icon: Icon(Icons.close), onPressed: () => setState(() => replyEvent = null), ), - Container( - width: 2, - height: 36, - color: Theme.of(context).primaryColor, - ), - SizedBox(width: 6), Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - (replyEvent?.sender?.calcDisplayname() ?? "") + ":", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).primaryColor, - ), - ), - Text( - replyEvent?.getLocalizedBody(context, - withSenderNamePrefix: false) ?? - "", - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - ], - ), + child: ReplyContent(replyEvent), ), ], ), diff --git a/pubspec.lock b/pubspec.lock index 8f32ee57..efa0bf89 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -117,8 +117,8 @@ packages: dependency: "direct main" description: path: "." - ref: "38f7bf947610b9b19a81aa9db05d76b460d116d9" - resolved-ref: "38f7bf947610b9b19a81aa9db05d76b460d116d9" + ref: e2fde3fa924cb9a1bdccf5dd6b63aad8d820d20a + resolved-ref: e2fde3fa924cb9a1bdccf5dd6b63aad8d820d20a url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index 4c45241d..54d67d52 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,7 @@ dependencies: famedlysdk: git: url: https://gitlab.com/famedly/famedlysdk.git - ref: 38f7bf947610b9b19a81aa9db05d76b460d116d9 + ref: e2fde3fa924cb9a1bdccf5dd6b63aad8d820d20a localstorage: ^3.0.1+4 bubble: ^1.1.9+1