From 7dc7261a06a98a285e2225553c6cdb6903583f4f Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 11:43:48 +0100 Subject: [PATCH 1/8] add initial example --- example/lib/custom_theme.dart | 129 +++++++++++++++++++++++++++++++++ lib/src/message_widget.dart | 43 +++++------ lib/src/stream_chat.dart | 40 ++++++---- lib/src/stream_chat_theme.dart | 117 ++++++++++++++++++++---------- lib/src/user_avatar.dart | 8 +- 5 files changed, 260 insertions(+), 77 deletions(-) create mode 100644 example/lib/custom_theme.dart diff --git a/example/lib/custom_theme.dart b/example/lib/custom_theme.dart new file mode 100644 index 00000000..cc65d81f --- /dev/null +++ b/example/lib/custom_theme.dart @@ -0,0 +1,129 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() async { + final client = Client('qk4nn7rpcn75', logLevel: Level.INFO); + + await client.setUser( + User(id: 'wild-breeze-7'), + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoid2lsZC1icmVlemUtNyJ9.VM2EX1EXOfgqa-bTH_3JzeY0T99ngWzWahSauP3dBMo', + ); + + runApp(MyApp(client)); +} + +class MyApp extends StatelessWidget { + final Client client; + + MyApp(this.client); + + @override + Widget build(BuildContext context) { + final theme = ThemeData( + primarySwatch: Colors.green, + ); + + final streamTheme = StreamChatThemeData.fromTheme(theme); + + return MaterialApp( + theme: theme, + home: Container( + child: StreamChat( + streamChatThemeData: streamTheme.copyWith( + channelPreviewTheme: ChannelPreviewTheme( + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(16), + ), + ), + ownMessageTheme: MessageTheme( + replies: streamTheme.ownMessageTheme.replies + .copyWith(fontStyle: FontStyle.italic), + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(12), + ), + ), + otherMessageTheme: MessageTheme( + messageBackgroundColor: Colors.red, + ), + ), + client: client, + child: ChannelListPage(), + ), + ), + ); + } +} + +class ChannelListPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: ChannelListView( + filter: { + 'members': { + '\$in': [StreamChat.of(context).user.id], + } + }, + sort: [SortOption('last_message_at')], + pagination: PaginationParams( + limit: 20, + ), + channelWidget: ChannelPage(), + ), + ); + } +} + +class ChannelPage extends StatelessWidget { + const ChannelPage({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: ChannelHeader(), + body: Column( + children: [ + Expanded( + child: MessageListView( + threadBuilder: (_, parentMessage) { + return ThreadPage( + parent: parentMessage, + ); + }, + ), + ), + MessageInput(), + ], + ), + ); + } +} + +class ThreadPage extends StatelessWidget { + final Message parent; + + ThreadPage({ + Key key, + this.parent, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column( + children: [ + Expanded( + child: MessageListView( + parentMessage: parent, + ), + ), + MessageInput( + parentMessage: parent, + ), + ], + ), + ); + } +} diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 9c3aa322..5d499f6a 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -41,6 +41,8 @@ class _MessageWidgetState extends State final Map _videoControllers = {}; final Map _chuwieControllers = {}; + MessageTheme messageTheme; + @override Widget build(BuildContext context) { super.build(context); @@ -56,6 +58,10 @@ class _MessageWidgetState extends State final alignment = isMyMessage ? Alignment.centerRight : Alignment.centerLeft; + messageTheme = isMyMessage + ? StreamChatTheme.of(context).ownMessageTheme + : StreamChatTheme.of(context).otherMessageTheme; + Widget child; if (widget.message.type == 'deleted') { @@ -121,9 +127,10 @@ class _MessageWidgetState extends State ), child: Text( 'This message was deleted...', - style: StreamChatTheme.of(context).messageTheme.messageText.copyWith( - fontStyle: FontStyle.italic, - ), + style: messageTheme.messageText.copyWith( + fontStyle: FontStyle.italic, + color: Colors.black, + ), ), ), ); @@ -133,7 +140,7 @@ class _MessageWidgetState extends State var row = [ Text( 'Replies: ${widget.message.replyCount}', - style: StreamChatTheme.of(context).messageTheme.replies, + style: messageTheme.replies, ), Transform( transform: Matrix4.rotationY(isMyMessage ? 0 : pi), @@ -220,13 +227,11 @@ class _MessageWidgetState extends State Text( attachment.title, overflow: TextOverflow.ellipsis, - style: StreamChatTheme.of(context) - .messageTheme - .messageText - .copyWith( - color: Colors.blue, - fontWeight: FontWeight.bold, - ), + style: + messageTheme.messageText.copyWith( + color: Colors.blue, + fontWeight: FontWeight.bold, + ), ), Text( Uri.parse(attachment.thumbUrl) @@ -238,9 +243,7 @@ class _MessageWidgetState extends State .reversed .join('.'), overflow: TextOverflow.ellipsis, - style: StreamChatTheme.of(context) - .messageTheme - .createdAt, + style: messageTheme.createdAt, ), ], ), @@ -321,9 +324,7 @@ class _MessageWidgetState extends State styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)) .copyWith( - p: StreamChatTheme.of(context) - .messageTheme - .messageText, + p: messageTheme.messageText, ), ), ), @@ -602,7 +603,7 @@ class _MessageWidgetState extends State padding: const EdgeInsets.only(top: 5.0), child: Text( formatDate(widget.message.createdAt.toLocal(), [HH, ':', nn]), - style: StreamChatTheme.of(context).messageTheme.createdAt, + style: messageTheme.createdAt, ), ); } @@ -616,11 +617,7 @@ class _MessageWidgetState extends State topRight: Radius.circular((isMyMessage && isLastUser) ? 2 : 16), bottomRight: Radius.circular(isMyMessage ? 2 : 16), ), - color: isMyMessage - ? StreamChatTheme.of(context).messageTheme.ownMessageBackgroundColor - : StreamChatTheme.of(context) - .messageTheme - .otherMessageBackgroundColor, + color: messageTheme.messageBackgroundColor, ); } diff --git a/lib/src/stream_chat.dart b/lib/src/stream_chat.dart index 2ce338a5..c9b03f92 100644 --- a/lib/src/stream_chat.dart +++ b/lib/src/stream_chat.dart @@ -107,20 +107,32 @@ class StreamChatState extends State { messageInputButtonTheme: themeData?.channelTheme?.messageInputButtonTheme, ), - messageTheme: defaultTheme.messageTheme.copyWith( - replies: themeData?.messageTheme?.replies, - createdAt: themeData?.messageTheme?.createdAt, - messageText: themeData?.messageTheme?.messageText, - otherMessageBackgroundColor: - themeData?.messageTheme?.otherMessageBackgroundColor, - ownMessageBackgroundColor: - themeData?.messageTheme?.ownMessageBackgroundColor, - fontFamily: themeData?.messageTheme?.fontFamily, - messageAuthor: themeData?.messageTheme?.messageAuthor, - messageMention: themeData?.messageTheme?.messageMention, - avatarTheme: defaultTheme.messageTheme.avatarTheme.copyWith( - constraints: themeData?.messageTheme?.avatarTheme?.constraints, - borderRadius: themeData?.messageTheme?.avatarTheme?.borderRadius, + ownMessageTheme: defaultTheme.ownMessageTheme.copyWith( + replies: themeData?.ownMessageTheme?.replies, + createdAt: themeData?.ownMessageTheme?.createdAt, + messageText: themeData?.ownMessageTheme?.messageText, + messageBackgroundColor: + themeData?.ownMessageTheme?.messageBackgroundColor, + fontFamily: themeData?.ownMessageTheme?.fontFamily, + messageAuthor: themeData?.ownMessageTheme?.messageAuthor, + messageMention: themeData?.ownMessageTheme?.messageMention, + avatarTheme: defaultTheme.ownMessageTheme.avatarTheme.copyWith( + constraints: themeData?.ownMessageTheme?.avatarTheme?.constraints, + borderRadius: themeData?.ownMessageTheme?.avatarTheme?.borderRadius, + ), + ), + otherMessageTheme: defaultTheme.otherMessageTheme.copyWith( + replies: themeData?.otherMessageTheme?.replies, + createdAt: themeData?.otherMessageTheme?.createdAt, + messageText: themeData?.otherMessageTheme?.messageText, + messageBackgroundColor: + themeData?.otherMessageTheme?.messageBackgroundColor, + fontFamily: themeData?.otherMessageTheme?.fontFamily, + messageAuthor: themeData?.otherMessageTheme?.messageAuthor, + messageMention: themeData?.otherMessageTheme?.messageMention, + avatarTheme: defaultTheme.otherMessageTheme.avatarTheme.copyWith( + constraints: themeData?.otherMessageTheme?.avatarTheme?.constraints, + borderRadius: themeData?.otherMessageTheme?.avatarTheme?.borderRadius, ), ), accentColor: themeData?.accentColor, diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index c3db901f..bcd098c3 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -28,7 +28,8 @@ class StreamChatThemeData { final Color accentColor; final ChannelPreviewTheme channelPreviewTheme; final ChannelTheme channelTheme; - final MessageTheme messageTheme; + final MessageTheme ownMessageTheme; + final MessageTheme otherMessageTheme; StreamChatThemeData({ this.primaryColor, @@ -36,7 +37,8 @@ class StreamChatThemeData { this.accentColor, this.channelPreviewTheme, this.channelTheme, - this.messageTheme, + this.otherMessageTheme, + this.ownMessageTheme, }); factory StreamChatThemeData.fromTheme(ThemeData theme) { @@ -52,8 +54,13 @@ class StreamChatThemeData { theme.accentColor, ]), ), - messageTheme: MessageTheme( - replies: defaultTheme.messageTheme.replies.copyWith( + ownMessageTheme: MessageTheme( + replies: defaultTheme.ownMessageTheme.replies.copyWith( + color: theme.accentColor, + ), + ), + otherMessageTheme: MessageTheme( + replies: defaultTheme.ownMessageTheme.replies.copyWith( color: theme.accentColor, ), ), @@ -66,7 +73,8 @@ class StreamChatThemeData { Color accentColor, ChannelPreviewTheme channelPreviewTheme, ChannelTheme channelTheme, - MessageTheme messageTheme, + MessageTheme ownMessageTheme, + MessageTheme otherMessageTheme, }) => StreamChatThemeData( primaryColor: primaryColor ?? this.primaryColor, @@ -97,27 +105,44 @@ class StreamChatThemeData { this.channelTheme.inputBackground, ) ?? this.channelTheme, - messageTheme: messageTheme?.copyWith( - messageText: - messageTheme?.messageText ?? this.messageTheme.messageText, - messageAuthor: messageTheme?.messageAuthor ?? - this.messageTheme.messageAuthor, - messageMention: messageTheme?.messageMention ?? - this.messageTheme.messageMention, - createdAt: messageTheme?.createdAt ?? this.messageTheme.createdAt, - replies: messageTheme?.replies ?? this.messageTheme.replies, - fontFamily: - messageTheme?.fontFamily ?? this.messageTheme.fontFamily, - ownMessageBackgroundColor: - messageTheme?.ownMessageBackgroundColor ?? - this.messageTheme.ownMessageBackgroundColor, - otherMessageBackgroundColor: - messageTheme?.otherMessageBackgroundColor ?? - this.messageTheme.otherMessageBackgroundColor, - avatarTheme: - messageTheme?.avatarTheme ?? this.messageTheme.avatarTheme, + ownMessageTheme: ownMessageTheme?.copyWith( + messageText: ownMessageTheme?.messageText ?? + this.ownMessageTheme.messageText, + messageAuthor: ownMessageTheme?.messageAuthor ?? + this.ownMessageTheme.messageAuthor, + messageMention: ownMessageTheme?.messageMention ?? + this.ownMessageTheme.messageMention, + createdAt: + ownMessageTheme?.createdAt ?? this.ownMessageTheme.createdAt, + replies: ownMessageTheme?.replies ?? this.ownMessageTheme.replies, + fontFamily: ownMessageTheme?.fontFamily ?? + this.ownMessageTheme.fontFamily, + messageBackgroundColor: ownMessageTheme?.messageBackgroundColor ?? + this.ownMessageTheme.messageBackgroundColor, + avatarTheme: ownMessageTheme?.avatarTheme ?? + this.ownMessageTheme.avatarTheme, ) ?? - this.messageTheme, + this.ownMessageTheme, + otherMessageTheme: otherMessageTheme?.copyWith( + messageText: otherMessageTheme?.messageText ?? + this.otherMessageTheme.messageText, + messageAuthor: otherMessageTheme?.messageAuthor ?? + this.otherMessageTheme.messageAuthor, + messageMention: otherMessageTheme?.messageMention ?? + this.otherMessageTheme.messageMention, + createdAt: otherMessageTheme?.createdAt ?? + this.otherMessageTheme.createdAt, + replies: + otherMessageTheme?.replies ?? this.otherMessageTheme.replies, + fontFamily: otherMessageTheme?.fontFamily ?? + this.otherMessageTheme.fontFamily, + messageBackgroundColor: + otherMessageTheme?.messageBackgroundColor ?? + this.otherMessageTheme.messageBackgroundColor, + avatarTheme: otherMessageTheme?.avatarTheme ?? + this.otherMessageTheme.avatarTheme, + ) ?? + this.otherMessageTheme, ); static StreamChatThemeData getDefaultTheme(ThemeData theme) { @@ -174,7 +199,7 @@ class StreamChatThemeData { Color(0xFF0076FF), ]), ), - messageTheme: MessageTheme( + ownMessageTheme: MessageTheme( messageText: TextStyle( fontSize: 15, color: Colors.black, @@ -188,8 +213,30 @@ class StreamChatThemeData { fontWeight: FontWeight.bold, fontSize: 12, ), - ownMessageBackgroundColor: Color(0xffebebeb), - otherMessageBackgroundColor: Colors.white, + messageBackgroundColor: Color(0xffebebeb), + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(20), + constraints: BoxConstraints.tightFor( + height: 32, + width: 32, + ), + ), + ), + otherMessageTheme: MessageTheme( + messageText: TextStyle( + fontSize: 15, + color: Colors.black, + ), + createdAt: TextStyle( + color: Colors.black.withOpacity(.5), + fontSize: 11, + ), + replies: TextStyle( + color: accentColor, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + messageBackgroundColor: Colors.white, avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( @@ -269,8 +316,7 @@ class MessageTheme { final TextStyle createdAt; final TextStyle replies; final String fontFamily; - final Color ownMessageBackgroundColor; - final Color otherMessageBackgroundColor; + final Color messageBackgroundColor; final AvatarTheme avatarTheme; const MessageTheme({ @@ -279,8 +325,7 @@ class MessageTheme { this.messageAuthor, this.messageMention, this.fontFamily, - this.ownMessageBackgroundColor, - this.otherMessageBackgroundColor, + this.messageBackgroundColor, this.avatarTheme, this.createdAt, }); @@ -292,7 +337,7 @@ class MessageTheme { TextStyle createdAt, TextStyle replies, String fontFamily, - Color ownMessageBackgroundColor, + Color messageBackgroundColor, Color otherMessageBackgroundColor, AvatarTheme avatarTheme, }) => @@ -302,10 +347,8 @@ class MessageTheme { messageMention: messageMention ?? this.messageMention, createdAt: createdAt ?? this.createdAt, fontFamily: fontFamily ?? this.fontFamily, - ownMessageBackgroundColor: - ownMessageBackgroundColor ?? this.ownMessageBackgroundColor, - otherMessageBackgroundColor: - otherMessageBackgroundColor ?? this.otherMessageBackgroundColor, + messageBackgroundColor: + messageBackgroundColor ?? this.messageBackgroundColor, avatarTheme: avatarTheme ?? this.avatarTheme, replies: replies ?? this.replies, ); diff --git a/lib/src/user_avatar.dart b/lib/src/user_avatar.dart index e0650b62..4c78b254 100644 --- a/lib/src/user_avatar.dart +++ b/lib/src/user_avatar.dart @@ -19,10 +19,12 @@ class UserAvatar extends StatelessWidget { return Container( padding: const EdgeInsets.all(4), constraints: - StreamChatTheme.of(context).messageTheme.avatarTheme.constraints, + StreamChatTheme.of(context).ownMessageTheme.avatarTheme.constraints, decoration: BoxDecoration( - borderRadius: - StreamChatTheme.of(context).messageTheme.avatarTheme.borderRadius, + borderRadius: StreamChatTheme.of(context) + .ownMessageTheme + .avatarTheme + .borderRadius, color: StreamChatTheme.of(context).accentColor, ), child: user.extraData?.containsKey('image') ?? false From 2d7ea2d3cd0dede2d26fcf62f211c596ee886638 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 13:28:01 +0100 Subject: [PATCH 2/8] add custom theme example --- example/lib/custom_theme.dart | 20 ++--- lib/src/channel_preview.dart | 2 + lib/src/message_list_view.dart | 8 +- lib/src/message_widget.dart | 150 ++++++++++++++++++--------------- pubspec.yaml | 3 +- 5 files changed, 96 insertions(+), 87 deletions(-) diff --git a/example/lib/custom_theme.dart b/example/lib/custom_theme.dart index cc65d81f..26b66584 100644 --- a/example/lib/custom_theme.dart +++ b/example/lib/custom_theme.dart @@ -23,27 +23,19 @@ class MyApp extends StatelessWidget { primarySwatch: Colors.green, ); - final streamTheme = StreamChatThemeData.fromTheme(theme); - return MaterialApp( theme: theme, home: Container( child: StreamChat( - streamChatThemeData: streamTheme.copyWith( - channelPreviewTheme: ChannelPreviewTheme( - avatarTheme: AvatarTheme( - borderRadius: BorderRadius.circular(16), - ), - ), + streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith( ownMessageTheme: MessageTheme( - replies: streamTheme.ownMessageTheme.replies - .copyWith(fontStyle: FontStyle.italic), + messageBackgroundColor: Colors.black, + messageText: TextStyle( + color: Colors.white, + ), avatarTheme: AvatarTheme( - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(8), ), - ), - otherMessageTheme: MessageTheme( - messageBackgroundColor: Colors.red, ), ), client: client, diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index 14ab6980..669c608b 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -103,6 +103,8 @@ class ChannelPreview extends StatelessWidget { return '📷'; } else if (e.type == 'video') { return '🎬'; + } else if (e.type == 'giphy') { + return 'GIF'; } return null; }) diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 4db16f9d..08830143 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -218,7 +218,7 @@ class _MessageListViewState extends State { } Widget _buildBottomMessage( - StreamChannelState channel, + StreamChannelState streamChannel, Message previousMessage, Message message, BuildContext context, @@ -243,9 +243,9 @@ class _MessageListViewState extends State { key: ValueKey('BOTTOM-MESSAGE'), onVisibilityChanged: (visibility) { _isBottom = visibility.visibleBounds != Rect.zero; - if (_isBottom) { - if (channel.channel.state.unreadCount > 0) { - channel.channel.markRead(); + if (_isBottom && streamChannel.channel.config.readEvents) { + if (streamChannel.channel.state.unreadCount > 0) { + streamChannel.channel.markRead(); } } }, diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 5d499f6a..a715c2b6 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -42,12 +42,16 @@ class _MessageWidgetState extends State final Map _chuwieControllers = {}; MessageTheme messageTheme; + StreamChatState streamChat; + StreamChannelState streamChannel; @override Widget build(BuildContext context) { super.build(context); - final streamChat = StreamChat.of(context); + streamChat = StreamChat.of(context); + streamChannel = StreamChannel.of(context); + final currentUserId = streamChat.client.state.user.id; final messageUserId = widget.message.user.id; final previousUserId = widget.previousMessage?.user?.id; @@ -73,7 +77,9 @@ class _MessageWidgetState extends State isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ _buildBubble(context, isMyMessage, isLastUser), - _buildThreadIndicator(context, isMyMessage), + streamChannel.channel.config.replies + ? _buildThreadIndicator(context, isMyMessage) + : SizedBox(), isNextUser ? SizedBox() : _buildTimestamp(isMyMessage, alignment), ], ), @@ -287,12 +293,14 @@ class _MessageWidgetState extends State ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ - Align( - child: _buildReactions(isMyMessage), - alignment: isMyMessage - ? Alignment.centerLeft - : Alignment.centerRight, - ), + streamChannel.channel.config.reactions + ? Align( + child: _buildReactions(isMyMessage), + alignment: isMyMessage + ? Alignment.centerLeft + : Alignment.centerRight, + ) + : SizedBox(), Stack( overflow: Overflow.visible, children: [ @@ -346,6 +354,11 @@ class _MessageWidgetState extends State } void _showMessageBottomSheet(BuildContext context, bool isMyMessage) { + if (!streamChannel.channel.config.reactions && + !streamChannel.channel.config.replies) { + return; + } + showModalBottomSheet( clipBehavior: Clip.hardEdge, shape: RoundedRectangleBorder( @@ -367,47 +380,52 @@ class _MessageWidgetState extends State children: [ Container( color: Colors.black87, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: reactionToEmoji.keys.map((reactionType) { - final ownReactionIndex = widget.message.ownReactions - .indexWhere( - (reaction) => reaction.type == reactionType); - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - IconButton( - iconSize: fontSize + 10, - icon: Text( - reactionToEmoji[reactionType], - style: textStyle, - ), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction(reactionType); - } else { - sendReaction(reactionType); - } - }, - ), - ownReactionIndex != -1 - ? Padding( - padding: const EdgeInsets.only(bottom: 4.0), - child: Text( - widget.message - .ownReactions[ownReactionIndex].score - .toString(), - style: TextStyle(color: Colors.white), + child: streamChannel.channel.config.reactions + ? Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: reactionToEmoji.keys.map((reactionType) { + final ownReactionIndex = widget.message.ownReactions + .indexWhere((reaction) => + reaction.type == reactionType); + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + IconButton( + iconSize: fontSize + 10, + icon: Text( + reactionToEmoji[reactionType], + style: textStyle, ), - ) - : SizedBox(), - ], - ); - }).toList(), - ), + onPressed: () { + if (ownReactionIndex != -1) { + removeReaction(reactionType); + } else { + sendReaction(reactionType); + } + }, + ), + ownReactionIndex != -1 + ? Padding( + padding: + const EdgeInsets.only(bottom: 4.0), + child: Text( + widget + .message + .ownReactions[ownReactionIndex] + .score + .toString(), + style: TextStyle(color: Colors.white), + ), + ) + : SizedBox(), + ], + ); + }).toList(), + ) + : SizedBox(), ), isMyMessage ? FlatButton( @@ -429,19 +447,21 @@ class _MessageWidgetState extends State }, ) : SizedBox(), - FlatButton( - child: Padding( - padding: const EdgeInsets.all(28.0), - child: Text( - 'Start a thread', - style: Theme.of(context).textTheme.headline, - ), - ), - onPressed: () { - Navigator.pop(context); - widget.onThreadTap(widget.message); - }, - ), + streamChannel.channel.config.replies + ? FlatButton( + child: Padding( + padding: const EdgeInsets.all(28.0), + child: Text( + 'Start a thread', + style: Theme.of(context).textTheme.headline, + ), + ), + onPressed: () { + Navigator.pop(context); + widget.onThreadTap(widget.message); + }, + ) + : SizedBox(), ], ), ); @@ -502,16 +522,12 @@ class _MessageWidgetState extends State }; void sendReaction(String reactionType) { - StreamChannel.of(context) - .channel - .sendReaction(widget.message.id, reactionType); + streamChannel.channel.sendReaction(widget.message.id, reactionType); Navigator.of(context).pop(); } void removeReaction(String reactionType) { - StreamChannel.of(context) - .channel - .deleteReaction(widget.message.id, reactionType); + streamChannel.channel.deleteReaction(widget.message.id, reactionType); Navigator.of(context).pop(); } diff --git a/pubspec.yaml b/pubspec.yaml index 3ee0f8b4..3e45ea8b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,8 +18,7 @@ dependencies: url_launcher: ^5.4.1 video_player: ^0.10.7 chewie: ^0.9.8+1 - animations: ^1.0.0+3 - stream_chat: ^0.1.10 + stream_chat: ^0.1.11 dev_dependencies: pedantic: ^1.8.0+1 From 6e067b0d7984fc847781537e2b4b49c7344c3062 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 13:38:47 +0100 Subject: [PATCH 3/8] fix markdown text style --- lib/src/message_widget.dart | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index a715c2b6..e6ecf5e7 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -329,9 +329,21 @@ class _MessageWidgetState extends State onTapLink: (link) { _launchURL(link); }, - styleSheet: - MarkdownStyleSheet.fromTheme(Theme.of(context)) - .copyWith( + styleSheet: MarkdownStyleSheet.fromTheme( + Theme.of(context).copyWith( + textTheme: Theme.of(context).textTheme.apply( + bodyColor: messageTheme.messageText.color, + decoration: + messageTheme.messageText.decoration, + decorationColor: messageTheme + .messageText.decorationColor, + decorationStyle: messageTheme + .messageText.decorationStyle, + fontFamily: + messageTheme.messageText.fontFamily, + ), + ), + ).copyWith( p: messageTheme.messageText, ), ), From babf7b4beabdab06ecf9f84a94b1abb9d5537512 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 13:39:51 +0100 Subject: [PATCH 4/8] remove fontfamily from theme --- lib/src/stream_chat.dart | 2 -- lib/src/stream_chat_theme.dart | 8 -------- 2 files changed, 10 deletions(-) diff --git a/lib/src/stream_chat.dart b/lib/src/stream_chat.dart index c9b03f92..fddf42de 100644 --- a/lib/src/stream_chat.dart +++ b/lib/src/stream_chat.dart @@ -113,7 +113,6 @@ class StreamChatState extends State { messageText: themeData?.ownMessageTheme?.messageText, messageBackgroundColor: themeData?.ownMessageTheme?.messageBackgroundColor, - fontFamily: themeData?.ownMessageTheme?.fontFamily, messageAuthor: themeData?.ownMessageTheme?.messageAuthor, messageMention: themeData?.ownMessageTheme?.messageMention, avatarTheme: defaultTheme.ownMessageTheme.avatarTheme.copyWith( @@ -127,7 +126,6 @@ class StreamChatState extends State { messageText: themeData?.otherMessageTheme?.messageText, messageBackgroundColor: themeData?.otherMessageTheme?.messageBackgroundColor, - fontFamily: themeData?.otherMessageTheme?.fontFamily, messageAuthor: themeData?.otherMessageTheme?.messageAuthor, messageMention: themeData?.otherMessageTheme?.messageMention, avatarTheme: defaultTheme.otherMessageTheme.avatarTheme.copyWith( diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index bcd098c3..6deb8370 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -115,8 +115,6 @@ class StreamChatThemeData { createdAt: ownMessageTheme?.createdAt ?? this.ownMessageTheme.createdAt, replies: ownMessageTheme?.replies ?? this.ownMessageTheme.replies, - fontFamily: ownMessageTheme?.fontFamily ?? - this.ownMessageTheme.fontFamily, messageBackgroundColor: ownMessageTheme?.messageBackgroundColor ?? this.ownMessageTheme.messageBackgroundColor, avatarTheme: ownMessageTheme?.avatarTheme ?? @@ -134,8 +132,6 @@ class StreamChatThemeData { this.otherMessageTheme.createdAt, replies: otherMessageTheme?.replies ?? this.otherMessageTheme.replies, - fontFamily: otherMessageTheme?.fontFamily ?? - this.otherMessageTheme.fontFamily, messageBackgroundColor: otherMessageTheme?.messageBackgroundColor ?? this.otherMessageTheme.messageBackgroundColor, @@ -315,7 +311,6 @@ class MessageTheme { final TextStyle messageMention; final TextStyle createdAt; final TextStyle replies; - final String fontFamily; final Color messageBackgroundColor; final AvatarTheme avatarTheme; @@ -324,7 +319,6 @@ class MessageTheme { this.messageText, this.messageAuthor, this.messageMention, - this.fontFamily, this.messageBackgroundColor, this.avatarTheme, this.createdAt, @@ -336,7 +330,6 @@ class MessageTheme { TextStyle messageMention, TextStyle createdAt, TextStyle replies, - String fontFamily, Color messageBackgroundColor, Color otherMessageBackgroundColor, AvatarTheme avatarTheme, @@ -346,7 +339,6 @@ class MessageTheme { messageAuthor: messageAuthor ?? this.messageAuthor, messageMention: messageMention ?? this.messageMention, createdAt: createdAt ?? this.createdAt, - fontFamily: fontFamily ?? this.fontFamily, messageBackgroundColor: messageBackgroundColor ?? this.messageBackgroundColor, avatarTheme: avatarTheme ?? this.avatarTheme, From 7daf412b7db1f1e4e501be9ceb5577faf6e01d2a Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 14:16:01 +0100 Subject: [PATCH 5/8] add threadheader --- example/lib/custom_theme.dart | 3 ++ example/lib/threads.dart | 3 ++ lib/src/thread_header.dart | 87 +++++++++++++++++++++++++++++++++++ lib/stream_chat_flutter.dart | 1 + 4 files changed, 94 insertions(+) create mode 100644 lib/src/thread_header.dart diff --git a/example/lib/custom_theme.dart b/example/lib/custom_theme.dart index 26b66584..0f2a57d1 100644 --- a/example/lib/custom_theme.dart +++ b/example/lib/custom_theme.dart @@ -104,6 +104,9 @@ class ThreadPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( + appBar: ThreadHeader( + parent: parent, + ), body: Column( children: [ Expanded( diff --git a/example/lib/threads.dart b/example/lib/threads.dart index 20481baf..20f67f63 100644 --- a/example/lib/threads.dart +++ b/example/lib/threads.dart @@ -88,6 +88,9 @@ class ThreadPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( + appBar: ThreadHeader( + parent: parent, + ), body: Column( children: [ Expanded( diff --git a/lib/src/thread_header.dart b/lib/src/thread_header.dart new file mode 100644 index 00000000..3421fa0a --- /dev/null +++ b/lib/src/thread_header.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; + +import 'stream_channel.dart'; + +class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { + final bool showBackButton; + final VoidCallback onBackPressed; + final Message parent; + + ThreadHeader({ + Key key, + @required this.parent, + this.showBackButton = true, + this.onBackPressed, + }) : preferredSize = Size.fromHeight(kToolbarHeight), + super(key: key); + + @override + Widget build(BuildContext context) { + final channel = StreamChannel.of(context).channel; + return AppBar( + automaticallyImplyLeading: false, + elevation: 1, + backgroundColor: + StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, + actions: [ + Container( + child: showBackButton ? _buildBackButton(context) : Container(), + ), + ], + centerTitle: false, + title: Text.rich( + TextSpan( + text: 'Thread', + children: [ + TextSpan( + text: + ' ${parent.replyCount} ${parent.replyCount == 1 ? 'reply' : 'replies'}', + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .lastMessageAt, + ), + ], + ), + style: + StreamChatTheme.of(context).channelTheme.channelHeaderTheme.title, + ), + ); + } + + Padding _buildBackButton(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(14.0), + child: AspectRatio( + aspectRatio: 1, + child: RawMaterialButton( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + elevation: 0, + highlightElevation: 0, + focusElevation: 0, + disabledElevation: 0, + hoverElevation: 0, + onPressed: () { + if (onBackPressed != null) { + onBackPressed(); + } else { + Navigator.of(context).pop(); + } + }, + fillColor: Colors.black.withOpacity(.1), + padding: EdgeInsets.all(4), + child: Icon( + Icons.close, + size: 15, + color: Colors.black, + ), + ), + ), + ); + } + + @override + final Size preferredSize; +} diff --git a/lib/stream_chat_flutter.dart b/lib/stream_chat_flutter.dart index 1f164781..3c41b7f0 100644 --- a/lib/stream_chat_flutter.dart +++ b/lib/stream_chat_flutter.dart @@ -11,3 +11,4 @@ export 'src/message_widget.dart'; export 'src/stream_channel.dart'; export 'src/stream_chat.dart'; export 'src/stream_chat_theme.dart'; +export 'src/thread_header.dart'; From b595a343c1d7ae1c84048da96fffbe607b542eb6 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 14:16:26 +0100 Subject: [PATCH 6/8] version bump --- README.md | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77454051..3fb35e2f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ TODO ```yaml dependencies: - stream_chat_flutter: ^0.0.1 + stream_chat_flutter: ^0.1.0 ``` You should then run `flutter packages get` diff --git a/pubspec.yaml b/pubspec.yaml index 3e45ea8b..6f6b4caa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 0.0.1 +version: 0.1.0 environment: sdk: ">=2.1.0 <3.0.0" From f062b6bc4648471be63529966c4c65130a5e00bc Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 14:17:07 +0100 Subject: [PATCH 7/8] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de3bc7f..ec6022b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +- Add ThreadHeader + ## 0.0.1 - First release \ No newline at end of file From fdf9ca9df9e4c28432be2de812e8d2793b5ffcb1 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 28 Feb 2020 14:17:35 +0100 Subject: [PATCH 8/8] version bump --- CHANGELOG.md | 2 +- README.md | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6022b6..ef2bb9d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.1.0 +## 0.1.1 - Add ThreadHeader diff --git a/README.md b/README.md index 3fb35e2f..cf1dda04 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ TODO ```yaml dependencies: - stream_chat_flutter: ^0.1.0 + stream_chat_flutter: ^0.1.1 ``` You should then run `flutter packages get` diff --git a/pubspec.yaml b/pubspec.yaml index 6f6b4caa..3f13ea59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 0.1.0 +version: 0.1.1 environment: sdk: ">=2.1.0 <3.0.0"