Merge pull request #75 from GetStream/develop

Develop
This commit is contained in:
Salvatore Giordano
2020-08-25 15:11:19 +02:00
committed by GitHub
3 changed files with 107 additions and 82 deletions
+95 -81
View File
@@ -60,6 +60,7 @@ class ChannelListView extends StatefulWidget {
this.channelPreviewBuilder, this.channelPreviewBuilder,
this.errorBuilder, this.errorBuilder,
this.onImageTap, this.onImageTap,
this.pullToRefresh = true,
}) : super(key: key); }) : super(key: key);
/// The builder that will be used in case of error /// 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 /// The function called when the image is tapped
final Function(Channel) onImageTap; final Function(Channel) onImageTap;
/// Set it to false to disable the pull-to-refresh widget
final bool pullToRefresh;
@override @override
_ChannelListViewState createState() => _ChannelListViewState(); _ChannelListViewState createState() => _ChannelListViewState();
} }
@@ -115,105 +119,115 @@ class _ChannelListViewState extends State<ChannelListView>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final channelsProvider = ChannelsBloc.of(context); final channelsBloc = ChannelsBloc.of(context);
if (!widget.pullToRefresh) {
return _buildListView(channelsBloc);
}
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async { onRefresh: () async {
return channelsProvider.queryChannels( return channelsBloc.queryChannels(
filter: widget.filter, filter: widget.filter,
sortOptions: widget.sort, sortOptions: widget.sort,
paginationParams: widget.pagination, paginationParams: widget.pagination,
options: widget.options, options: widget.options,
); );
}, },
child: StreamBuilder<List<Channel>>( child: _buildListView(channelsBloc),
stream: channelsProvider.channelsStream, );
builder: (context, snapshot) { }
if (snapshot.hasError) {
if (snapshot.error is Error) {
print((snapshot.error as Error).stackTrace);
}
if (widget.errorBuilder != null) { StreamBuilder<List<Channel>> _buildListView(
return widget.errorBuilder(snapshot.error); ChannelsBlocState channelsBlocState,
} ) {
return StreamBuilder<List<Channel>>(
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 (widget.errorBuilder != null) {
if (snapshot.error is DioError) { return widget.errorBuilder(snapshot.error);
final dioError = snapshot.error as DioError; }
if (dioError.type == DioErrorType.RESPONSE) {
message = dioError.message; var message = snapshot.error.toString();
} else { if (snapshot.error is DioError) {
message = 'Check your connection and retry'; 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( return Center(
mainAxisAlignment: MainAxisAlignment.center, child: Column(
children: <Widget>[ mainAxisAlignment: MainAxisAlignment.center,
Text.rich( children: <Widget>[
TextSpan( Text.rich(
children: [ TextSpan(
WidgetSpan( children: [
child: Padding( WidgetSpan(
padding: const EdgeInsets.only( child: Padding(
right: 2.0, padding: const EdgeInsets.only(
), right: 2.0,
child: Icon(Icons.error_outline),
), ),
child: Icon(Icons.error_outline),
), ),
TextSpan(text: 'Error loading channels'), ),
], TextSpan(text: 'Error loading channels'),
), ],
style: Theme.of(context).textTheme.headline6,
), ),
Padding( style: Theme.of(context).textTheme.headline6,
padding: const EdgeInsets.only( ),
top: 16.0, Padding(
), padding: const EdgeInsets.only(
child: Text(message), top: 16.0,
), ),
FlatButton( child: Text(message),
onPressed: () { ),
channelsProvider.queryChannels( FlatButton(
filter: widget.filter, onPressed: () {
sortOptions: widget.sort, channelsBlocState.queryChannels(
paginationParams: widget.pagination, filter: widget.filter,
options: widget.options, sortOptions: widget.sort,
); paginationParams: widget.pagination,
}, options: widget.options,
child: Text('Retry'), );
), },
], 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<String> valueKey = key;
final index = channels.indexWhere(
(channel) => 'CHANNEL-${channel.id}' == valueKey.value);
return index != -1 ? (index * 2) : null;
},
), ),
); );
}), }
);
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<String> valueKey = key;
final index = channels.indexWhere(
(channel) => 'CHANNEL-${channel.id}' == valueKey.value);
return index != -1 ? (index * 2) : null;
},
),
);
});
} }
Widget _itemBuilder(context, int i, List<Channel> channels) { Widget _itemBuilder(context, int i, List<Channel> channels) {
+7 -1
View File
@@ -11,10 +11,12 @@ class MessageText extends StatelessWidget {
@required this.message, @required this.message,
@required this.messageTheme, @required this.messageTheme,
this.onMentionTap, this.onMentionTap,
this.onLinkTap,
}) : super(key: key); }) : super(key: key);
final Message message; final Message message;
final void Function(User) onMentionTap; final void Function(User) onMentionTap;
final void Function(String) onLinkTap;
final MessageTheme messageTheme; final MessageTheme messageTheme;
@override @override
@@ -35,7 +37,11 @@ class MessageText extends StatelessWidget {
print('tap on ${mentionedUser.name}'); print('tap on ${mentionedUser.name}');
} }
} else { } else {
launchURL(context, link); if (onLinkTap != null) {
onLinkTap(link);
} else {
launchURL(context, link);
}
} }
}, },
styleSheet: MarkdownStyleSheet.fromTheme( styleSheet: MarkdownStyleSheet.fromTheme(
+5
View File
@@ -97,6 +97,9 @@ class MessageWidget extends StatefulWidget {
/// The function called when tapping on UserAvatar /// The function called when tapping on UserAvatar
final void Function(User) onUserAvatarTap; final void Function(User) onUserAvatarTap;
/// The function called when tapping on a link
final void Function(String) onLinkTap;
final List<Read> readList; final List<Read> readList;
/// If true show the users username next to the timestamp of the message /// 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.showDeleteMessage = true,
this.showEditMessage = true, this.showEditMessage = true,
this.onUserAvatarTap, this.onUserAvatarTap,
this.onLinkTap,
this.onMessageActions, this.onMessageActions,
this.editMessageInputBuilder, this.editMessageInputBuilder,
this.textBuilder, this.textBuilder,
@@ -764,6 +768,7 @@ class _MessageWidgetState extends State<MessageWidget> {
return widget.textBuilder != null return widget.textBuilder != null
? widget.textBuilder(context, widget.message) ? widget.textBuilder(context, widget.message)
: MessageText( : MessageText(
onLinkTap: widget.onLinkTap,
message: widget.message, message: widget.message,
onMentionTap: widget.onMentionTap, onMentionTap: widget.onMentionTap,
messageTheme: widget.messageTheme, messageTheme: widget.messageTheme,