From 1e8fbd285408c70f39781704d76665c0671b5d42 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 25 Aug 2020 11:07:29 +0200 Subject: [PATCH 1/2] add pullToRefresh property to ChannelListView --- lib/src/channel_list_view.dart | 176 ++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 81 deletions(-) diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 231e1ba9..b0f39ea6 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -60,6 +60,7 @@ class ChannelListView extends StatefulWidget { this.channelPreviewBuilder, this.errorBuilder, this.onImageTap, + this.pullToRefresh = true, }) : super(key: key); /// The builder that will be used in case of error @@ -105,6 +106,9 @@ class ChannelListView extends StatefulWidget { /// The function called when the image is tapped final Function(Channel) onImageTap; + /// Set it to false to disable the pull-to-refresh widget + final bool pullToRefresh; + @override _ChannelListViewState createState() => _ChannelListViewState(); } @@ -115,105 +119,115 @@ class _ChannelListViewState extends State @override Widget build(BuildContext context) { - final channelsProvider = ChannelsBloc.of(context); + final channelsBloc = ChannelsBloc.of(context); + + if (!widget.pullToRefresh) { + return _buildListView(channelsBloc); + } return RefreshIndicator( onRefresh: () async { - return channelsProvider.queryChannels( + return channelsBloc.queryChannels( filter: widget.filter, sortOptions: widget.sort, paginationParams: widget.pagination, options: widget.options, ); }, - child: StreamBuilder>( - stream: channelsProvider.channelsStream, - builder: (context, snapshot) { - if (snapshot.hasError) { - if (snapshot.error is Error) { - print((snapshot.error as Error).stackTrace); - } + child: _buildListView(channelsBloc), + ); + } - if (widget.errorBuilder != null) { - return widget.errorBuilder(snapshot.error); - } + StreamBuilder> _buildListView( + ChannelsBlocState channelsBlocState, + ) { + return StreamBuilder>( + stream: channelsBlocState.channelsStream, + builder: (context, snapshot) { + if (snapshot.hasError) { + if (snapshot.error is Error) { + print((snapshot.error as Error).stackTrace); + } - var message = snapshot.error.toString(); - if (snapshot.error is DioError) { - final dioError = snapshot.error as DioError; - if (dioError.type == DioErrorType.RESPONSE) { - message = dioError.message; - } else { - message = 'Check your connection and retry'; - } + if (widget.errorBuilder != null) { + return widget.errorBuilder(snapshot.error); + } + + var message = snapshot.error.toString(); + if (snapshot.error is DioError) { + final dioError = snapshot.error as DioError; + if (dioError.type == DioErrorType.RESPONSE) { + message = dioError.message; + } else { + message = 'Check your connection and retry'; } - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text.rich( - TextSpan( - children: [ - WidgetSpan( - child: Padding( - padding: const EdgeInsets.only( - right: 2.0, - ), - child: Icon(Icons.error_outline), + } + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Padding( + padding: const EdgeInsets.only( + right: 2.0, ), + child: Icon(Icons.error_outline), ), - TextSpan(text: 'Error loading channels'), - ], - ), - style: Theme.of(context).textTheme.headline6, + ), + TextSpan(text: 'Error loading channels'), + ], ), - Padding( - padding: const EdgeInsets.only( - top: 16.0, - ), - child: Text(message), + style: Theme.of(context).textTheme.headline6, + ), + Padding( + padding: const EdgeInsets.only( + top: 16.0, ), - FlatButton( - onPressed: () { - channelsProvider.queryChannels( - filter: widget.filter, - sortOptions: widget.sort, - paginationParams: widget.pagination, - options: widget.options, - ); - }, - child: Text('Retry'), - ), - ], - ), - ); - } - - if (!snapshot.hasData) { - return Center( - child: CircularProgressIndicator(), - ); - } - - final channels = snapshot.data; - return ListView.custom( - physics: AlwaysScrollableScrollPhysics(), - controller: _scrollController, - childrenDelegate: SliverChildBuilderDelegate( - (context, i) { - return _itemBuilder(context, i, channels); - }, - childCount: (channels.length * 2) + 1, - findChildIndexCallback: (key) { - final ValueKey valueKey = key; - final index = channels.indexWhere( - (channel) => 'CHANNEL-${channel.id}' == valueKey.value); - return index != -1 ? (index * 2) : null; - }, + child: Text(message), + ), + FlatButton( + onPressed: () { + channelsBlocState.queryChannels( + filter: widget.filter, + sortOptions: widget.sort, + paginationParams: widget.pagination, + options: widget.options, + ); + }, + child: Text('Retry'), + ), + ], ), ); - }), - ); + } + + if (!snapshot.hasData) { + return Center( + child: CircularProgressIndicator(), + ); + } + + final channels = snapshot.data; + return ListView.custom( + physics: AlwaysScrollableScrollPhysics(), + controller: _scrollController, + childrenDelegate: SliverChildBuilderDelegate( + (context, i) { + return _itemBuilder(context, i, channels); + }, + childCount: (channels.length * 2) + 1, + findChildIndexCallback: (key) { + final ValueKey valueKey = key; + final index = channels.indexWhere( + (channel) => 'CHANNEL-${channel.id}' == valueKey.value); + return index != -1 ? (index * 2) : null; + }, + ), + ); + }); } Widget _itemBuilder(context, int i, List channels) { From 5bcc9bdf912a51e7f134083ac7850b02dcb90268 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 25 Aug 2020 11:09:37 +0200 Subject: [PATCH 2/2] add onLinkTap to MessageWidget --- lib/src/message_text.dart | 8 +++++++- lib/src/message_widget.dart | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/src/message_text.dart b/lib/src/message_text.dart index 6ca99f6c..2ee6a6f8 100644 --- a/lib/src/message_text.dart +++ b/lib/src/message_text.dart @@ -11,10 +11,12 @@ class MessageText extends StatelessWidget { @required this.message, @required this.messageTheme, this.onMentionTap, + this.onLinkTap, }) : super(key: key); final Message message; final void Function(User) onMentionTap; + final void Function(String) onLinkTap; final MessageTheme messageTheme; @override @@ -35,7 +37,11 @@ class MessageText extends StatelessWidget { print('tap on ${mentionedUser.name}'); } } else { - launchURL(context, link); + if (onLinkTap != null) { + onLinkTap(link); + } else { + launchURL(context, link); + } } }, styleSheet: MarkdownStyleSheet.fromTheme( diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index fc6aecf2..056e433a 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -97,6 +97,9 @@ class MessageWidget extends StatefulWidget { /// The function called when tapping on UserAvatar final void Function(User) onUserAvatarTap; + /// The function called when tapping on a link + final void Function(String) onLinkTap; + final List readList; /// If true show the users username next to the timestamp of the message @@ -128,6 +131,7 @@ class MessageWidget extends StatefulWidget { this.showDeleteMessage = true, this.showEditMessage = true, this.onUserAvatarTap, + this.onLinkTap, this.onMessageActions, this.editMessageInputBuilder, this.textBuilder, @@ -764,6 +768,7 @@ class _MessageWidgetState extends State { return widget.textBuilder != null ? widget.textBuilder(context, widget.message) : MessageText( + onLinkTap: widget.onLinkTap, message: widget.message, onMentionTap: widget.onMentionTap, messageTheme: widget.messageTheme,