diff --git a/packages/stream_chat_flutter/lib/src/message_actions_modal.dart b/packages/stream_chat_flutter/lib/src/message_actions_modal.dart index af05d74c..d914afba 100644 --- a/packages/stream_chat_flutter/lib/src/message_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/message_actions_modal.dart @@ -596,7 +596,8 @@ class _MessageActionsModalState extends State { elevation: 2, clipBehavior: Clip.hardEdge, isScrollControlled: true, - backgroundColor: StreamChatTheme.of(context).channelTheme.inputBackground, + backgroundColor: + StreamChatTheme.of(context).messageInputTheme.inputBackground, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(16), diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index 32d1eab8..ec6b9574 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -235,7 +235,7 @@ class MessageInputState extends State { @override Widget build(BuildContext context) { Widget child = Container( - color: StreamChatTheme.of(context).channelTheme.inputBackground, + color: StreamChatTheme.of(context).messageInputTheme.inputBackground, child: SafeArea( child: GestureDetector( onPanUpdate: (details) { @@ -392,7 +392,8 @@ class MessageInputState extends State { : CrossFadeState.showSecond, firstChild: _buildSendButton(context), secondChild: _buildIdleSendButton(context), - duration: Duration(milliseconds: 300), + duration: + StreamChatTheme.of(context).messageInputTheme.sendAnimationDuration, alignment: Alignment.center, ), ); @@ -1685,8 +1686,10 @@ class MessageInputState extends State { return IconButton( icon: StreamSvgIcon.lightning( color: _commandsOverlay != null - ? StreamChatTheme.of(context).channelTheme.actionButtonColor - : StreamChatTheme.of(context).channelTheme.actionButtonIdleColor, + ? StreamChatTheme.of(context).messageInputTheme.actionButtonColor + : StreamChatTheme.of(context) + .messageInputTheme + .actionButtonIdleColor, ), padding: const EdgeInsets.all(0), constraints: BoxConstraints.tightFor( @@ -1723,8 +1726,10 @@ class MessageInputState extends State { return IconButton( icon: StreamSvgIcon.attach( color: _openFilePickerSection - ? StreamChatTheme.of(context).channelTheme.actionButtonColor - : StreamChatTheme.of(context).channelTheme.actionButtonIdleColor, + ? StreamChatTheme.of(context).messageInputTheme.actionButtonColor + : StreamChatTheme.of(context) + .messageInputTheme + .actionButtonIdleColor, ), padding: const EdgeInsets.all(0), constraints: BoxConstraints.tightFor( @@ -1963,7 +1968,7 @@ class MessageInputState extends State { Widget _buildIdleSendButton(BuildContext context) { return StreamSvgIcon( assetName: _getIdleSendIcon(), - color: StreamChatTheme.of(context).channelTheme.sendButtonIdleColor, + color: StreamChatTheme.of(context).messageInputTheme.sendButtonIdleColor, ); } @@ -1978,7 +1983,7 @@ class MessageInputState extends State { ), icon: StreamSvgIcon( assetName: _getSendIcon(), - color: StreamChatTheme.of(context).channelTheme.sendButtonColor, + color: StreamChatTheme.of(context).messageInputTheme.sendButtonColor, ), ); } diff --git a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart index ef1008e3..338e2603 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart @@ -60,6 +60,9 @@ class StreamChatThemeData { /// Theme of other users messages final MessageTheme otherMessageTheme; + /// Theme of other users messages + final MessageInputTheme messageInputTheme; + /// The widget that will be built when the channel image is unavailable final Widget Function(BuildContext, Channel) defaultChannelImage; @@ -80,6 +83,7 @@ class StreamChatThemeData { this.channelTheme, this.otherMessageTheme, this.ownMessageTheme, + this.messageInputTheme, this.defaultChannelImage, this.defaultUserImage, this.primaryIconTheme, @@ -108,6 +112,7 @@ class StreamChatThemeData { ChannelTheme channelTheme, MessageTheme ownMessageTheme, MessageTheme otherMessageTheme, + MessageInputTheme messageInputTheme, Widget Function(BuildContext, Channel) defaultChannelImage, Widget Function(BuildContext, User) defaultUserImage, IconThemeData primaryIconTheme, @@ -123,6 +128,7 @@ class StreamChatThemeData { channelTheme: channelTheme ?? this.channelTheme, ownMessageTheme: ownMessageTheme ?? this.ownMessageTheme, otherMessageTheme: otherMessageTheme ?? this.otherMessageTheme, + messageInputTheme: messageInputTheme ?? this.messageInputTheme, reactionIcons: reactionIcons ?? this.reactionIcons, ); @@ -143,6 +149,8 @@ class StreamChatThemeData { other.ownMessageTheme, otherMessageTheme: otherMessageTheme?.merge(other.otherMessageTheme) ?? other.otherMessageTheme, + messageInputTheme: messageInputTheme?.merge(other.messageInputTheme) ?? + other.messageInputTheme, reactionIcons: other.reactionIcons, ); } @@ -182,10 +190,6 @@ class StreamChatThemeData { ), indicatorIconSize: 16.0), channelTheme: ChannelTheme( - actionButtonColor: colorTheme.accentBlue, - actionButtonIdleColor: colorTheme.grey, - sendButtonColor: colorTheme.accentBlue, - sendButtonIdleColor: colorTheme.greyGainsboro, channelHeaderTheme: ChannelHeaderTheme( avatarTheme: AvatarTheme( borderRadius: BorderRadius.circular(20), @@ -201,7 +205,6 @@ class StreamChatThemeData { color: colorTheme.black.withOpacity(.5), ), ), - inputBackground: colorTheme.white, ), ownMessageTheme: MessageTheme( messageAuthor: textTheme.footnote.copyWith(color: colorTheme.grey), @@ -245,6 +248,14 @@ class StreamChatThemeData { ), ), ), + messageInputTheme: MessageInputTheme( + sendAnimationDuration: Duration(milliseconds: 300), + actionButtonColor: colorTheme.accentBlue, + actionButtonIdleColor: colorTheme.grey, + sendButtonColor: colorTheme.accentBlue, + sendButtonIdleColor: colorTheme.greyGainsboro, + inputBackground: colorTheme.white, + ), reactionIcons: [ ReactionIcon( type: 'love', @@ -625,47 +636,16 @@ class ChannelTheme { /// Theme of the [ChannelHeader] widget final ChannelHeaderTheme channelHeaderTheme; - /// Background color of [MessageInput] send button - final Color sendButtonColor; - - /// Background color of [MessageInput] action buttons - final Color actionButtonColor; - - /// Background color of [MessageInput] send button - final Color sendButtonIdleColor; - - /// Background color of [MessageInput] action buttons - final Color actionButtonIdleColor; - - /// Background color of [MessageInput] - final Color inputBackground; - ChannelTheme({ this.channelHeaderTheme, - this.actionButtonColor, - this.sendButtonColor, - this.actionButtonIdleColor, - this.sendButtonIdleColor, - this.inputBackground, }); /// Creates a copy of [ChannelTheme] with specified attributes overridden. ChannelTheme copyWith({ ChannelHeaderTheme channelHeaderTheme, - Color inputBackground, - Color actionButtonColor, - Color sendButtonColor, - Color actionButtonIdleColor, - Color sendButtonIdleColor, }) => ChannelTheme( channelHeaderTheme: channelHeaderTheme ?? this.channelHeaderTheme, - inputBackground: inputBackground ?? this.inputBackground, - actionButtonColor: actionButtonColor ?? this.actionButtonColor, - sendButtonColor: sendButtonColor ?? this.sendButtonColor, - actionButtonIdleColor: - actionButtonIdleColor ?? this.actionButtonIdleColor, - sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor, ); ChannelTheme merge(ChannelTheme other) { @@ -673,11 +653,6 @@ class ChannelTheme { return copyWith( channelHeaderTheme: channelHeaderTheme?.merge(other.channelHeaderTheme) ?? other.channelHeaderTheme, - inputBackground: other.inputBackground, - actionButtonColor: other.actionButtonColor, - actionButtonIdleColor: other.actionButtonIdleColor, - sendButtonColor: other.sendButtonColor, - sendButtonIdleColor: other.sendButtonIdleColor, ); } } @@ -870,6 +845,65 @@ class ChannelHeaderTheme { } } +class MessageInputTheme { + final Duration sendAnimationDuration; + + /// Background color of [MessageInput] send button + final Color sendButtonColor; + + /// Background color of [MessageInput] action buttons + final Color actionButtonColor; + + /// Background color of [MessageInput] send button + final Color sendButtonIdleColor; + + /// Background color of [MessageInput] action buttons + final Color actionButtonIdleColor; + + /// Background color of [MessageInput] + final Color inputBackground; + + const MessageInputTheme({ + this.sendAnimationDuration, + this.actionButtonColor, + this.sendButtonColor, + this.actionButtonIdleColor, + this.sendButtonIdleColor, + this.inputBackground, + }); + + MessageInputTheme copyWith({ + Duration sendAnimationDuration, + Color inputBackground, + Color actionButtonColor, + Color sendButtonColor, + Color actionButtonIdleColor, + Color sendButtonIdleColor, + }) => + MessageInputTheme( + sendAnimationDuration: + sendAnimationDuration ?? this.sendAnimationDuration, + inputBackground: inputBackground ?? this.inputBackground, + actionButtonColor: actionButtonColor ?? this.actionButtonColor, + sendButtonColor: sendButtonColor ?? this.sendButtonColor, + actionButtonIdleColor: + actionButtonIdleColor ?? this.actionButtonIdleColor, + sendButtonIdleColor: sendButtonIdleColor ?? this.sendButtonIdleColor, + ); + + MessageInputTheme merge(MessageInputTheme other) { + if (other == null) return this; + return copyWith( + sendAnimationDuration: other.sendAnimationDuration, + inputBackground: other.inputBackground, + actionButtonColor: other.actionButtonColor, + actionButtonIdleColor: other.actionButtonIdleColor, + sendButtonColor: other.sendButtonColor, + sendButtonIdleColor: other.sendButtonIdleColor, + ); + } +} + class Effect { final double sigmaX; final double sigmaY;