import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/group_image.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/channel_image.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/channel_image_paint.png) /// /// It shows the current [Channel] image. /// /// ```dart /// class MyApp extends StatelessWidget { /// final Client client; /// final Channel channel; /// /// MyApp(this.client, this.channel); /// /// @override /// Widget build(BuildContext context) { /// return MaterialApp( /// debugShowCheckedModeBanner: false, /// home: StreamChat( /// client: client, /// child: StreamChannel( /// channel: channel, /// child: Center( /// child: ChannelImage( /// channel: channel, /// ), /// ), /// ), /// ), /// ); /// } /// } /// ``` /// /// The widget uses a [StreamBuilder] to render the channel information image as soon as it updates. /// /// By default the widget radius size is 40x40 pixels. /// Set the property [constraints] to set a custom dimension. /// /// The widget renders the ui based on the first ancestor of type [StreamChatTheme]. /// Modify it to change the widget appearance. class ChannelImage extends StatelessWidget { /// Instantiate a new ChannelImage const ChannelImage({ Key key, this.channel, this.constraints, this.onTap, this.showOnlineStatus = true, this.borderRadius, }) : super(key: key); final BorderRadius borderRadius; /// The channel to show the image of final Channel channel; /// The diameter of the image final BoxConstraints constraints; /// The function called when the image is tapped final VoidCallback onTap; final bool showOnlineStatus; @override Widget build(BuildContext context) { final streamChat = StreamChat.of(context); final channel = this.channel ?? StreamChannel.of(context).channel; return StreamBuilder>( stream: channel.extraDataStream, initialData: channel.extraData, builder: (context, snapshot) { String image; if (snapshot.data?.containsKey('image') == true) { image = snapshot.data['image']; } else if (channel.state.members?.length == 2) { final otherMember = channel.state.members .firstWhere((member) => member.user.id != streamChat.user.id); return StreamBuilder( stream: streamChat.client.state.usersStream .map((users) => users[otherMember.userId]), initialData: otherMember.user, builder: (context, snapshot) { return UserAvatar( borderRadius: borderRadius, user: snapshot.data ?? otherMember.user, constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme .avatarTheme .constraints, onTap: onTap != null ? (_) { onTap(); } : null, ); }); } else { final images = channel.state.members .where((member) => member.user.id != streamChat.user.id && member.user.extraData['image'] != null) .take(4) .map((e) => e.user.extraData['image'] as String) .toList(); return GroupImage( images: images, constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme .avatarTheme .constraints, onTap: onTap, ); } return ClipRRect( borderRadius: borderRadius ?? StreamChatTheme.of(context) .channelPreviewTheme .avatarTheme .borderRadius, child: Container( constraints: constraints ?? StreamChatTheme.of(context) .channelPreviewTheme .avatarTheme .constraints, decoration: BoxDecoration( color: StreamChatTheme.of(context).accentColor, ), child: Stack( alignment: Alignment.center, fit: StackFit.expand, children: [ image != null ? CachedNetworkImage( imageUrl: image, errorWidget: (_, __, ___) { return Center( child: Text( snapshot.data?.containsKey('name') ?? false ? snapshot.data['name'][0] : '', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ); }, fit: BoxFit.cover, ) : StreamChatTheme.of(context) .defaultChannelImage(context, channel), Material( color: Colors.transparent, child: InkWell( onTap: onTap, ), ), ], ), ), ); }); } }