fix example

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2021-04-20 21:17:43 +05:30
parent 3bb1b11ee8
commit 4e9f4baf23
5 changed files with 54 additions and 49 deletions
+4 -14
View File
@@ -1685,8 +1685,7 @@ class ChannelClientState {
...messages!, ...messages!,
]; ];
newThreads[parentId]! newThreads[parentId]!.sort(_sortByCreatedAt);
.sort(_sortByCreatedAt as int Function(Message, Message)?);
} else { } else {
newThreads[parentId] = messages; newThreads[parentId] = messages;
} }
@@ -1713,7 +1712,7 @@ class ChannelClientState {
.any((newMessage) => newMessage.id == m.id) != .any((newMessage) => newMessage.id == m.id) !=
true) true)
.toList(), .toList(),
]..sort(_sortByCreatedAt as int Function(Message, Message)?); ]..sort(_sortByCreatedAt);
final newWatchers = <User>[ final newWatchers = <User>[
...updatedState.watchers, ...updatedState.watchers,
@@ -1752,17 +1751,8 @@ class ChannelClientState {
); );
} }
int? _sortByCreatedAt(a, b) { int _sortByCreatedAt(Message a, Message b) =>
if (a.createdAt == null) { a.createdAt.compareTo(b.createdAt);
return 1;
}
if (b.createdAt == null) {
return -1;
}
return a.createdAt.compareTo(b.createdAt);
}
/// The channel state related to this client /// The channel state related to this client
ChannelState get _channelState => _channelStateController.value!; ChannelState get _channelState => _channelStateController.value!;
@@ -7,6 +7,7 @@ import 'package:stream_chat/src/models/message.dart';
import 'package:stream_chat/src/models/reaction.dart'; import 'package:stream_chat/src/models/reaction.dart';
import 'package:stream_chat/src/models/read.dart'; import 'package:stream_chat/src/models/read.dart';
import 'package:stream_chat/src/models/user.dart'; import 'package:stream_chat/src/models/user.dart';
import 'package:stream_chat/src/extensions/iterable_extension.dart';
/// A simple client used for persisting chat data locally. /// A simple client used for persisting chat data locally.
abstract class ChatPersistenceClient { abstract class ChatPersistenceClient {
@@ -78,7 +79,7 @@ abstract class ChatPersistenceClient {
return ChannelState( return ChannelState(
members: data[0] as List<Member>, members: data[0] as List<Member>,
read: data[1] as List<Read>, read: data[1] as List<Read>,
channel: data[2] as ChannelModel, channel: data[2] as ChannelModel?,
messages: data[3] as List<Message>, messages: data[3] as List<Message>,
pinnedMessages: data[4] as List<Message>, pinnedMessages: data[4] as List<Message>,
); );
@@ -192,17 +193,17 @@ abstract class ChatPersistenceClient {
deleteMembers, deleteMembers,
]); ]);
final channels = cleanedChannelStates final channels = cleanedChannelStates.map((it) => it.channel).withNullifyer;
.map((it) => it.channel)
.where((it) => it != null) as Iterable<ChannelModel>;
final reactions = final reactions = cleanedChannelStates
cleanedChannelStates.expand((it) => it.messages).expand((it) => [ .expand((it) => it.messages)
.expand((it) => [
if (it.ownReactions != null) if (it.ownReactions != null)
...it.ownReactions!.where((r) => r.userId != null), ...it.ownReactions!.where((r) => r.userId != null),
if (it.latestReactions != null) if (it.latestReactions != null)
...it.latestReactions!.where((r) => r.userId != null), ...it.latestReactions!.where((r) => r.userId != null),
]); ])
.withNullifyer;
final users = cleanedChannelStates final users = cleanedChannelStates
.map((cs) => [ .map((cs) => [
@@ -220,7 +221,7 @@ abstract class ChatPersistenceClient {
...cs.members.map((m) => m.user), ...cs.members.map((m) => m.user),
]) ])
.expand((it) => it) .expand((it) => it)
.where((it) => it != null) as Iterable<User>; .withNullifyer;
final updateMessagesFuture = cleanedChannelStates.map((it) { final updateMessagesFuture = cleanedChannelStates.map((it) {
final cid = it.channel!.cid; final cid = it.channel!.cid;
@@ -0,0 +1,9 @@
/// Useful extension functions for [Iterable]
extension IterableX<T> on Iterable<T?> {
/// Removes all the null values
/// and converts `Iterable<T?>` into `Iterable<T>`
Iterable<T> get withNullifyer => [
for (final item in this)
if (item != null) item
];
}
@@ -50,15 +50,16 @@ Future<void> main() async {
/// Example using Stream's Low Level Dart client. /// Example using Stream's Low Level Dart client.
class StreamExample extends StatelessWidget { class StreamExample extends StatelessWidget {
/// To initialize this example, an instance of [client] and [channel] is required. /// To initialize this example, an instance of
/// [client] and [channel] is required.
const StreamExample({ const StreamExample({
Key key, Key? key,
@required this.client, required this.client,
@required this.channel, required this.channel,
}) : super(key: key); }) : super(key: key);
/// Instance of [StreamChatClient] we created earlier. This contains information about /// Instance of [StreamChatClient] we created earlier.
/// our application and connection state. /// This contains information about our application and connection state.
final StreamChatClient client; final StreamChatClient client;
/// The channel we'd like to observe and participate. /// The channel we'd like to observe and participate.
@@ -77,28 +78,31 @@ class StreamExample extends StatelessWidget {
/// containing the channel name and a [MessageView] displaying recent messages. /// containing the channel name and a [MessageView] displaying recent messages.
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
/// [HomeScreen] is constructed using the [Channel] we defined earlier. /// [HomeScreen] is constructed using the [Channel] we defined earlier.
const HomeScreen({Key key, @required this.channel}) : super(key: key); const HomeScreen({
Key? key,
required this.channel,
}) : super(key: key);
/// Channel object containing the [Channel.id] we'd like to observe. /// Channel object containing the [Channel.id] we'd like to observe.
final Channel channel; final Channel channel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final messages = channel.state.channelStateStream; final messages = channel.state!.channelStateStream;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Channel: ${channel.id}'), title: Text('Channel: ${channel.id}'),
), ),
body: SafeArea( body: SafeArea(
child: StreamBuilder<ChannelState>( child: StreamBuilder<ChannelState?>(
stream: messages, stream: messages,
builder: ( builder: (
BuildContext context, BuildContext context,
AsyncSnapshot<ChannelState> snapshot, AsyncSnapshot<ChannelState?> snapshot,
) { ) {
if (snapshot.hasData && snapshot.data != null) { if (snapshot.hasData && snapshot.data != null) {
return MessageView( return MessageView(
messages: snapshot.data.messages.reversed.toList(), messages: snapshot.data!.messages.reversed.toList(),
channel: channel, channel: channel,
); );
} else if (snapshot.hasError) { } else if (snapshot.hasError) {
@@ -110,8 +114,8 @@ class HomeScreen extends StatelessWidget {
} }
return const Center( return const Center(
child: SizedBox( child: SizedBox(
width: 100.0, width: 100,
height: 100.0, height: 100,
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
); );
@@ -127,9 +131,9 @@ class HomeScreen extends StatelessWidget {
class MessageView extends StatefulWidget { class MessageView extends StatefulWidget {
/// Message takes the latest list of messages and the current channel. /// Message takes the latest list of messages and the current channel.
const MessageView({ const MessageView({
Key key, Key? key,
@required this.messages, required this.messages,
@required this.channel, required this.channel,
}) : super(key: key); }) : super(key: key);
/// List of messages sent in the given channel. /// List of messages sent in the given channel.
@@ -143,8 +147,8 @@ class MessageView extends StatefulWidget {
} }
class _MessageViewState extends State<MessageView> { class _MessageViewState extends State<MessageView> {
TextEditingController _controller; late final TextEditingController _controller;
ScrollController _scrollController; late final ScrollController _scrollController;
List<Message> get _messages => widget.messages; List<Message> get _messages => widget.messages;
@@ -182,20 +186,20 @@ class _MessageViewState extends State<MessageView> {
reverse: true, reverse: true,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final item = _messages[index]; final item = _messages[index];
if (item.user.id == widget.channel.client.uid) { if (item.user?.id == widget.channel.client.uid) {
return Align( return Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8),
child: Text(item.text), child: Text(item.text ?? ''),
), ),
); );
} else { } else {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8),
child: Text(item.text), child: Text(item.text ?? ''),
), ),
); );
} }
@@ -203,7 +207,7 @@ class _MessageViewState extends State<MessageView> {
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@@ -251,7 +255,8 @@ class _MessageViewState extends State<MessageView> {
} }
} }
/// Helper extension for quickly retrieving the current user id from a [StreamChatClient]. /// Helper extension for quickly retrieving
/// the current user id from a [StreamChatClient].
extension on StreamChatClient { extension on StreamChatClient {
String get uid => state.user.id; String get uid => state.user!.id;
} }
@@ -5,7 +5,7 @@ publish_to: 'none'
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
dependencies: dependencies:
flutter: flutter: