From 8b5d1de37744142957d2b096f4c31b049249c603 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 21 Apr 2020 22:05:38 +0200 Subject: [PATCH] extract date_divider and reply_indicator widgets --- lib/src/date_divider.dart | 91 ++++++++++++++++++++++++++++++++++ lib/src/message_list_view.dart | 78 ++--------------------------- lib/src/message_widget.dart | 50 +++++-------------- lib/src/reply_indicator.dart | 54 ++++++++++++++++++++ lib/src/sending_indicator.dart | 2 +- lib/stream_chat_flutter.dart | 1 + 6 files changed, 163 insertions(+), 113 deletions(-) create mode 100644 lib/src/date_divider.dart create mode 100644 lib/src/reply_indicator.dart diff --git a/lib/src/date_divider.dart b/lib/src/date_divider.dart new file mode 100644 index 00000000..f1d074d1 --- /dev/null +++ b/lib/src/date_divider.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +/// It shows a date divider depending on the date difference +class DateDivider extends StatelessWidget { + const DateDivider({ + Key key, + @required this.nextMessage, + @required this.messageWidget, + }) : super(key: key); + + final Message nextMessage; + final Widget messageWidget; + + @override + Widget build(BuildContext context) { + final divider = Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Divider(), + ), + ); + + final createdAt = Jiffy(nextMessage.createdAt.toLocal()); + final now = DateTime.now(); + final hourInfo = createdAt.format('h:mm a'); + + String dayInfo; + if (Jiffy(createdAt).isSame(now, Units.DAY)) { + dayInfo = 'TODAY'; + } else if (Jiffy(createdAt) + .isSame(now.subtract(Duration(days: 1)), Units.DAY)) { + dayInfo = 'YESTERDAY'; + } else if (Jiffy(createdAt).isAfter( + now.subtract(Duration(days: 7)), + Units.DAY, + )) { + dayInfo = createdAt.format('EEEE').toUpperCase(); + } else if (Jiffy(createdAt).isAfter( + Jiffy(now).subtract(years: 1), + Units.DAY, + )) { + dayInfo = createdAt.format('dd/MM').toUpperCase(); + } else { + dayInfo = createdAt.format('dd/MM/yyyy').toUpperCase(); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + messageWidget, + Padding( + padding: const EdgeInsets.only(top: 24.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + divider, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32.0), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: dayInfo, + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + TextSpan(text: ' AT'), + TextSpan(text: ' $hourInfo'), + ], + style: TextStyle( + fontWeight: FontWeight.normal, + ), + ), + style: TextStyle( + fontSize: 10, + color: + Theme.of(context).textTheme.title.color.withOpacity(.5), + ), + ), + ), + divider, + ], + ), + ), + ], + ); + } +} diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 8f8fdab2..a6f2dba1 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -6,6 +6,7 @@ import 'package:stream_chat/stream_chat.dart'; import 'package:visibility_detector/visibility_detector.dart'; import '../stream_chat_flutter.dart'; +import 'date_divider.dart'; import 'message_widget.dart'; import 'stream_channel.dart'; @@ -225,80 +226,9 @@ class _MessageListViewState extends State { if (nextMessage != null && !Jiffy(message.createdAt.toLocal()) .isSame(nextMessage.createdAt.toLocal(), Units.DAY)) { - final divider = Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Divider(), - ), - ); - - final createdAt = Jiffy(nextMessage.createdAt.toLocal()); - final now = DateTime.now(); - final hourInfo = createdAt.format('h:mm a'); - - String dayInfo; - if (Jiffy(createdAt).isSame(now, Units.DAY)) { - dayInfo = 'TODAY'; - } else if (Jiffy(createdAt) - .isSame(now.subtract(Duration(days: 1)), Units.DAY)) { - dayInfo = 'YESTERDAY'; - } else if (Jiffy(createdAt).isAfter( - now.subtract(Duration(days: 7)), - Units.DAY, - )) { - dayInfo = createdAt.format('EEEE').toUpperCase(); - } else if (Jiffy(createdAt).isAfter( - Jiffy(now).subtract(years: 1), - Units.DAY, - )) { - dayInfo = createdAt.format('dd/MM').toUpperCase(); - } else { - dayInfo = createdAt.format('dd/MM/yyyy').toUpperCase(); - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - messageWidget, - Padding( - padding: const EdgeInsets.only(top: 24.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - divider, - Padding( - padding: const EdgeInsets.symmetric(horizontal: 32.0), - child: Text.rich( - TextSpan( - children: [ - TextSpan( - text: dayInfo, - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - TextSpan(text: ' AT'), - TextSpan(text: ' $hourInfo'), - ], - style: TextStyle( - fontWeight: FontWeight.normal, - ), - ), - style: TextStyle( - fontSize: 10, - color: Theme.of(context) - .textTheme - .title - .color - .withOpacity(.5), - ), - ), - ), - divider, - ], - ), - ), - ], + return DateDivider( + messageWidget: messageWidget, + nextMessage: nextMessage, ); } diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 56579f79..1e0fd789 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -1,5 +1,4 @@ import 'dart:io'; -import 'dart:math'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:chewie/chewie.dart'; @@ -13,6 +12,7 @@ import 'package:stream_chat_flutter/src/full_screen_image.dart'; import 'package:stream_chat_flutter/src/message_input.dart'; import 'package:stream_chat_flutter/src/message_list_view.dart'; import 'package:stream_chat_flutter/src/reaction_picker.dart'; +import 'package:stream_chat_flutter/src/reply_indicator.dart'; import 'package:stream_chat_flutter/src/sending_indicator.dart'; import 'package:stream_chat_flutter/src/stream_channel.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; @@ -206,45 +206,19 @@ class _MessageWidgetState extends State } Widget _buildThreadIndicator(BuildContext context) { - var row = [ - Text( - 'Replies: ${widget.message.replyCount}', - style: _messageTheme.replies, - ), - Transform( - transform: Matrix4.rotationY(_isMyMessage ? 0 : pi), - alignment: Alignment.center, - child: Icon( - Icons.subdirectory_arrow_left, - color: Theme.of(context).brightness == Brightness.dark - ? Colors.white12 - : Colors.black12, - ), - ), - ]; - - if (!_isMyMessage) { - row = row.reversed.toList(); - } - - return (widget.message.replyCount ?? 0) > 0 - ? GestureDetector( - onTap: () { - if (widget.isParent) { - return; - } - if (widget.onThreadTap != null) { + if (widget.message?.replyCount != null && widget.message.replyCount > 0) { + return ReplyIndicator( + onTap: widget.isParent + ? () { widget.onThreadTap(widget.message); } - }, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 2.0), - child: Row( - children: row, - ), - ), - ) - : SizedBox(); + : null, + message: widget.message, + messageTheme: _messageTheme, + reversed: _isMyMessage, + ); + } + return SizedBox(); } Widget _buildBubble( diff --git a/lib/src/reply_indicator.dart b/lib/src/reply_indicator.dart new file mode 100644 index 00000000..6ed5f83a --- /dev/null +++ b/lib/src/reply_indicator.dart @@ -0,0 +1,54 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +class ReplyIndicator extends StatelessWidget { + final Message message; + final VoidCallback onTap; + final bool reversed; + final MessageTheme messageTheme; + + const ReplyIndicator({ + Key key, + this.message, + this.onTap, + this.reversed = false, + this.messageTheme, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + var row = [ + Text( + 'Replies: ${message.replyCount}', + style: messageTheme?.replies, + ), + Transform( + transform: Matrix4.rotationY(reversed ? 0 : pi), + alignment: Alignment.center, + child: Icon( + Icons.subdirectory_arrow_left, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white12 + : Colors.black12, + ), + ), + ]; + + if (!reversed) { + row = row.reversed.toList(); + } + + return GestureDetector( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 2.0), + child: Row( + children: row, + ), + ), + ); + } +} diff --git a/lib/src/sending_indicator.dart b/lib/src/sending_indicator.dart index 6a36eae4..9c7ebb57 100644 --- a/lib/src/sending_indicator.dart +++ b/lib/src/sending_indicator.dart @@ -19,7 +19,7 @@ class SendingIndicator extends StatelessWidget { ), child: CircleAvatar( radius: 4, - backgroundColor: Theme.of(context).accentColor, + backgroundColor: StreamChatTheme.of(context).accentColor, child: Icon( Icons.done, color: Colors.white, diff --git a/lib/stream_chat_flutter.dart b/lib/stream_chat_flutter.dart index d777ffff..38e0dac3 100644 --- a/lib/stream_chat_flutter.dart +++ b/lib/stream_chat_flutter.dart @@ -6,6 +6,7 @@ export 'src/channel_list_view.dart'; export 'src/channel_name.dart'; export 'src/channel_preview.dart'; export 'src/channels_bloc.dart'; +export 'src/date_divider.dart'; export 'src/message_input.dart'; export 'src/message_list_view.dart'; export 'src/message_widget.dart';