Merge pull request #37 from GetStream/feature/channelHeaderOnTap

Feature/channel header on tap
This commit is contained in:
Salvatore Giordano
2020-04-20 12:27:00 +02:00
committed by GitHub
4 changed files with 89 additions and 47 deletions
+30 -16
View File
@@ -57,11 +57,19 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
/// By default it calls [Navigator.pop] /// By default it calls [Navigator.pop]
final VoidCallback onBackPressed; final VoidCallback onBackPressed;
/// Callback to call when the header is tapped.
final VoidCallback onTitleTap;
/// Callback to call when the image is tapped.
final VoidCallback onImageTap;
/// Creates a channel header /// Creates a channel header
ChannelHeader({ ChannelHeader({
Key key, Key key,
this.showBackButton = true, this.showBackButton = true,
this.onBackPressed, this.onBackPressed,
this.onTitleTap,
this.onImageTap,
}) : preferredSize = Size.fromHeight(kToolbarHeight), }) : preferredSize = Size.fromHeight(kToolbarHeight),
super(key: key); super(key: key);
@@ -76,27 +84,33 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
actions: <Widget>[ actions: <Widget>[
Padding( Padding(
padding: const EdgeInsets.only(right: 10.0), padding: const EdgeInsets.only(right: 10.0),
child: Stack( child: Center(
children: <Widget>[ child: ChannelImage(
Center( onTap: onImageTap,
child: ChannelImage(), ),
),
],
), ),
), ),
], ],
centerTitle: true, centerTitle: true,
title: Column( title: InkWell(
crossAxisAlignment: CrossAxisAlignment.center, onTap: onTitleTap,
children: <Widget>[ child: Container(
ChannelName( height: preferredSize.height,
textStyle: StreamChatTheme.of(context) width: preferredSize.width,
.channelTheme child: Column(
.channelHeaderTheme crossAxisAlignment: CrossAxisAlignment.center,
.title, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ChannelName(
textStyle: StreamChatTheme.of(context)
.channelTheme
.channelHeaderTheme
.title,
),
_buildLastActive(context, channel),
],
), ),
_buildLastActive(context, channel), ),
],
), ),
); );
} }
+34 -19
View File
@@ -47,6 +47,7 @@ class ChannelImage extends StatelessWidget {
Key key, Key key,
this.channel, this.channel,
this.constraints, this.constraints,
this.onTap,
}) : super(key: key); }) : super(key: key);
/// The channel to show the image of /// The channel to show the image of
@@ -55,6 +56,9 @@ class ChannelImage extends StatelessWidget {
/// The diameter of the image /// The diameter of the image
final BoxConstraints constraints; final BoxConstraints constraints;
/// The function called when the image is tapped
final VoidCallback onTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final client = StreamChat.of(context); final client = StreamChat.of(context);
@@ -86,25 +90,36 @@ class ChannelImage extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: StreamChatTheme.of(context).accentColor, color: StreamChatTheme.of(context).accentColor,
), ),
child: image != null child: Stack(
? CachedNetworkImage( fit: StackFit.expand,
imageUrl: image, children: <Widget>[
errorWidget: (_, __, ___) { image != null
return Center( ? CachedNetworkImage(
child: Text( imageUrl: image,
snapshot.data?.containsKey('name') ?? false errorWidget: (_, __, ___) {
? snapshot.data['name'][0] return Center(
: '', child: Text(
style: TextStyle( snapshot.data?.containsKey('name') ?? false
color: Colors.white, ? snapshot.data['name'][0]
fontWeight: FontWeight.bold, : '',
), style: TextStyle(
), color: Colors.white,
); fontWeight: FontWeight.bold,
}, ),
fit: BoxFit.cover, ),
) );
: SizedBox(), },
fit: BoxFit.cover,
)
: SizedBox(),
Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
),
),
],
),
), ),
); );
}); });
+18 -11
View File
@@ -56,6 +56,7 @@ class ChannelListView extends StatefulWidget {
this.channelWidget, this.channelWidget,
this.channelPreviewBuilder, this.channelPreviewBuilder,
this.errorBuilder, this.errorBuilder,
this.onImageTap,
}) : super(key: key); }) : super(key: key);
final Widget Function(Error error) errorBuilder; final Widget Function(Error error) errorBuilder;
@@ -94,6 +95,9 @@ class ChannelListView extends StatefulWidget {
/// Builder used to create a custom channel preview /// Builder used to create a custom channel preview
final ChannelPreviewBuilder channelPreviewBuilder; final ChannelPreviewBuilder channelPreviewBuilder;
/// The function called when the image is tapped
final Function(Channel) onImageTap;
@override @override
_ChannelListViewState createState() => _ChannelListViewState(); _ChannelListViewState createState() => _ChannelListViewState();
} }
@@ -215,8 +219,6 @@ class _ChannelListViewState extends State<ChannelListView> {
if (i < channels.length) { if (i < channels.length) {
final channel = channels[i]; final channel = channels[i];
final channelClient = streamChat.client.channels[channel.cid];
ChannelTapCallback onTap; ChannelTapCallback onTap;
if (widget.onChannelTap != null) { if (widget.onChannelTap != null) {
onTap = widget.onChannelTap; onTap = widget.onChannelTap;
@@ -237,11 +239,11 @@ class _ChannelListViewState extends State<ChannelListView> {
} }
return StreamChannel( return StreamChannel(
key: ValueKey<String>('CHANNEL-${channelClient.id}'), key: ValueKey<String>('CHANNEL-${channel.id}'),
channel: channelClient, channel: channel,
child: StreamBuilder<DateTime>( child: StreamBuilder<DateTime>(
initialData: channelClient.updatedAt, initialData: channel.updatedAt,
stream: channelClient.updatedAtStream, stream: channel.updatedAtStream,
builder: (context, snapshot) { builder: (context, snapshot) {
Widget child; Widget child;
if (widget.channelPreviewBuilder != null) { if (widget.channelPreviewBuilder != null) {
@@ -249,14 +251,14 @@ class _ChannelListViewState extends State<ChannelListView> {
children: [ children: [
widget.channelPreviewBuilder( widget.channelPreviewBuilder(
context, context,
channelClient, channel,
), ),
Positioned.fill( Positioned.fill(
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
onTap(channelClient, widget.channelWidget); onTap(channel, widget.channelWidget);
}, },
), ),
), ),
@@ -265,9 +267,14 @@ class _ChannelListViewState extends State<ChannelListView> {
); );
} else { } else {
child = ChannelPreview( child = ChannelPreview(
channel: channelClient, channel: channel,
onTap: (channelClient) { onImageTap: widget.onImageTap != null
onTap(channelClient, widget.channelWidget); ? () {
widget.onImageTap(channel);
}
: null,
onTap: (channel) {
onTap(channel, widget.channelWidget);
}, },
); );
} }
+7 -1
View File
@@ -25,10 +25,14 @@ class ChannelPreview extends StatelessWidget {
/// Channel displayed /// Channel displayed
final Channel channel; final Channel channel;
/// The function called when the image is tapped
final VoidCallback onImageTap;
ChannelPreview({ ChannelPreview({
@required this.channel, @required this.channel,
Key key, Key key,
this.onTap, this.onTap,
this.onImageTap,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -37,7 +41,9 @@ class ChannelPreview extends StatelessWidget {
onTap: () { onTap: () {
onTap(channel); onTap(channel);
}, },
leading: ChannelImage(), leading: ChannelImage(
onTap: onImageTap,
),
title: ChannelName( title: ChannelName(
textStyle: StreamChatTheme.of(context).channelPreviewTheme.title, textStyle: StreamChatTheme.of(context).channelPreviewTheme.title,
), ),