Merge pull request #1623 from GetStream/feat/channel-avatar-builders

feat(ui): add support for builder to override avatars in StreamChannelAvatar.
This commit is contained in:
Sahil Kumar
2023-06-19 15:41:34 +05:30
committed by GitHub
4 changed files with 99 additions and 18 deletions
+28
View File
@@ -52,6 +52,34 @@
) )
``` ```
- Added support for `StreamChannelAvatar.ownSpaceAvatarBuilder`, `StreamChannelAvatar.oneToOneAvatarBuilder` and
`StreamChannelAvatar.groupAvatarBuilder` to override the default avatar
widget.[#1614](https://github.com/GetStream/stream-chat-flutter/issues/1614)
```dart
StreamChannelAvatar(
...,
ownSpaceAvatarBuilder: (context, channel) {
return Container(
color: Colors.red,
child: Text('Own Space Avatar'),
);
},
oneToOneAvatarBuilder: (context, channel) {
return Container(
color: Colors.red,
child: Text('One to One Avatar'),
);
},
groupAvatarBuilder: (context, channel) {
return Container(
color: Colors.red,
child: Text('Group Avatar'),
);
},
)
```
## 6.3.0 ## 6.3.0
🐞 Fixed 🐞 Fixed
@@ -1,6 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// WidgetBuilder for [StreamGroupAvatar].
typedef StreamGroupAvatarBuilder = Widget Function(
BuildContext context,
List<Member> members,
// ignore: avoid_positional_boolean_parameters
bool isSelected,
);
/// {@template streamGroupAvatar} /// {@template streamGroupAvatar}
/// Widget for constructing a group of images /// Widget for constructing a group of images
/// {@endtemplate} /// {@endtemplate}
@@ -2,6 +2,14 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
/// WidgetBuilder for [StreamUserAvatar].
typedef StreamUserAvatarBuilder = Widget Function(
BuildContext context,
User user,
// ignore: avoid_positional_boolean_parameters
bool isSelected,
);
/// {@template streamUserAvatar} /// {@template streamUserAvatar}
/// Displays a user's avatar. /// Displays a user's avatar.
/// {@endtemplate} /// {@endtemplate}
@@ -54,6 +54,9 @@ class StreamChannelAvatar extends StatelessWidget {
this.selected = false, this.selected = false,
this.selectionColor, this.selectionColor,
this.selectionThickness = 4, this.selectionThickness = 4,
this.ownSpaceAvatarBuilder,
this.oneToOneAvatarBuilder,
this.groupAvatarBuilder,
}) : assert( }) : assert(
channel.state != null, channel.state != null,
'Channel ${channel.id} is not initialized', 'Channel ${channel.id} is not initialized',
@@ -80,6 +83,21 @@ class StreamChannelAvatar extends StatelessWidget {
/// Thickness of selection image /// Thickness of selection image
final double selectionThickness; final double selectionThickness;
/// Builder to create avatar for own space channel.
///
/// Defaults to [StreamUserAvatar].
final StreamUserAvatarBuilder? ownSpaceAvatarBuilder;
/// Builder to create avatar for one to one channel.
///
/// Defaults to [StreamUserAvatar].
final StreamUserAvatarBuilder? oneToOneAvatarBuilder;
/// Builder to create avatar for group channel.
///
/// Defaults to [StreamGroupAvatar].
final StreamGroupAvatarBuilder? groupAvatarBuilder;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final client = channel.client.state; final client = channel.client.state;
@@ -146,15 +164,22 @@ class StreamChannelAvatar extends StatelessWidget {
return BetterStreamBuilder<User>( return BetterStreamBuilder<User>(
stream: client.currentUserStream.map((it) => it!), stream: client.currentUserStream.map((it) => it!),
initialData: currentUser, initialData: currentUser,
builder: (context, user) => StreamUserAvatar( builder: (context, user) {
borderRadius: borderRadius ?? previewTheme?.borderRadius, final ownSpaceBuilder = ownSpaceAvatarBuilder;
user: user, if (ownSpaceBuilder != null) {
constraints: constraints ?? previewTheme?.constraints, return ownSpaceBuilder(context, user, selected);
onTap: onTap != null ? (_) => onTap!() : null, }
selected: selected,
selectionColor: selectionColor ?? colorTheme.accentPrimary, return StreamUserAvatar(
selectionThickness: selectionThickness, borderRadius: borderRadius ?? previewTheme?.borderRadius,
), user: user,
constraints: constraints ?? previewTheme?.constraints,
onTap: onTap != null ? (_) => onTap!() : null,
selected: selected,
selectionColor: selectionColor ?? colorTheme.accentPrimary,
selectionThickness: selectionThickness,
);
},
); );
} }
@@ -169,18 +194,30 @@ class StreamChannelAvatar extends StatelessWidget {
), ),
), ),
initialData: member, initialData: member,
builder: (context, member) => StreamUserAvatar( builder: (context, member) {
borderRadius: borderRadius ?? previewTheme?.borderRadius, final oneToOneBuilder = oneToOneAvatarBuilder;
user: member.user!, if (oneToOneBuilder != null) {
constraints: constraints ?? previewTheme?.constraints, return oneToOneBuilder(context, member.user!, selected);
onTap: onTap != null ? (_) => onTap!() : null, }
selected: selected,
selectionColor: selectionColor ?? colorTheme.accentPrimary, return StreamUserAvatar(
selectionThickness: selectionThickness, borderRadius: borderRadius ?? previewTheme?.borderRadius,
), user: member.user!,
constraints: constraints ?? previewTheme?.constraints,
onTap: onTap != null ? (_) => onTap!() : null,
selected: selected,
selectionColor: selectionColor ?? colorTheme.accentPrimary,
selectionThickness: selectionThickness,
);
},
); );
} }
final groupBuilder = groupAvatarBuilder;
if (groupBuilder != null) {
return groupBuilder(context, otherMembers, selected);
}
// Group conversation // Group conversation
return StreamGroupAvatar( return StreamGroupAvatar(
channel: channel, channel: channel,