Merge branch 'master' into feature/partial-update

This commit is contained in:
Salvatore Giordano
2021-02-19 16:10:54 +01:00
committed by GitHub
3 changed files with 127 additions and 82 deletions
@@ -154,7 +154,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
},
);
},
errorBuilder: widget.emptyBuilder ??
errorBuilder: widget.errorBuilder ??
(BuildContext context, dynamic error) {
if (error is Error) {
print((error).stackTrace);
@@ -67,6 +67,8 @@ class StreamExample extends StatelessWidget {
/// [ChannelListCore] is a `builder` with callbacks for constructing UIs based
/// on different scenarios.
class HomeScreen extends StatelessWidget {
final channelListController = ChannelListController();
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -75,6 +77,15 @@ class HomeScreen extends StatelessWidget {
),
body: ChannelsBloc(
child: ChannelListCore(
channelListController: channelListController,
filter: {
'type': 'messaging',
'members': {
r'$in': [
StreamChatCore.of(context).user.id,
]
}
},
emptyBuilder: (BuildContext context) {
return Center(
child: Text('Looks like you are not in any channels'),
@@ -99,31 +110,46 @@ class HomeScreen extends StatelessWidget {
BuildContext context,
List<Channel> channels,
) =>
ListView.builder(
itemCount: channels.length,
itemBuilder: (BuildContext context, int index) {
final _item = channels[index];
return ListTile(
title: Text(_item.name),
subtitle: Text(_item.state.lastMessage.text),
onTap: () {
/// Display a list of messages when the user taps on an item.
/// We can use [StreamChannel] to wrap our [MessageScreen] screen
/// with the selected channel.
///
/// This allows us to use a built-in inherited widget for accessing
/// our `channel` later on.
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: _item,
child: MessageScreen(),
),
),
);
},
);
LazyLoadScrollView(
onEndOfPage: () async {
channelListController.paginateData();
},
child: ListView.builder(
itemCount: channels.length,
itemBuilder: (BuildContext context, int index) {
final _item = channels[index];
return ListTile(
title: Text(_item.name),
subtitle: StreamBuilder<Message>(
stream: _item.state.lastMessageStream,
initialData: _item.state.lastMessage,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.text);
}
return SizedBox();
},
),
onTap: () {
/// Display a list of messages when the user taps on an item.
/// We can use [StreamChannel] to wrap our [MessageScreen] screen
/// with the selected channel.
///
/// This allows us to use a built-in inherited widget for accessing
/// our `channel` later on.
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: _item,
child: MessageScreen(),
),
),
);
},
);
},
),
),
),
),
@@ -145,6 +171,7 @@ class MessageScreen extends StatefulWidget {
class _MessageScreenState extends State<MessageScreen> {
TextEditingController _controller;
ScrollController _scrollController;
final messageListController = MessageListController();
@override
void initState() {
@@ -175,68 +202,83 @@ class _MessageScreenState extends State<MessageScreen> {
final channel = StreamChannel.of(context).channel;
return Scaffold(
appBar: AppBar(
title: Text(channel.name),
title: StreamBuilder<List<User>>(
initialData: channel.state.typingEvents,
stream: channel.state.typingEventsStream,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data.isNotEmpty) {
return Text('${snapshot.data.first.name} is typing...');
}
return SizedBox();
},
),
),
body: SafeArea(
child: Column(
children: [
Expanded(
child: MessageListCore(
emptyBuilder: (BuildContext context) {
return Center(
child: Text('Nothing here yet'),
);
},
loadingBuilder: (BuildContext context) {
return Center(
child: SizedBox(
height: 100.0,
width: 100.0,
child: CircularProgressIndicator(),
),
);
},
messageListBuilder: (
BuildContext context,
List<Message> messages,
) {
return ListView.builder(
controller: _scrollController,
itemCount: messages.length,
reverse: true,
itemBuilder: (BuildContext context, int index) {
final item = messages[index];
final client = StreamChatCore.of(context).client;
if (item.user.id == client.uid) {
return Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item.text),
),
);
} else {
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item.text),
),
);
}
},
);
},
errorWidgetBuilder: (BuildContext context, error) {
print(error?.toString());
return Center(
child: SizedBox(
height: 100.0,
width: 100.0,
child: Text('Oh no, an error occured. Please see logs.'),
),
);
child: LazyLoadScrollView(
onEndOfPage: () async {
messageListController.paginateData();
},
child: MessageListCore(
emptyBuilder: (BuildContext context) {
return Center(
child: Text('Nothing here yet'),
);
},
loadingBuilder: (BuildContext context) {
return Center(
child: SizedBox(
height: 100.0,
width: 100.0,
child: CircularProgressIndicator(),
),
);
},
messageListBuilder: (
BuildContext context,
List<Message> messages,
) {
return ListView.builder(
controller: _scrollController,
itemCount: messages.length,
reverse: true,
itemBuilder: (BuildContext context, int index) {
final item = messages[index];
final client = StreamChatCore.of(context).client;
if (item.user.id == client.uid) {
return Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item.text),
),
);
} else {
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item.text),
),
);
}
},
);
},
errorWidgetBuilder: (BuildContext context, error) {
print(error?.toString());
return Center(
child: SizedBox(
height: 100.0,
width: 100.0,
child:
Text('Oh no, an error occured. Please see logs.'),
),
);
},
),
),
),
Padding(
@@ -64,7 +64,10 @@ class ChannelListCore extends StatefulWidget {
this.filter,
this.options,
this.sort,
this.pagination,
this.pagination = const PaginationParams(
offset: 0,
limit: 25,
),
this.channelListController,
}) : assert(errorBuilder != null),
assert(emptyBuilder != null),