From f90fd713c20844341cc086eb78056f7606286c7a Mon Sep 17 00:00:00 2001 From: groovinchip Date: Tue, 27 Jul 2021 10:32:49 -0400 Subject: [PATCH] chore: upgrade AvatarTheme * `AvatarTheme` is now an `InheritedTheme` and has a corresponding `AvatarThemeData` class --- .../example/lib/tutorial_part_6.dart | 4 +- .../lib/src/stream_chat_theme.dart | 23 +++- .../lib/src/theme/avatar_theme.dart | 113 +++++++++++++++--- .../lib/src/theme/channel_header_theme.dart | 4 +- .../src/theme/channel_list_header_theme.dart | 4 +- .../lib/src/theme/channel_preview_theme.dart | 4 +- .../lib/src/theme/gallery_header_theme.dart | 2 +- .../lib/src/theme/message_theme.dart | 4 +- 8 files changed, 127 insertions(+), 31 deletions(-) diff --git a/packages/stream_chat_flutter/example/lib/tutorial_part_6.dart b/packages/stream_chat_flutter/example/lib/tutorial_part_6.dart index cf94b568..1cf34d27 100644 --- a/packages/stream_chat_flutter/example/lib/tutorial_part_6.dart +++ b/packages/stream_chat_flutter/example/lib/tutorial_part_6.dart @@ -59,7 +59,7 @@ class MyApp extends StatelessWidget { final colorTheme = defaultTheme.colorTheme; final customTheme = defaultTheme.merge(StreamChatThemeData( channelPreviewTheme: ChannelPreviewTheme( - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(8), ), ), @@ -68,7 +68,7 @@ class MyApp extends StatelessWidget { messageText: TextStyle( color: colorTheme.barsBg, ), - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(8), ), ), 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 4336325b..d2eb0df0 100644 --- a/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart +++ b/packages/stream_chat_flutter/lib/src/stream_chat_theme.dart @@ -62,6 +62,7 @@ class StreamChatThemeData { ChannelListViewThemeData? channelListViewTheme, UserListViewThemeData? userListViewTheme, MessageSearchListViewThemeData? messageSearchListViewTheme, + AvatarThemeData? avatarTheme, }) { brightness ??= colorTheme?.brightness ?? Brightness.light; final isDark = brightness == Brightness.dark; @@ -89,6 +90,7 @@ class StreamChatThemeData { channelListViewTheme: channelListViewTheme, userListViewTheme: userListViewTheme, messageSearchListViewTheme: messageSearchListViewTheme, + avatarTheme: avatarTheme, ); return defaultData.merge(customizedData); @@ -121,6 +123,7 @@ class StreamChatThemeData { required this.channelListViewTheme, required this.userListViewTheme, required this.messageSearchListViewTheme, + required this.avatarTheme, }); /// Create a theme from a Material [Theme] @@ -188,6 +191,9 @@ class StreamChatThemeData { /// Theme configuration for the [] widget. final MessageSearchListViewThemeData messageSearchListViewTheme; + /// Theme configuration for the [] widget. + final AvatarThemeData avatarTheme; + /// Creates a copy of [StreamChatThemeData] with specified attributes /// overridden. StreamChatThemeData copyWith({ @@ -208,6 +214,7 @@ class StreamChatThemeData { ChannelListViewThemeData? channelListViewTheme, UserListViewThemeData? userListViewTheme, MessageSearchListViewThemeData? messageSearchListViewTheme, + AvatarThemeData? avatarTheme, }) => StreamChatThemeData.raw( channelListHeaderTheme: @@ -230,6 +237,7 @@ class StreamChatThemeData { userListViewTheme: userListViewTheme ?? this.userListViewTheme, messageSearchListViewTheme: messageSearchListViewTheme ?? this.messageSearchListViewTheme, + avatarTheme: avatarTheme ?? this.avatarTheme, ); /// Merge themes @@ -257,6 +265,7 @@ class StreamChatThemeData { userListViewTheme: userListViewTheme.merge(other.userListViewTheme), messageSearchListViewTheme: messageSearchListViewTheme.merge(other.messageSearchListViewTheme), + avatarTheme: avatarTheme.merge(other.avatarTheme), ); } @@ -271,7 +280,7 @@ class StreamChatThemeData { IconThemeData(color: colorTheme.textHighEmphasis.withOpacity(.5)); final channelTheme = ChannelTheme( channelHeaderTheme: ChannelHeaderTheme( - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(20), constraints: const BoxConstraints.tightFor( height: 40, @@ -287,7 +296,7 @@ class StreamChatThemeData { ); final channelPreviewTheme = ChannelPreviewTheme( unreadCounterColor: colorTheme.accentError, - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(20), constraints: const BoxConstraints.tightFor( height: 40, @@ -315,7 +324,7 @@ class StreamChatThemeData { ), channelPreviewTheme: channelPreviewTheme, channelListHeaderTheme: ChannelListHeaderTheme( - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(20), constraints: const BoxConstraints.tightFor( height: 40, @@ -338,7 +347,7 @@ class StreamChatThemeData { reactionsBorderColor: colorTheme.borders, reactionsMaskColor: colorTheme.appBg, messageBorderColor: colorTheme.disabled, - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(20), constraints: const BoxConstraints.tightFor( height: 32, @@ -364,7 +373,7 @@ class StreamChatThemeData { ), messageBackgroundColor: colorTheme.barsBg, messageBorderColor: colorTheme.borders, - avatarTheme: AvatarTheme( + avatarTheme: AvatarThemeData( borderRadius: BorderRadius.circular(20), constraints: const BoxConstraints.tightFor( height: 32, @@ -487,7 +496,9 @@ class StreamChatThemeData { messageSearchListViewTheme: MessageSearchListViewThemeData( backgroundColor: colorTheme.appBg, ), + avatarTheme: AvatarThemeData( + borderRadius: BorderRadius.circular(8), + ), ); } } - diff --git a/packages/stream_chat_flutter/lib/src/theme/avatar_theme.dart b/packages/stream_chat_flutter/lib/src/theme/avatar_theme.dart index f3e68597..873bd259 100644 --- a/packages/stream_chat_flutter/lib/src/theme/avatar_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/avatar_theme.dart @@ -1,9 +1,62 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/theme/themes.dart'; -/// Theme for avatar -class AvatarTheme { - /// Constructor for creating [AvatarTheme] - AvatarTheme({ +/// Overrides the default style of [UserAvatar] descendants. +/// +/// See also: +/// +/// * [AvatarThemeData], which is used to configure this theme. +class AvatarTheme extends InheritedTheme { + /// Creates an [AvatarTheme]. + /// + /// The [data] parameter must not be null. + const AvatarTheme({ + Key? key, + required this.data, + required Widget child, + }) : super(key: key, child: child); + + /// The configuration of this theme. + final AvatarThemeData data; + + /// The closest instance of this class that encloses the given context. + /// + /// If there is no enclosing [GalleryHeaderTheme] widget, then + /// [StreamChatThemeData.avatarTheme] is used. + /// + /// Typical usage is as follows: + /// + /// ```dart + /// final theme = AvatarTheme.of(context); + /// ``` + static AvatarThemeData of(BuildContext context) { + final avatarTheme = + context.dependOnInheritedWidgetOfExactType(); + return avatarTheme?.data ?? StreamChatTheme.of(context).avatarTheme; + } + + @override + Widget wrap(BuildContext context, Widget child) => + AvatarTheme(data: data, child: child); + + @override + bool updateShouldNotify(AvatarTheme oldWidget) => data != oldWidget.data; +} + +/// A style that overrides the default appearance of [UserAvatar]s when used +/// with [AvatarTheme] or with the overall [StreamChatTheme]'s +/// [StreamChatThemeData.avatarTheme]. +/// +/// See also: +/// +/// * [AvatarTheme], the theme which is configured with this class. +/// * [StreamChatThemeData.avatarTheme], which can be used to override +/// the default style for [UserAvatar]s below the overall [StreamChatTheme]. +class AvatarThemeData with Diagnosticable { + /// Creates an [AvatarThemeData]. + AvatarThemeData({ BoxConstraints? constraints, BorderRadius? borderRadius, }) : _constraints = constraints, @@ -15,30 +68,62 @@ class AvatarTheme { /// Get constraints for avatar BoxConstraints get constraints => _constraints ?? - const BoxConstraints.tightFor( - height: 32, - width: 32, - ); + const BoxConstraints.tightFor( + height: 32, + width: 32, + ); /// Get border radius BorderRadius get borderRadius => _borderRadius ?? BorderRadius.circular(20); - /// Copy with another theme - AvatarTheme copyWith({ + /// Copy this [AvatarThemeData] to another. + AvatarThemeData copyWith({ BoxConstraints? constraints, BorderRadius? borderRadius, }) => - AvatarTheme( + AvatarThemeData( constraints: constraints ?? _constraints, borderRadius: borderRadius ?? _borderRadius, ); - /// Merge with another AvatarTheme - AvatarTheme merge(AvatarTheme? other) { + /// Linearly interpolate between two [UserAvatar] themes. + /// + /// All the properties must be non-null. + AvatarThemeData lerp( + AvatarThemeData a, + AvatarThemeData b, + double t, + ) => + AvatarThemeData( + borderRadius: BorderRadius.lerp(a.borderRadius, b.borderRadius, t), + constraints: BoxConstraints.lerp(a.constraints, b.constraints, t), + ); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is AvatarThemeData && + runtimeType == other.runtimeType && + _constraints == other._constraints && + _borderRadius == other._borderRadius; + + @override + int get hashCode => _constraints.hashCode ^ _borderRadius.hashCode; + + /// Merges one [AvatarThemeData] with the another + AvatarThemeData merge(AvatarThemeData? other) { if (other == null) return this; return copyWith( constraints: other._constraints, borderRadius: other._borderRadius, ); } -} \ No newline at end of file + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('borderRadius', borderRadius)) + ..add(DiagnosticsProperty('constraints', constraints)); + } +} diff --git a/packages/stream_chat_flutter/lib/src/theme/channel_header_theme.dart b/packages/stream_chat_flutter/lib/src/theme/channel_header_theme.dart index 2072b3c5..be1d0347 100644 --- a/packages/stream_chat_flutter/lib/src/theme/channel_header_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/channel_header_theme.dart @@ -18,7 +18,7 @@ class ChannelHeaderTheme { final TextStyle? subtitle; /// Theme for avatar - final AvatarTheme? avatarTheme; + final AvatarThemeData? avatarTheme; /// Color for [ChannelHeaderTheme] final Color? color; @@ -27,7 +27,7 @@ class ChannelHeaderTheme { ChannelHeaderTheme copyWith({ TextStyle? title, TextStyle? subtitle, - AvatarTheme? avatarTheme, + AvatarThemeData? avatarTheme, Color? color, }) => ChannelHeaderTheme( diff --git a/packages/stream_chat_flutter/lib/src/theme/channel_list_header_theme.dart b/packages/stream_chat_flutter/lib/src/theme/channel_list_header_theme.dart index ca36b9bd..8b5984bd 100644 --- a/packages/stream_chat_flutter/lib/src/theme/channel_list_header_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/channel_list_header_theme.dart @@ -14,7 +14,7 @@ class ChannelListHeaderTheme { final TextStyle? title; /// Theme dedicated to the userAvatar - final AvatarTheme? avatarTheme; + final AvatarThemeData? avatarTheme; /// Background color of the appbar final Color? color; @@ -22,7 +22,7 @@ class ChannelListHeaderTheme { /// Returns a new [ChannelListHeaderTheme] replacing some of its properties ChannelListHeaderTheme copyWith({ TextStyle? title, - AvatarTheme? avatarTheme, + AvatarThemeData? avatarTheme, Color? color, }) => ChannelListHeaderTheme( diff --git a/packages/stream_chat_flutter/lib/src/theme/channel_preview_theme.dart b/packages/stream_chat_flutter/lib/src/theme/channel_preview_theme.dart index 4643bb8d..61975b3f 100644 --- a/packages/stream_chat_flutter/lib/src/theme/channel_preview_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/channel_preview_theme.dart @@ -23,7 +23,7 @@ class ChannelPreviewTheme { final TextStyle? lastMessageAt; /// Avatar theme - final AvatarTheme? avatarTheme; + final AvatarThemeData? avatarTheme; /// Unread counter color final Color? unreadCounterColor; @@ -36,7 +36,7 @@ class ChannelPreviewTheme { TextStyle? title, TextStyle? subtitle, TextStyle? lastMessageAt, - AvatarTheme? avatarTheme, + AvatarThemeData? avatarTheme, Color? unreadCounterColor, double? indicatorIconSize, }) => diff --git a/packages/stream_chat_flutter/lib/src/theme/gallery_header_theme.dart b/packages/stream_chat_flutter/lib/src/theme/gallery_header_theme.dart index 9b5faa83..611a77bc 100644 --- a/packages/stream_chat_flutter/lib/src/theme/gallery_header_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/gallery_header_theme.dart @@ -8,7 +8,7 @@ import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; /// /// * [GalleryHeaderThemeData], which is used to configure this theme. class GalleryHeaderTheme extends InheritedTheme { - /// Creates an [GalleryHeaderTheme]. + /// Creates a [GalleryHeaderTheme]. /// /// The [data] parameter must not be null. const GalleryHeaderTheme({ diff --git a/packages/stream_chat_flutter/lib/src/theme/message_theme.dart b/packages/stream_chat_flutter/lib/src/theme/message_theme.dart index 87543cb1..e9deb1f4 100644 --- a/packages/stream_chat_flutter/lib/src/theme/message_theme.dart +++ b/packages/stream_chat_flutter/lib/src/theme/message_theme.dart @@ -49,7 +49,7 @@ class MessageTheme { final Color? reactionsMaskColor; /// Theme of the avatar - final AvatarTheme? avatarTheme; + final AvatarThemeData? avatarTheme; /// Copy with a theme MessageTheme copyWith({ @@ -60,7 +60,7 @@ class MessageTheme { TextStyle? replies, Color? messageBackgroundColor, Color? messageBorderColor, - AvatarTheme? avatarTheme, + AvatarThemeData? avatarTheme, Color? reactionsBackgroundColor, Color? reactionsBorderColor, Color? reactionsMaskColor,