From 4c4473d4b5d29fd1a518a1571e792533e8420a7a Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 20 Apr 2021 13:14:07 +0200 Subject: [PATCH] migrate sample app --- packages/stream_chat/lib/src/api/channel.dart | 54 ++++++++---------- packages/stream_chat/lib/src/client.dart | 11 ++-- .../test/src/api/channel_test.dart | 18 +++--- .../analysis_options.yaml | 1 + .../example/lib/main.dart | 57 ++++++++++--------- .../example/pubspec.yaml | 2 +- .../lib/src/channel_list_core.dart | 1 + .../test/channels_bloc_test.dart | 4 +- 8 files changed, 77 insertions(+), 71 deletions(-) diff --git a/packages/stream_chat/lib/src/api/channel.dart b/packages/stream_chat/lib/src/api/channel.dart index cc205772..7389448f 100644 --- a/packages/stream_chat/lib/src/api/channel.dart +++ b/packages/stream_chat/lib/src/api/channel.dart @@ -27,7 +27,7 @@ class Channel { } /// Create a channel client instance from a [ChannelState] object - Channel.fromState(this._client, ChannelState channelState) { + Channel.fromState(this._client, ChannelState channelState) : _extraData = {} { _cid = channelState.channel!.cid; _id = channelState.channel!.id; type = channelState.channel!.type; @@ -45,9 +45,9 @@ class Channel { String? _id; String? _cid; - Map? _extraData; + Map _extraData; - set extraData(Map? extraData) { + set extraData(Map extraData) { if (_initializedCompleter.isCompleted) { throw Exception( 'Once the channel is initialized you should use channel.update ' @@ -189,7 +189,7 @@ class Channel { } /// Channel extra data - Map? get extraData => + Map get extraData => state?._channelState.channel?.extraData ?? _extraData; /// Channel extra data as a stream @@ -1028,7 +1028,7 @@ class Channel { }) ..addAll(options); - if (_extraData != null) { + if (_extraData.isNotEmpty) { payload['data'] = _extraData; } @@ -1684,8 +1684,7 @@ class ChannelClientState { ...messages, ]; - newThreads[parentId]! - .sort(_sortByCreatedAt as int Function(Message, Message)?); + newThreads[parentId]!.sort(_sortByCreatedAt); } else { newThreads[parentId] = messages; } @@ -1712,7 +1711,7 @@ class ChannelClientState { .any((newMessage) => newMessage.id == m.id) != true) .toList(), - ]..sort(_sortByCreatedAt as int Function(Message, Message)?); + ]..sort(_sortByCreatedAt); final newWatchers = [ ...updatedState.watchers, @@ -1751,17 +1750,8 @@ class ChannelClientState { ); } - int? _sortByCreatedAt(a, b) { - if (a.createdAt == null) { - return 1; - } - - if (b.createdAt == null) { - return -1; - } - - return a.createdAt.compareTo(b.createdAt); - } + int _sortByCreatedAt(Message a, Message b) => + a.createdAt.compareTo(b.createdAt); /// The channel state related to this client ChannelState get _channelState => _channelStateController.value!; @@ -1799,15 +1789,15 @@ class ChannelClientState { } /// Channel related typing users last value - List? get typingEvents => _typingEventsController.value as List?; + List get typingEvents => _typingEventsController.value!; /// Channel related typing users stream - Stream> get typingEventsStream => _typingEventsController.stream; - final BehaviorSubject> _typingEventsController = + Stream> get typingEventsStream => _typingEventsController.stream; + final BehaviorSubject> _typingEventsController = BehaviorSubject.seeded([]); final Channel _channel; - final Map _typings = {}; + final Map _typings = {}; void _listenTypingEvents() { if (_channelState.channel?.config.typingEvents == false) { @@ -1818,9 +1808,12 @@ class ChannelClientState { ..add( _channel.on(EventType.typingStart).listen( (event) { - if (event.user!.id != _channel.client.state.user!.id) { - _typings[event.user] = DateTime.now(); - _typingEventsController.add(_typings.keys.toList()); + if (event.user != null) { + final user = event.user!; + if (user.id != _channel.client.state.user?.id) { + _typings[user] = DateTime.now(); + _typingEventsController.add(_typings.keys.toList()); + } } }, ), @@ -1828,9 +1821,12 @@ class ChannelClientState { ..add( _channel.on(EventType.typingStop).listen( (event) { - if (event.user!.id != _channel.client.state.user!.id) { - _typings.remove(event.user); - _typingEventsController.add(_typings.keys.toList()); + if (event.user != null) { + final user = event.user!; + if (user.id != _channel.client.state.user?.id) { + _typings.remove(event.user); + _typingEventsController.add(_typings.keys.toList()); + } } }, ), diff --git a/packages/stream_chat/lib/src/client.dart b/packages/stream_chat/lib/src/client.dart index 403e5a2b..4689e9ec 100644 --- a/packages/stream_chat/lib/src/client.dart +++ b/packages/stream_chat/lib/src/client.dart @@ -780,10 +780,11 @@ class StreamChatClient { PaginationParams paginationParams = const PaginationParams(), }) async { final offlineChannels = (await _chatPersistenceClient?.getChannelStates( - filter: filter, - sort: sort, - paginationParams: paginationParams, - ))!; + filter: filter, + sort: sort, + paginationParams: paginationParams, + )) ?? + []; final updatedData = _mapChannelStateToChannel(offlineChannels); state.channels = updatedData.key; return updatedData.value; @@ -1193,7 +1194,7 @@ class StreamChatClient { Channel channel( String type, { String? id, - Map? extraData, + Map extraData = const {}, }) { if (id != null && state.channels?.containsKey('$type:$id') == true) { if (state.channels!['$type:$id'] != null) { diff --git a/packages/stream_chat/test/src/api/channel_test.dart b/packages/stream_chat/test/src/api/channel_test.dart index 041a3e49..8f18d5e2 100644 --- a/packages/stream_chat/test/src/api/channel_test.dart +++ b/packages/stream_chat/test/src/api/channel_test.dart @@ -516,7 +516,7 @@ void main() { ); await channelClient.watch(); - final event = Event(type: EventType.any); + final event = const Event(type: EventType.any); when( () => mockDio.post( @@ -564,7 +564,7 @@ void main() { ); await channelClient.watch(); - final event = Event(type: EventType.typingStart); + final event = const Event(type: EventType.typingStart); when( () => mockDio.post( @@ -610,7 +610,7 @@ void main() { ); await channelClient.watch(); - final event = Event(type: EventType.typingStop); + final event = const Event(type: EventType.typingStop); when( () => mockDio.post( @@ -901,8 +901,10 @@ void main() { 'presence': true, }; - when(() => mockDio.post('/channels/messaging/query', - data: options)).thenAnswer( + when(() => mockDio.post( + '/channels/messaging/query', + data: options, + )).thenAnswer( (_) async => Response( data: r''' { @@ -1198,8 +1200,10 @@ void main() { final response = await channelClient.query(options: options); - verify(() => mockDio.post('/channels/messaging/query', - data: options)).called(1); + verify(() => mockDio.post( + '/channels/messaging/query', + data: options, + )).called(1); expect(channelClient.id, response.channel?.id); expect(channelClient.cid, response.channel?.cid); }); diff --git a/packages/stream_chat_flutter_core/analysis_options.yaml b/packages/stream_chat_flutter_core/analysis_options.yaml index 039d0230..545d5492 100644 --- a/packages/stream_chat_flutter_core/analysis_options.yaml +++ b/packages/stream_chat_flutter_core/analysis_options.yaml @@ -3,6 +3,7 @@ analyzer: - lib/**/*.g.dart - lib/**/*.freezed.dart - example/* + - test/* linter: rules: - always_use_package_imports diff --git a/packages/stream_chat_flutter_core/example/lib/main.dart b/packages/stream_chat_flutter_core/example/lib/main.dart index aa705db1..a9157e6e 100644 --- a/packages/stream_chat_flutter_core/example/lib/main.dart +++ b/packages/stream_chat_flutter_core/example/lib/main.dart @@ -38,8 +38,8 @@ class StreamExample extends StatelessWidget { /// If you'd prefer using pre-made UI widgets for your app, please see our other /// package, `stream_chat_flutter`. const StreamExample({ - Key key, - @required this.client, + Key? key, + required this.client, }) : super(key: key); /// Instance of Stream Client. @@ -55,7 +55,7 @@ class StreamExample extends StatelessWidget { home: HomeScreen(), builder: (context, child) => StreamChatCore( client: client, - child: child, + child: child!, ), ); } @@ -82,7 +82,7 @@ class HomeScreen extends StatelessWidget { 'type': 'messaging', 'members': { r'$in': [ - StreamChatCore.of(context).user.id, + StreamChatCore.of(context).user!.id, ] } }, @@ -100,10 +100,13 @@ class HomeScreen extends StatelessWidget { ), ); }, - errorBuilder: (BuildContext context, dynamic error) { + errorBuilder: ( + BuildContext context, + dynamic error, + ) { return Center( child: Text( - 'Oh no, something went wrong. Please check your config.'), + 'Oh no, something went wrong. Please check your config. ${error}'), ); }, listBuilder: ( @@ -112,20 +115,20 @@ class HomeScreen extends StatelessWidget { ) => LazyLoadScrollView( onEndOfPage: () async { - channelListController.paginateData(); + 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( - stream: _item.state.lastMessageStream, - initialData: _item.state.lastMessage, + title: Text(_item.name!), + subtitle: StreamBuilder( + stream: _item.state!.lastMessageStream, + initialData: _item.state!.lastMessage, builder: (context, snapshot) { if (snapshot.hasData) { - return Text(snapshot.data.text); + return Text(snapshot.data!.text!); } return SizedBox(); @@ -169,8 +172,8 @@ class MessageScreen extends StatefulWidget { } class _MessageScreenState extends State { - TextEditingController _controller; - ScrollController _scrollController; + late final TextEditingController _controller; + late final ScrollController _scrollController; final messageListController = MessageListController(); @override @@ -203,11 +206,11 @@ class _MessageScreenState extends State { return Scaffold( appBar: AppBar( title: StreamBuilder>( - initialData: channel.state.typingEvents, - stream: channel.state.typingEventsStream, + 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...'); + if (snapshot.hasData && snapshot.data!.isNotEmpty) { + return Text('${snapshot.data!.first.name} is typing...'); } return SizedBox(); }, @@ -219,7 +222,7 @@ class _MessageScreenState extends State { Expanded( child: LazyLoadScrollView( onEndOfPage: () async { - messageListController.paginateData(); + messageListController.paginateData!(); }, child: MessageListCore( emptyBuilder: (BuildContext context) { @@ -247,12 +250,12 @@ class _MessageScreenState extends State { itemBuilder: (BuildContext context, int index) { final item = messages[index]; final client = StreamChatCore.of(context).client; - if (item.user.id == client.uid) { + if (item.user!.id == client.uid) { return Align( alignment: Alignment.centerRight, child: Padding( padding: const EdgeInsets.all(8.0), - child: Text(item.text), + child: Text(item.text!), ), ); } else { @@ -260,7 +263,7 @@ class _MessageScreenState extends State { alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.all(8.0), - child: Text(item.text), + child: Text(item.text!), ), ); } @@ -268,7 +271,7 @@ class _MessageScreenState extends State { ); }, errorWidgetBuilder: (BuildContext context, error) { - print(error?.toString()); + print(error.toString()); return Center( child: SizedBox( height: 100.0, @@ -282,7 +285,7 @@ class _MessageScreenState extends State { ), ), Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8), child: Row( children: [ Expanded( @@ -308,7 +311,7 @@ class _MessageScreenState extends State { } }, child: const Padding( - padding: EdgeInsets.all(8.0), + padding: EdgeInsets.all(8), child: Center( child: Icon( Icons.send, @@ -332,12 +335,12 @@ class _MessageScreenState extends State { /// below, we add two simple extensions to the [StreamChatClient] and [Channel]. extension on StreamChatClient { /// Fetches the current user id. - String get uid => state.user.id; + String get uid => state.user!.id; } extension on Channel { /// Fetches the name of the channel by accessing [extraData] or [cid]. - String get name { + String? get name { final _channelName = extraData['name']; if (_channelName != null) { return _channelName; diff --git a/packages/stream_chat_flutter_core/example/pubspec.yaml b/packages/stream_chat_flutter_core/example/pubspec.yaml index 91cf4a01..e03eba6c 100644 --- a/packages/stream_chat_flutter_core/example/pubspec.yaml +++ b/packages/stream_chat_flutter_core/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: diff --git a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart index 322a2780..992cae5d 100644 --- a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart @@ -133,6 +133,7 @@ class ChannelListCoreState extends State { stream: channelsBlocState.channelsStream, builder: (context, snapshot) { if (snapshot.hasError) { + print('snapshot: ${snapshot.stackTrace}'); return widget.errorBuilder(context, snapshot.error!); } if (!snapshot.hasData) { diff --git a/packages/stream_chat_flutter_core/test/channels_bloc_test.dart b/packages/stream_chat_flutter_core/test/channels_bloc_test.dart index de8b0af1..28136add 100644 --- a/packages/stream_chat_flutter_core/test/channels_bloc_test.dart +++ b/packages/stream_chat_flutter_core/test/channels_bloc_test.dart @@ -779,8 +779,8 @@ void main() { final mockClient = MockClient(); final channels = _generateChannels(mockClient); int channelComparator(Channel a, Channel b) { - final aData = a.extraData!['extra_data_key'] as String; - final bData = b.extraData!['extra_data_key'] as String; + final aData = a.extraData['extra_data_key'] as String; + final bData = b.extraData['extra_data_key'] as String; return bData.compareTo(aData); }