Merge branch 'master' into feature/partial-update
This commit is contained in:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user