From b4dc9defd1da3dfe60ddca3dbce1c0efa1107241 Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Wed, 11 Oct 2023 15:02:57 +0300 Subject: [PATCH 01/14] fix(doc): fix broken documentation snippets --- .../01-customize_message_widget.mdx | 5 +- .../02-customize_text_messages.mdx | 35 ++++++----- .../03-customize_message_actions.mdx | 4 +- .../04-adding_custom_attachments.mdx | 59 ++++++++++--------- .../05-customize_attachment_picker_modal.mdx | 17 +++--- .../06-autocomplete_triggers.mdx | 6 +- .../07-slidable_channel_list_preview.mdx | 7 ++- .../stream_chat_and_theming.mdx | 51 ++++++++-------- .../stream_channel_header.mdx | 8 +-- .../stream_channel_list_header.mdx | 6 +- .../stream_channel_list_view.mdx | 4 +- .../stream_member_grid_view.mdx | 23 ++++---- .../stream_member_list_view.mdx | 6 +- .../stream_message_input.mdx | 4 +- .../stream_message_list_view.mdx | 8 +-- .../stream_message_search_grid_view.mdx | 12 +++- .../stream_message_search_list_view.mdx | 9 ++- .../stream_message_widget.mdx | 4 +- .../stream_user_grid_view.mdx | 17 +++--- .../stream_user_list_view.mdx | 4 +- .../lazy_load_scroll_view.mdx | 2 +- .../message_list_core.mdx | 12 ++-- .../paged_value_listenable_builder.mdx | 4 +- .../stream_channel_list_controller.mdx | 6 +- .../stream_channel_list_event_handler.mdx | 13 +--- .../stream_chat_core.mdx | 2 +- .../stream_member_list_controller.mdx | 8 +-- .../stream_message_input_controller.mdx | 4 +- .../stream_message_search_list_controller.mdx | 5 +- .../stream_user_list_controller.mdx | 6 +- ...er_token_generation_with_firebase_auth.mdx | 49 ++++++++------- .../05-guides/04-adding_localization.mdx | 4 ++ .../adding_push_notifications_v2.mdx | 6 +- 33 files changed, 222 insertions(+), 188 deletions(-) diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx index 93611740..e37debbc 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx @@ -21,8 +21,9 @@ provided inside the `messageBuilder` parameter of the `StreamMessageListView` li ```dart StreamMessageListView( messageBuilder: (context, details, messageList, defaultImpl) { - // Your implementation of the message here - // E.g: return Text(details.message.text ?? ''); + return defaultWidget.copyWith( + ... + ); }, ), ``` diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/02-customize_text_messages.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/02-customize_text_messages.mdx index 429fc5e2..da607184 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/02-customize_text_messages.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/02-customize_text_messages.mdx @@ -91,7 +91,7 @@ StreamMessageListView( messageBuilder: (context, messageDetails, messageList, defaultWidget) { return defaultWidget.copyWith( textBuilder: (context, message) { - return Text(message.text); + return Text(message.text ?? ''); }, ); }, @@ -108,14 +108,16 @@ StreamMessageListView( messageBuilder: (context, messageDetails, messageList, defaultWidget) { return defaultWidget.copyWith( textBuilder: (context, message) { - final text = _replaceHashtags(message.text).replaceAll('\n', '\\\n'); + final text = _replaceHashtags(message.text)?.replaceAll('\n', '\\\n'); final messageTheme = StreamChatTheme.of(context).ownMessageTheme; + if (text == null) return const SizedBox(); + return MarkdownBody( data: text, onTapLink: ( String link, - String href, + String? href, String title, ) { // Do something with tapped hashtag @@ -123,16 +125,16 @@ StreamMessageListView( styleSheet: MarkdownStyleSheet.fromTheme( Theme.of(context).copyWith( textTheme: Theme.of(context).textTheme.apply( - bodyColor: messageTheme.messageText.color, - decoration: messageTheme.messageText.decoration, - decorationColor: messageTheme.messageText.decorationColor, - decorationStyle: messageTheme.messageText.decorationStyle, - fontFamily: messageTheme.messageText.fontFamily, + bodyColor: messageTheme.messageTextStyle?.color, + decoration: messageTheme.messageTextStyle?.decoration, + decorationColor: messageTheme.messageTextStyle?.decorationColor, + decorationStyle: messageTheme.messageTextStyle?.decorationStyle, + fontFamily: messageTheme.messageTextStyle?.fontFamily, ), ), ).copyWith( - a: messageTheme.messageLinks, - p: messageTheme.messageText, + a: messageTheme.messageLinksStyle, + p: messageTheme.messageTextStyle, ), ); }, @@ -140,13 +142,16 @@ StreamMessageListView( }, ) -String _replaceHashtags(String text) { - RegExp exp = new RegExp(r"\B#\w\w+"); +String? _replaceHashtags(String? text) { + if (text == null) return null; + + final exp = RegExp(r"\B#\w\w+"); + String result = text; exp.allMatches(text).forEach((match){ - text = text.replaceAll( - '${match.group(0)}', '[${match.group(0)}](${match.group(0).replaceAll(' ', '')})'); + text = text!.replaceAll( + '${match.group(0)}', '[${match.group(0)}](${match.group(0)?.replaceAll(' ', '')})'); }); - return text; + return result; } ``` diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/03-customize_message_actions.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/03-customize_message_actions.mdx index 966a996d..b329f764 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/03-customize_message_actions.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/03-customize_message_actions.mdx @@ -68,8 +68,8 @@ StreamMessageListView( return defaultMessage.copyWith( customActions: [ StreamMessageAction( - leading: Icon(Icons.add), - title: Text('Demo Action'), + leading: const Icon(Icons.add), + title: const Text('Demo Action'), onTap: (message) { /// Complete action here }, diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx index 03f9f129..18c15f49 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx @@ -35,9 +35,9 @@ Message( text: 'This is my location', attachments: [ Attachment( - uploadState: UploadState.success(), + uploadState: const UploadState.success(), type: 'location', - extraData: { + extraData: const { 'latitude': 'fetched_latitude', 'longitude': 'fetched_longitude', }, @@ -62,14 +62,13 @@ First, we add a button which when clicked fetches and shares location into the ` StreamMessageInput( actions: [ InkWell( - child: Icon( + child: const Icon( Icons.location_on, - size: 20.0, - color: StreamChatTheme.of(context).colorTheme.grey, + size: 20, + color: Colors.grey, ), onTap: () { - var channel = StreamChannel.of(context).channel; - var user = StreamChat.of(context).user; + final channel = StreamChannel.of(context).channel; _determinePosition().then((value) { channel.sendMessage( @@ -77,7 +76,7 @@ StreamMessageInput( text: 'This is my location', attachments: [ Attachment( - uploadState: UploadState.success(), + uploadState: const UploadState.success(), type: 'location', extraData: { 'latitude': value.latitude.toString(), @@ -126,8 +125,7 @@ Next, we build the Static Maps URL (Add your API key before using the code snipp ```dart String _buildMapAttachment(String lat, String long) { - var baseURL = 'https://maps.googleapis.com/maps/api/staticmap?'; - var url = Uri( + final url = Uri( scheme: 'https', host: 'maps.googleapis.com', port: 443, @@ -155,8 +153,8 @@ StreamMessageListView( 'location': (context, message, attachments) { final attachmentWidget = Image.network( _buildMapAttachment( - attachments[0].extraData['latitude'], - attachments[0].extraData['longitude'], + attachments[0].extraData['latitude'].toString(), + attachments[0].extraData['longitude'].toString(), ), ); @@ -194,14 +192,14 @@ First, we add the attachment when the location button is clicked: InkWell( child: Icon( Icons.location_on, - size: 20.0, - color: StreamChatTheme.of(context).colorTheme.grey, + size: 20, + color: Colors.grey, ), onTap: () { _determinePosition().then((value) { _messageInputController.addAttachment( Attachment( - uploadState: UploadState.success(), + uploadState: const UploadState.success(), type: 'location', extraData: { 'latitude': value.latitude.toString(), @@ -227,14 +225,14 @@ StreamMessageInput( InkWell( child: Icon( Icons.location_on, - size: 20.0, - color: StreamChatTheme.of(context).colorTheme.grey, + size: 20, + color: Colors.grey, ), onTap: () { _determinePosition().then((value) { _messageInputController.addAttachment( Attachment( - uploadState: UploadState.success(), + uploadState: const UploadState.success(), type: 'location', extraData: { 'latitude': value.latitude.toString(), @@ -248,16 +246,21 @@ StreamMessageInput( }, ), ], - attachmentThumbnailBuilders: { - 'location': (context, attachment) { - return Image.network( - _buildMapAttachment( - attachment.extraData['latitude'], - attachment.extraData['longitude'], - ), - ); - }, - }, + mediaAttachmentBuilder: ( + BuildContext context, + Attachment attachment, + ValueSetter? onRemovePressed, + ) { + if (attachment.type == 'location') { + return Image.network( + _buildMapAttachment( + attachment.extraData['latitude'].toString(), + attachment.extraData['longitude'].toString(), + ), + ); + } + return const SizedBox(); + }, ), ``` diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/05-customize_attachment_picker_modal.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/05-customize_attachment_picker_modal.mdx index 77f727c9..4e89830b 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/05-customize_attachment_picker_modal.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/05-customize_attachment_picker_modal.mdx @@ -25,11 +25,14 @@ The initial attachments can be passed to the Attachment Picker Modal in two ways * By passing the `initialAttachments` parameter. ```dart + StreamMessageInputController _messageInputController = + StreamMessageInputController(); + ... showStreamAttachmentPickerModalBottomSheet( context: context, initialAttachments: [ // Pass the initial attachments to the modal here if any are available already (optional) - ...messageInputController.attachments, + ..._messageInputController.attachments, ], ); ``` @@ -65,7 +68,7 @@ However, you can also customize the options by passing the `customOptions` param customOptions: [ // Pass the custom attachment picker options here AttachmentPickerOption( - icon: Icon(Icons.audiotrack), + icon: const Icon(Icons.audiotrack), supportedTypes: [AttachmentPickerType.audios], optionViewBuilder: (context, attachmentPickerController) { return AudioPicker( @@ -87,7 +90,7 @@ The size of the attachment thumbnail item shown in the gallery picker can be def ```dart showStreamAttachmentPickerModalBottomSheet( context: context, - attachmentThumbnailSize: ThumbnailSize.square(600), + attachmentThumbnailSize: const ThumbnailSize.square(600), ); ``` @@ -121,13 +124,13 @@ Possible values are between 0 and 100. The scale of the attachment thumbnail item shown in the gallery picker can be defined by passing the `attachmentThumbnailScale` parameter. -For example, if this is 2.0, it means that there are four image pixels for every one logical pixel, and the image's actual width and height are +For example, if this is 2, it means that there are four image pixels for every one logical pixel, and the image's actual width and height are double the height and width that should be used when painting the image. ```dart showStreamAttachmentPickerModalBottomSheet( context: context, - attachmentThumbnailScale: 2.0, + attachmentThumbnailScale: 2, ); ``` @@ -145,13 +148,13 @@ The `showStreamAttachmentPickerModalBottomSheet` function also accepts the param isDismissible: true, clipBehavior: Clip.antiAlias, barrierColor: Colors.black.withOpacity(0.5), - constraints: BoxConstraints( + constraints: const BoxConstraints( maxHeight: 500, maxWidth: 500, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical( - top: Radius.circular(16.0), + top: Radius.circular(16), ), ), ); diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/06-autocomplete_triggers.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/06-autocomplete_triggers.mdx index ac38087b..601106dc 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/06-autocomplete_triggers.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/06-autocomplete_triggers.mdx @@ -63,19 +63,19 @@ class StreamEmojiAutocompleteOptions extends StatelessWidget { horizontalTitleGap: 0, leading: Text( emoji.char, - style: themeData.textTheme.headline6!.copyWith( + style: themeData.textTheme.titleLarge!.copyWith( fontSize: 24, ), ), title: SubstringHighlight( text: emoji.shortName, term: query, - textStyleHighlight: themeData.textTheme.headline6!.copyWith( + textStyleHighlight: themeData.textTheme.titleLarge!.copyWith( color: Colors.yellow, fontSize: 14.5, fontWeight: FontWeight.bold, ), - textStyle: themeData.textTheme.headline6!.copyWith( + textStyle: themeData.textTheme.titleLarge!.copyWith( fontSize: 14.5, ), ), diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/07-slidable_channel_list_preview.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/07-slidable_channel_list_preview.mdx index 30ba952f..38bf429f 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/07-slidable_channel_list_preview.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/07-slidable_channel_list_preview.mdx @@ -25,8 +25,8 @@ If you're new to Stream Chat Flutter, we recommend looking at our [getting start dependencies: flutter: sdk: flutter - stream_chat_flutter: ^4.0.0 - flutter_slidable: ^1.2.0 + stream_chat_flutter: ^6.0.0 + flutter_slidable: ^3.0.0 ``` ⚠️ Note: The examples shown in this guide use the above packages and versions. @@ -120,7 +120,8 @@ class _ChannelListPageState extends State { onRefresh: _controller.refresh, child: StreamChannelListView( controller: _controller, - itemBuilder: (context, channel, tile) { + itemBuilder: (context, channels, index, tile) { + final channel = channels[index]; final chatTheme = StreamChatTheme.of(context); final backgroundColor = chatTheme.colorTheme.inputBg; final canDeleteChannel = channel.ownCapabilities diff --git a/docusaurus/docs/Flutter/02-customization/stream_chat_and_theming.mdx b/docusaurus/docs/Flutter/02-customization/stream_chat_and_theming.mdx index ff38e1c4..1b8ee93f 100644 --- a/docusaurus/docs/Flutter/02-customization/stream_chat_and_theming.mdx +++ b/docusaurus/docs/Flutter/02-customization/stream_chat_and_theming.mdx @@ -29,41 +29,44 @@ factory StreamChatThemeData({ Brightness? brightness, TextTheme? textTheme, ColorTheme? colorTheme, - ChannelListHeaderTheme? channelListHeaderTheme, - ChannelPreviewTheme? channelPreviewTheme, - ChannelTheme? channelTheme, - MessageTheme? otherMessageTheme, - MessageTheme? ownMessageTheme, - MessageInputTheme? messageInputTheme, - Widget Function(BuildContext, Channel)? defaultChannelImage, + StreamChannelListHeaderThemeData? channelListHeaderTheme, + StreamChannelPreviewThemeData? channelPreviewTheme, + StreamChannelHeaderThemeData? channelHeaderTheme, + StreamMessageThemeData? otherMessageTheme, + StreamMessageThemeData? ownMessageTheme, + StreamMessageInputThemeData? messageInputTheme, Widget Function(BuildContext, User)? defaultUserImage, + PlaceholderUserImage? placeholderUserImage, IconThemeData? primaryIconTheme, - List? reactionIcons, + List? reactionIcons, + StreamGalleryHeaderThemeData? imageHeaderTheme, + StreamGalleryFooterThemeData? imageFooterTheme, + StreamMessageListViewThemeData? messageListViewTheme, }); ``` ### Stream Chat Theme in use -Let's take a look at customizing widgets using `StreamChatTheme`. In the example below, we can change the default color theme to yellow and override the channel header's typography and colors. +Let's take a look at customizing widgets using `StreamChatThemeData`. In the example below, we can change the default color theme to yellow and override the channel header's typography and colors. ```dart -builder: (context, child) => StreamChat( - client: client, - child: child, - streamChatThemeData: StreamChatThemeData( - colorTheme: ColorTheme.light( - primaryAccent: const Color(0xffffe072), - ), - channelTheme: ChannelTheme( - channelHeaderTheme: ChannelHeaderTheme( - color: const Color(0xffd34646), - title: TextStyle( - color: Colors.white, - ), - ), +MaterialApp( + builder: (context, child) => StreamChat( + client: client, + streamChatThemeData: StreamChatThemeData( + colorTheme: StreamColorTheme.light( + accentPrimary: const Color(0xffffe072), + ), + channelHeaderTheme: const ChannelHeaderThemeData( + color: const Color(0xffd34646), + titleStyle: TextStyle( + color: Colors.white, ), ), - ), + ), + child: child, + ), +); ``` We are creating this class at the very top of our widget tree using the `streamChatThemeData` parameter found in the `StreamChat` widget. diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_header.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_header.mdx index bc3c8aaf..cd7ff3e4 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_header.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_header.mdx @@ -28,13 +28,13 @@ and send messages. ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ - Key key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { return Scaffold( - appBar: StreaChannelHeader(), + appBar: const StreamChannelHeader(), body: Column( children: [ Expanded( @@ -46,7 +46,7 @@ class ChannelPage extends StatelessWidget { }, ), ), - StreamMessageInput(), + const StreamMessageInput(), ], ), ); diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_header.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_header.mdx index 54379bdd..a18f0881 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_header.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_header.mdx @@ -27,9 +27,9 @@ common Channels Page. ```dart class ChannelListPage extends StatefulWidget { const ChannelListPage({ - Key? key, + super.key, required this.client, - }) : super(key: key); + }); final StreamChatClient client; @@ -55,7 +55,7 @@ class _ChannelListPageState extends State { @override Widget build(BuildContext context) => Scaffold( - appBar: StreamChannelListHeader(), + appBar: const StreamChannelListHeader(), body: RefreshIndicator( onRefresh: _controller.refresh, child: StreamChannelListView( diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_view.mdx index 33376fcf..a29685db 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_channel_list_view.mdx @@ -33,9 +33,9 @@ Here is a basic example of the `StreamChannelListView` widget. It consists of th ```dart class ChannelListPage extends StatefulWidget { const ChannelListPage({ - Key? key, + super.key, required this.client, - }) : super(key: key); + }); final StreamChatClient client; diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_grid_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_grid_view.mdx index db9cbb98..6da7a75b 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_grid_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_grid_view.mdx @@ -21,11 +21,11 @@ See the [StreamMemberListView](./stream_member_list_view.mdx) documentation for ```dart class MemberGridPage extends StatefulWidget { const MemberGridPage({ - Key? key, + super.key, required this.client, - }) : super(key: key); + }); - final StreamChatClient client; + final Channel channel; @override State createState() => _MemberGridPageState(); @@ -33,13 +33,13 @@ class MemberGridPage extends StatefulWidget { class _MemberGridPageState extends State { late final _controller = StreamMemberListController( - client: widget.client, + channel: widget.channel, limit: 25, filter: Filter.and([ Filter.notEqual('id', StreamChat.of(context).currentUser!.id), ]), sort: [ - SortOption( + const SortOption( 'name', direction: 1, ), @@ -58,13 +58,16 @@ class _MemberGridPageState extends State { onRefresh: _controller.refresh, child: StreamMemberGridView( controller: _controller, - onChannelTap: (channel) => Navigator.push( + onMemberTap: (member) => Navigator.push( context, MaterialPageRoute( - builder: (_) => StreamChannel( - channel: channel, - child: const ChannelPage(), - ), + builder: (_) => Scaffold( + body: Center( + child: StreamUserAvatar( + user: member.user!, + ), + ), + ), ), ), ), diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_list_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_list_view.mdx index 26285876..2a54c713 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_list_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_member_list_view.mdx @@ -20,7 +20,7 @@ Make sure to check the [StreamMemberListController](../04-stream_chat_flutter_co ```dart class MemberListPage extends StatefulWidget { - const MemberListPage({Key? key}) : super(key: key); + const MemberListPage({super.key}); @override State createState() => _MemberListPageState(); @@ -29,7 +29,7 @@ class MemberListPage extends StatefulWidget { class _MemberListPageState extends State { late final StreamMemberListController _memberListController = StreamMemberListController( - client: StreamChat.of(context).client, + channel: StreamChannel.of(context).channel, limit: 25, filter: Filter.and( [Filter.notEqual('id', StreamChat.of(context).currentUser!.id)], @@ -62,7 +62,7 @@ You can use your own widget for the member items using the `itemBuilder` paramet StreamMemberListView( // ... itemBuilder: (context, members, index, defaultWidget) { - return Text(members[index].name); + return Text(members[index].user!.name); }, ), ``` diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx index 8778f3a4..8610d5e2 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx @@ -71,8 +71,8 @@ StreamMessageInput( InkWell( child: Icon( Icons.location_on, - size: 20.0, - color: StreamChatTheme.of(context).colorTheme.grey, + size: 20, + color: Colors.grey, ), onTap: () { // Do something here diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_list_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_list_view.mdx index 19a041a0..cc67e01d 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_list_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_list_view.mdx @@ -29,19 +29,19 @@ An example of how you can use the `StreamMessageListView` is: ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ - Key key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { return Scaffold( - appBar: StreamChannelHeader(), + appBar: const StreamChannelHeader(), body: Column( children: [ Expanded( child: StreamMessageListView(), ), - StreamMessageInput(), + const StreamMessageInput(), ], ), ); diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_grid_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_grid_view.mdx index d20a62fc..b19ca021 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_grid_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_grid_view.mdx @@ -21,9 +21,9 @@ Make sure to check the [StreamMessageSearchListView](./stream_message_search_lis ```dart class StreamMessageSearchPage extends StatefulWidget { const StreamMessageSearchPage({ - Key? key, + super.key, required this.client, - }) : super(key: key);` + }); final StreamChatClient client; @@ -35,7 +35,10 @@ class _StreamMessageSearchState extends State { late final _controller = StreamMessageSearchListController( client: widget.client, limit: 20, - filters: Filter.in_('members', [StreamChat.of(context).user!.id],), + filter: Filter.in_( + 'members', + [StreamChat.of(context).user!.id], + ), searchQuery: 'your query here', ); @@ -49,6 +52,9 @@ class _StreamMessageSearchState extends State { Widget build(BuildContext context) => Scaffold( body: StreamMessageSearchGridView( controller: _controller, + itemBuilder: (context, values, index) { + // return your custom widget here + }, ), ); } diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_list_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_list_view.mdx index ca4fd11e..e9048b04 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_list_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_search_list_view.mdx @@ -27,9 +27,9 @@ While the `StreamMessageListView` is tied to a certain `StreamChannel`, a `Strea ```dart class StreamMessageSearchPage extends StatefulWidget { const StreamMessageSearchPage({ - Key? key, + super.key, required this.client, - }) : super(key: key);` + }); final StreamChatClient client; @@ -41,7 +41,10 @@ class _StreamMessageSearchState extends State { late final _controller = StreamMessageSearchListController( client: widget.client, limit: 20, - filters: Filter.in_('members', [StreamChat.of(context).user!.id],), + filter: Filter.in_( + 'members', + [StreamChat.of(context).user!.id], + ), searchQuery: 'your query here', ); diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_widget.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_widget.mdx index 3e6cc867..f358676d 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_widget.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_widget.mdx @@ -25,8 +25,8 @@ a default implementation of the widget for us to modify. ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ - Key key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_grid_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_grid_view.mdx index d2fb953d..160ece9b 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_grid_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_grid_view.mdx @@ -21,9 +21,9 @@ Make sure to check the [StreamUserListView](./stream_user_list_view.mdx) documen ```dart class UserGridPage extends StatefulWidget { const UserGridPage({ - Key? key, + super.key, required this.client, - }) : super(key: key); + }); final StreamChatClient client; @@ -39,7 +39,7 @@ class _UserGridPageState extends State { Filter.notEqual('id', StreamChat.of(context).currentUser!.id), ]), sort: [ - SortOption( + const SortOption( 'name', direction: 1, ), @@ -58,12 +58,15 @@ class _UserGridPageState extends State { onRefresh: _controller.refresh, child: StreamUserGridView( controller: _controller, - onChannelTap: (channel) => Navigator.push( + onMemberTap: (member) => Navigator.push( context, MaterialPageRoute( - builder: (_) => StreamChannel( - channel: channel, - child: const ChannelPage(), + builder: (_) => Scaffold( + body: Center( + child: StreamUserAvatar( + user: member.user!, + ), + ), ), ), ), diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_list_view.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_list_view.mdx index f8fcbf2b..1a1e2eba 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_list_view.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_user_list_view.mdx @@ -24,7 +24,7 @@ Make sure to check the [StreamUserListController](../04-stream_chat_flutter_core ```dart class UserListPage extends StatefulWidget { - const UserListPage({Key? key}) : super(key: key); + const UserListPage({super.key}); @override State createState() => _UserListPageState(); @@ -66,7 +66,7 @@ You can use your own widget for the user items using the `itemBuilder` parameter StreamUsersListView( // ... itemBuilder: (context, users, index, defaultWidget) { - return Text(user[index].name); + return Text(users[index].name); }, ), ``` diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/lazy_load_scroll_view.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/lazy_load_scroll_view.mdx index 457f15c7..20fbb1b9 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/lazy_load_scroll_view.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/lazy_load_scroll_view.mdx @@ -35,7 +35,7 @@ LazyLoadScrollView( /// The child could be any widget which dispatches [ScrollNotification]s. /// For example [ListView], [GridView] or [CustomScrollView]. child: ListView.builder( - itemBuilder: ((context, index) => _buildListTile), + itemBuilder: (context, index) => _buildListTile, ), ) ``` diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/message_list_core.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/message_list_core.mdx index 2a20db92..37b0f306 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/message_list_core.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/message_list_core.mdx @@ -31,8 +31,8 @@ A `MessageListController` is used to paginate data. ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ - Key key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { @@ -42,20 +42,20 @@ class ChannelPage extends StatelessWidget { Expanded( child: MessageListCore( emptyBuilder: (context) { - return Center( + return const Center( child: Text('Nothing here...'), ); }, loadingBuilder: (context) { - return Center( + return const Center( child: CircularProgressIndicator(), ); }, messageListBuilder: (context, list) { return MessagesPage(list); }, - errorWidgetBuilder: (context, err) { - return Center( + errorBuilder: (context, err) { + return const Center( child: Text('Error'), ); }, diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/paged_value_listenable_builder.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/paged_value_listenable_builder.mdx index b527f7a0..a5f8f735 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/paged_value_listenable_builder.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/paged_value_listenable_builder.mdx @@ -65,7 +65,7 @@ class _MyHomePageState extends State { const Text('Usernames:'), Expanded( child: ListView( - children: userNames.map((it) => Text(it)).toList(), + children: userNames.map(Text.new).toList(), ), ), if (nextPageKey != null) @@ -75,7 +75,7 @@ class _MyHomePageState extends State { ), ], ), - loading: () => CircularProgressIndicator(), + loading: CircularProgressIndicator.new, error: (e) => Text('Error: $e'), ); }, diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_controller.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_controller.mdx index 6775ec02..9095ba4d 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_controller.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_controller.mdx @@ -25,7 +25,7 @@ First of all we should create an instance of the `StreamChannelListController` a You can also add a `Filter`, a list of `SortOption`s and other pagination-related parameters. ```dart -class ChannelListPageState extends State { +class _MyChannelListPageState extends State { /// Controller used for loading more data and controlling pagination in /// [StreamChannelListController]. late final channelListController = StreamChannelListController( @@ -40,6 +40,8 @@ class ChannelListPageState extends State { ), ]), ); + ... +} ``` Make sure you call `channelListController.doInitialLoad()` to load the initial data and `channelListController.dispose()` when the controller is no longer required. @@ -92,7 +94,7 @@ Widget build(BuildContext context) => Scaffold( child: Text(error.message), ); } - return CircularProgressIndicator(); + return const CircularProgressIndicator(); } final _item = channels[index]; diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_event_handler.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_event_handler.mdx index 043d41a1..8f6b7561 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_event_handler.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_channel_list_event_handler.mdx @@ -44,20 +44,11 @@ Pass it down to the controller: * Mix the `StreamChannelListEventHandler` into your widget state. ```dart -class _ChannelListPageState extends State - with StreamChannelListEventHandler { - - @override - void onConnectionRecovered( - Event event, - StreamChannelListController controller, - ) { - // Write your own custom implementation here - } +class _ChannelListPageState extends State { late final _listController = StreamChannelListController( client: StreamChat.of(context).client, - eventHandler: this, + eventHandler: MyCustomEventHandler(), ); } ``` diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_chat_core.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_chat_core.mdx index 11743abf..486b4fdf 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_chat_core.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_chat_core.mdx @@ -22,7 +22,7 @@ return MaterialApp( home: HomeScreen(), builder: (context, child) => StreamChatCore( client: client, - child: child!, + child: child, ), ); ``` diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_member_list_controller.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_member_list_controller.mdx index a811d77e..04401eb4 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_member_list_controller.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_member_list_controller.mdx @@ -26,7 +26,7 @@ class MemberListPageState extends State { /// Controller used for loading more data and controlling pagination in /// [StreamMemberListController]. late final memberListController = StreamMemberListController( - client: StreamChatCore.of(context).client, + channel: StreamChannel.of(context).channel, ); ``` @@ -52,7 +52,7 @@ You can use a [`PagedValueListenableBuilder`](./paged_value_listenable_builder.m ```dart @override Widget build(BuildContext context) => Scaffold( - body: PagedValueListenableBuilder>( + body: PagedValueListenableBuilder( valueListenable: memberListController, builder: (context, value, child) { return value.when( @@ -80,12 +80,12 @@ Widget build(BuildContext context) => Scaffold( child: Text(error.message), ); } - return CircularProgressIndicator(); + return const CircularProgressIndicator(); } final _item = members[index]; return ListTile( - title: Text(_item.name ?? ''), + title: Text(_item.user?.name ?? ''), ); }, ), diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_input_controller.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_input_controller.mdx index 9520f13c..c7f8971b 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_input_controller.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_input_controller.mdx @@ -47,7 +47,7 @@ Padding( children: [ Expanded( child: TextField( - controller: messageInputController.textEditingController, + controller: messageInputController.textFieldController, onChanged: (s) => messageInputController.text = s, decoration: const InputDecoration( hintText: 'Enter your message', @@ -66,7 +66,7 @@ Padding( messageInputController.message, ); messageInputController.clear(); - if (mounted) { + if (context.mounted) { _updateList(); } } diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_search_list_controller.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_search_list_controller.mdx index 00b9e7e9..40a0bd81 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_search_list_controller.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_message_search_list_controller.mdx @@ -59,8 +59,7 @@ Widget build(BuildContext context) => Scaffold( /// In a real-world app you should throttle the search requests. /// You can use our library [rate_limiter](https://pub.dev/packages/rate_limiter). onChanged: (s) { - messageSearchListController.searchQuery = s; - messageSearchListController.doInitialLoad(); + messageSearchListController..searchQuery = s..doInitialLoad(); }, ), Expanded( @@ -92,7 +91,7 @@ Widget build(BuildContext context) => Scaffold( child: Text(error.message), ); } - return CircularProgressIndicator(); + return const CircularProgressIndicator(); } final _item = responses[index]; diff --git a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_user_list_controller.mdx b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_user_list_controller.mdx index 84705d49..ec40bef2 100644 --- a/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_user_list_controller.mdx +++ b/docusaurus/docs/Flutter/04-stream_chat_flutter_core/stream_user_list_controller.mdx @@ -52,7 +52,7 @@ You can use a [`PagedValueListenableBuilder`](./paged_value_listenable_builder.m ```dart @override Widget build(BuildContext context) => Scaffold( - body: PagedValueListenableBuilder>( + body: PagedValueListenableBuilder( valueListenable: userListController, builder: (context, value, child) { return value.when( @@ -80,12 +80,12 @@ Widget build(BuildContext context) => Scaffold( child: Text(error.message), ); } - return CircularProgressIndicator(); + return const CircularProgressIndicator(); } final _item = users[index]; return ListTile( - title: Text(_item.name ?? ''), + title: Text(_item.name), ); }, ), diff --git a/docusaurus/docs/Flutter/05-guides/03-user_token_generation_with_firebase_auth.mdx b/docusaurus/docs/Flutter/05-guides/03-user_token_generation_with_firebase_auth.mdx index 85a0250d..4292f7fb 100644 --- a/docusaurus/docs/Flutter/05-guides/03-user_token_generation_with_firebase_auth.mdx +++ b/docusaurus/docs/Flutter/05-guides/03-user_token_generation_with_firebase_auth.mdx @@ -15,16 +15,16 @@ In this guide, you'll explore how you can use Firebase Auth as an authentication generate Stream Chat user tokens. You will use Stream's [NodeJS client](https://getstream.io/chat/docs/node/?language=javascript) for Stream account creation and -token generation, and [Flutter Cloud Functions for Firebase](https://firebase.flutter.dev/docs/functions/overview) to invoke the cloud functions +token generation, and [Flutter Cloud Functions for Firebase](https://firebase.google.com/docs/functions/callable?gen=2nd#dart) to invoke the cloud functions from your Flutter app. Stream supports several different [backend clients](https://getstream.io/chat/sdk/#backend-clients) to integrate with your server. This guide only shows an easy way to integrate Stream Chat authentication using Firebase and Flutter. ### Flutter Firebase -See the [Flutter Firebase getting started](https://firebase.flutter.dev/docs/overview) docs for setup and installation instructions. +See the [Flutter Firebase getting started](https://firebase.google.com/docs/flutter/setup) docs for setup and installation instructions. -You will also need to add the [Flutter Firebase Authentication](https://firebase.flutter.dev/docs/auth/overview), and [Flutter Firebase Cloud Functions](https://firebase.flutter.dev/docs/functions/overview) packages to your app. Depending on the platform that you target, there may be specific configurations that you need to do. +You will also need to add the [Flutter Firebase Authentication](https://firebase.google.com/docs/auth/flutter/start), and [Flutter Firebase Cloud Functions](https://firebase.google.com/docs/functions/callable?gen=2nd#dart) packages to your app. Depending on the platform that you target, there may be specific configurations that you need to do. #### Starting Code @@ -35,20 +35,20 @@ You will extend this later to execute cloud functions. ```dart import 'package:cloud_functions/cloud_functions.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_auth/firebase_auth.dart' as firebase_auth; import 'package:flutter/material.dart'; import 'dart:async'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( + return const MaterialApp( home: Scaffold( body: Auth(), ), @@ -57,20 +57,20 @@ class MyApp extends StatelessWidget { } class Auth extends StatefulWidget { - Auth({Key? key}) : super(key: key); + const Auth({super.key}); @override _AuthState createState() => _AuthState(); } class _AuthState extends State { - late FirebaseAuth auth; + late firebase_auth.FirebaseAuth auth; late FirebaseFunctions functions; @override void initState() { super.initState(); - auth = FirebaseAuth.instance; + auth = firebase_auth.FirebaseAuth.instance; functions = FirebaseFunctions.instance; } @@ -103,19 +103,26 @@ class _AuthState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ AuthenticationState( - streamUser: auth.authStateChanges(), + streamUser: auth.authStateChanges().map( + (firebaseUser) => firebaseUser != null + ? User( + id: firebaseUser.uid, + // Map other user fields here + ) + : null, + ), ), ElevatedButton( onPressed: createAccount, - child: Text('Create account'), + child: const Text('Create account'), ), ElevatedButton( onPressed: signIn, - child: Text('Sign in'), + child: const Text('Sign in'), ), ElevatedButton( onPressed: signOut, - child: Text('Sign out'), + child: const Text('Sign out'), ), ], ), @@ -125,9 +132,9 @@ class _AuthState extends State { class AuthenticationState extends StatelessWidget { const AuthenticationState({ - Key? key, + super.key, required this.streamUser, - }) : super(key: key); + }); final Stream streamUser; @@ -138,10 +145,10 @@ class AuthenticationState extends StatelessWidget { builder: (context, snapshot) { if (snapshot.hasData) { return (snapshot.data != null) - ? Text('Authenticated') - : Text('Not Authenticated'); + ? const Text('Authenticated') + : const Text('Not Authenticated'); } - return Text('Not Authenticated'); + return const Text('Not Authenticated'); }, ); } @@ -158,8 +165,8 @@ in the `createAccount`, `signIn` and `signOut` methods. There is a button to inv The `FirebaseFunctions.instance` will be used later in this guide. -The `AuthenticationState` widget listens to `auth.authStateChanges()` to display a message -indicating if a user is authenticated. +The `AuthenticationState`` widget listens to `auth.authStateChanges()` (mapped to Stream's `User`) +to display a message indicating if a user is authenticated. ### Firebase Cloud Functions @@ -168,7 +175,7 @@ Firebase Cloud Functions allows you to extend Firebase with custom operations th - **External event**: For example, directly calling a cloud function from your Flutter application. To set up your local environment to deploy cloud functions, please see the -[Cloud Functions getting started](https://firebase.flutter.dev/docs/overview) docs. +[Cloud Functions getting started](https://firebase.google.com/docs/flutter/setup) docs. After initializing your project with cloud functions, you should have a **functions** folder in your project, including a `package.json` file. diff --git a/docusaurus/docs/Flutter/05-guides/04-adding_localization.mdx b/docusaurus/docs/Flutter/05-guides/04-adding_localization.mdx index c6050d10..4f945693 100644 --- a/docusaurus/docs/Flutter/05-guides/04-adding_localization.mdx +++ b/docusaurus/docs/Flutter/05-guides/04-adding_localization.mdx @@ -61,6 +61,10 @@ void main() { } class MyApp extends StatelessWidget { + + // Setup client and channel code here + ... + @override Widget build(BuildContext context) { return MaterialApp( diff --git a/docusaurus/docs/Flutter/05-guides/05-push-notifications/adding_push_notifications_v2.mdx b/docusaurus/docs/Flutter/05-guides/05-push-notifications/adding_push_notifications_v2.mdx index c440daaf..b57618b8 100644 --- a/docusaurus/docs/Flutter/05-guides/05-push-notifications/adding_push_notifications_v2.mdx +++ b/docusaurus/docs/Flutter/05-guides/05-push-notifications/adding_push_notifications_v2.mdx @@ -208,9 +208,9 @@ void handleNotification( flutterLocalNotificationsPlugin.show( 1, - 'New message from ${response.message.user.name} in ${response.channel.name}', + 'New message from ${response.message.user!.name} in ${response.channel!.name}', response.message.text, - NotificationDetails( + const NotificationDetails( android: AndroidNotificationDetails( 'new_message', 'New message notifications channel', @@ -255,7 +255,7 @@ Make sure to read the [general push notification docs](https://getstream.io/chat If you're not sure whether you've set up push notifications correctly, for example, you don't always receive them, or they don’t work reliably, then you can follow these steps to make sure your configuration is correct and working: 1. Clone our repository for push testing: `git clone git@github.com:GetStream/chat-push-test.git` -2. `cd flutter` +2. `cd chat-push-test/flutter` 3. In that folder run `flutter pub get` 4. Input your API key and secret in `lib/main.dart` 5. Change the bundle identifier/application ID and development team/user so you can run the app on your physical device.**Do not** run on an iOS simulator, as it will not work. Testing on an Android emulator is fine. From d7f518ca027872a47e3764e182c8b72a29dd12a3 Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Thu, 12 Oct 2023 15:36:10 +0300 Subject: [PATCH 02/14] Update docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx Co-authored-by: Deven Joshi --- .../01-custom-widgets/01-customize_message_widget.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx index e37debbc..405de137 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/01-customize_message_widget.mdx @@ -21,7 +21,7 @@ provided inside the `messageBuilder` parameter of the `StreamMessageListView` li ```dart StreamMessageListView( messageBuilder: (context, details, messageList, defaultImpl) { - return defaultWidget.copyWith( + return defaultImpl.copyWith( ... ); }, From 23644132144b9db69c5fba7e6310e7120337b0ce Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Thu, 12 Oct 2023 16:18:39 +0300 Subject: [PATCH 03/14] Update: switch back to theme colors --- .../01-custom-widgets/04-adding_custom_attachments.mdx | 6 +++--- .../Flutter/03-stream_chat_flutter/stream_message_input.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx index 18c15f49..2954523b 100644 --- a/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx +++ b/docusaurus/docs/Flutter/02-customization/01-custom-widgets/04-adding_custom_attachments.mdx @@ -65,7 +65,7 @@ StreamMessageInput( child: const Icon( Icons.location_on, size: 20, - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.textLowEmphasis, ), onTap: () { final channel = StreamChannel.of(context).channel; @@ -193,7 +193,7 @@ First, we add the attachment when the location button is clicked: child: Icon( Icons.location_on, size: 20, - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.textLowEmphasis, ), onTap: () { _determinePosition().then((value) { @@ -226,7 +226,7 @@ StreamMessageInput( child: Icon( Icons.location_on, size: 20, - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.textLowEmphasis, ), onTap: () { _determinePosition().then((value) { diff --git a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx index 8610d5e2..45c399a9 100644 --- a/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx +++ b/docusaurus/docs/Flutter/03-stream_chat_flutter/stream_message_input.mdx @@ -72,7 +72,7 @@ StreamMessageInput( child: Icon( Icons.location_on, size: 20, - color: Colors.grey, + color: StreamChatTheme.of(context).colorTheme.textLowEmphasis, ), onTap: () { // Do something here From 844df206178c7053d8297db80072d64170b01d06 Mon Sep 17 00:00:00 2001 From: Kanat Kiialbaev Date: Mon, 23 Oct 2023 00:19:32 -0700 Subject: [PATCH 04/14] fix(core): video attachment upload (#1754) * fix video attachment upload * fix test * add changelog --- .../lib/src/core/http/stream_http_client_options.dart | 8 ++++---- .../src/core/http/stream_http_client_options_test.dart | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart index d68e073f..ad18c254 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart @@ -7,8 +7,8 @@ class StreamHttpClientOptions { /// Instantiates a new [StreamHttpClientOptions] const StreamHttpClientOptions({ String? baseUrl, - this.connectTimeout = const Duration(seconds: 6), - this.receiveTimeout = const Duration(seconds: 6), + this.connectTimeout = const Duration(seconds: 30), + this.receiveTimeout = const Duration(seconds: 30), this.queryParameters = const {}, this.headers = const {}, }) : baseUrl = baseUrl ?? _defaultBaseURL; @@ -16,10 +16,10 @@ class StreamHttpClientOptions { /// base url to use with client. final String baseUrl; - /// connect timeout, default to 6s + /// connect timeout, default to 30s final Duration connectTimeout; - /// received timeout, default to 6s + /// received timeout, default to 30s final Duration receiveTimeout; /// Common query parameters. diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart index 1ed0e5ab..0a54c00a 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart @@ -5,8 +5,8 @@ void main() { test('should return the all default set params', () { const options = StreamHttpClientOptions(); expect(options.baseUrl, 'https://chat.stream-io-api.com'); - expect(options.connectTimeout, const Duration(seconds: 6)); - expect(options.receiveTimeout, const Duration(seconds: 6)); + expect(options.connectTimeout, const Duration(seconds: 30)); + expect(options.receiveTimeout, const Duration(seconds: 30)); expect(options.queryParameters, const {}); expect(options.headers, const {}); }); diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index c8facc3d..23ad62ef 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,9 @@ +## UNRELEASED + +🐞 Fixed + +- Fixed video attachment uploading. [#1754](https://github.com/GetStream/stream-chat-flutter/pull/1754) + ## 6.10.0 - Added mixin support to `StreamChannelListEventHandler`. From 354ae323b2cef03596d1d126f8188e500f8e8ce5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:02:26 +0200 Subject: [PATCH 05/14] chore(repo): bump connectivity_plus (#1750) Bumps [connectivity_plus](https://github.com/fluttercommunity/plus_plugins/tree/main/packages/connectivity_plus) from 4.0.2 to 5.0.1. - [Release notes](https://github.com/fluttercommunity/plus_plugins/releases) - [Commits](https://github.com/fluttercommunity/plus_plugins/commits/connectivity_plus-v5.0.1/packages/connectivity_plus) --- updated-dependencies: - dependency-name: connectivity_plus dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Efthymis Sarmpanis --- packages/stream_chat_flutter_core/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index 47e3142e..f3e1124b 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -11,7 +11,7 @@ environment: dependencies: collection: ^1.17.1 - connectivity_plus: ^4.0.2 + connectivity_plus: ">=4.0.2 <6.0.0" flutter: sdk: flutter freezed_annotation: ^2.4.1 From 2de5b3eaa6b3c496a2bc3d856e82eb88c7e2f88b Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Thu, 2 Nov 2023 11:45:07 +0200 Subject: [PATCH 06/14] fix(doc): update the use of GoRouter in the guides --- .../09-initialize_stream_chat_widget_tree.mdx | 76 ++++++++++--------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/docusaurus/docs/Flutter/05-guides/09-initialize_stream_chat_widget_tree.mdx b/docusaurus/docs/Flutter/05-guides/09-initialize_stream_chat_widget_tree.mdx index 645e38bd..0f1bd86f 100644 --- a/docusaurus/docs/Flutter/05-guides/09-initialize_stream_chat_widget_tree.mdx +++ b/docusaurus/docs/Flutter/05-guides/09-initialize_stream_chat_widget_tree.mdx @@ -489,47 +489,51 @@ class _MyAppState extends State { late final _router = GoRouter( initialLocation: '/', - navigatorBuilder: (context, state, child) { - if (state.location.startsWith('/chat')) { - wasPreviousRouteChat = true; - return StreamChat( - client: _client, - child: ChatSetup(client: _client, child: child), - ); - } else { - if (wasPreviousRouteChat) { - wasPreviousRouteChat = false; - return StreamChat( - client: _client, - child: child, - ); - } else { - return child; - } - } - }, routes: [ - GoRoute( - path: '/', - builder: (context, state) => const HomeScreen(), + ShellRoute( + builder: (context, state, child) { + if (state.uri.host.startsWith('/chat')) { + wasPreviousRouteChat = true; + return StreamChat( + client: _client, + child: ChatSetup(client: _client, child: child), + ); + } else { + if (wasPreviousRouteChat) { + wasPreviousRouteChat = false; + return StreamChat( + client: _client, + child: child, + ); + } else { + return child; + } + } + }, routes: [ GoRoute( - path: 'settings', - builder: (context, state) => const SettingsPage(), - ), - GoRoute( - path: 'chat', - builder: (context, state) => const ChannelListPage(), + path: '/', + builder: (context, state) => const HomeScreen(), routes: [ GoRoute( - path: 'channel', - builder: (context, state) { - final channel = state.extra as Channel; - return StreamChannel( - channel: channel, - child: const ChannelPage(), - ); - }, + path: 'settings', + builder: (context, state) => const SettingsPage(), + ), + GoRoute( + path: 'chat', + builder: (context, state) => const ChannelListPage(), + routes: [ + GoRoute( + path: 'channel', + builder: (context, state) { + final channel = state.extra as Channel; + return StreamChannel( + channel: channel, + child: const ChannelPage(), + ); + }, + ), + ], ), ], ), From 02d686cc7555de32a8b8f80deb46e9d0a43b27fd Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Wed, 1 Nov 2023 18:40:43 +0200 Subject: [PATCH 07/14] fix(ui): deprecate exposed `showReactionPickerTail` in `MessageWidget` `showReactionPickerTail` property is bind with `showReactionPicker` as it is the only one needed to couple the reaction modal with the tail Closes #1759 --- packages/stream_chat_flutter/CHANGELOG.md | 7 ++ .../src/message_widget/message_widget.dart | 18 ++-- .../message_actions_modal_test.dart | 95 +++++++++++++++++++ .../stream_chat_flutter/test/src/mocks.dart | 10 +- 4 files changed, 118 insertions(+), 12 deletions(-) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 95434934..eab50c35 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,10 @@ +# Upcoming + +🐞 Fixed + +- [[#1759]](https://github.com/GetStream/stream-chat-flutter/issues/1759) Fixed + The Reaction Picker is not being removed when I set showReactionPicker to false. + # 6.11.0 🐞 Fixed diff --git a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart index c038cf02..92d0889a 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart @@ -60,7 +60,9 @@ class StreamMessageWidget extends StatefulWidget { bool? showReactionPicker, @Deprecated('Use `showReactionPicker` instead') bool showReactionPickerIndicator = true, - @internal this.showReactionPickerTail = false, + @internal + @Deprecated('Use `showReactionPicker` instead') + this.showReactionPickerTail, this.showUserAvatar = DisplayWidget.show, this.showSendingIndicator = true, this.showThreadReplyIndicator = false, @@ -483,7 +485,8 @@ class StreamMessageWidget extends StatefulWidget { /// Whether or not to show the reaction picker tail /// {@endtemplate} @internal - final bool showReactionPickerTail; + @Deprecated('Use `showReactionPicker` instead') + final bool? showReactionPickerTail; /// {@template onShowMessage} /// Callback when show message is tapped @@ -743,8 +746,6 @@ class StreamMessageWidget extends StatefulWidget { showReactionPicker: showReactionPicker ?? showReactionPickerIndicator ?? this.showReactionPicker, - showReactionPickerTail: - showReactionPickerTail ?? this.showReactionPickerTail, onShowMessage: onShowMessage ?? this.onShowMessage, showUsername: showUsername ?? this.showUsername, showTimestamp: showTimestamp ?? this.showTimestamp, @@ -1002,7 +1003,7 @@ class _StreamMessageWidgetState extends State messageWidget: widget, showBottomRow: showBottomRow, showPinHighlight: widget.showPinHighlight, - showReactionPickerTail: widget.showReactionPickerTail, + showReactionPickerTail: widget.showReactionPicker, showReactions: showReactions, onReactionsTap: () { widget.onReactionsTap != null @@ -1217,7 +1218,8 @@ class _StreamMessageWidgetState extends State translateUserAvatar: false, showSendingIndicator: false, padding: EdgeInsets.zero, - // Show the tail if the reaction picker is visible. + // Show both the tail if the picker is shown. + showReactionPicker: widget.showReactionPicker, showReactionPickerTail: widget.showReactionPicker, showPinHighlight: false, showUserAvatar: @@ -1258,6 +1260,7 @@ class _StreamMessageWidgetState extends State return StreamChannel( channel: channel, child: MessageActionsModal( + showReactionPicker: widget.showReactionPicker, messageWidget: widget.copyWith( key: const Key('MessageWidget'), message: widget.message.copyWith( @@ -1271,9 +1274,6 @@ class _StreamMessageWidgetState extends State translateUserAvatar: false, showSendingIndicator: false, padding: EdgeInsets.zero, - // Show both the tail if the picker is shown. - showReactionPicker: widget.showReactionPicker, - showReactionPickerTail: widget.showReactionPicker, showPinHighlight: false, showUserAvatar: widget.message.user!.id == channel.client.state.currentUser!.id diff --git a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart index 0dd0e118..05263cab 100644 --- a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart +++ b/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart @@ -64,6 +64,101 @@ void main() { }, ); + testWidgets( + 'it should show the reaction picker', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel( + ownCapabilities: ['send-message', 'send-reaction'], + ); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + + final themeData = ThemeData(); + final streamTheme = StreamChatThemeData.fromTheme(themeData); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: StreamChat( + streamChatThemeData: streamTheme, + client: client, + child: SizedBox( + child: StreamChannel( + channel: channel, + child: MessageActionsModal( + message: Message( + text: 'test', + user: User( + id: 'user-id', + ), + state: MessageState.sent, + ), + messageWidget: const Text( + 'test', + key: Key('MessageWidget'), + ), + messageTheme: streamTheme.ownMessageTheme, + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(find.byType(StreamReactionPicker), findsOneWidget); + }, + ); + + testWidgets( + 'it should not show the reaction picker', + (WidgetTester tester) async { + final client = MockClient(); + final clientState = MockClientState(); + final channel = MockChannel(); + + when(() => client.state).thenReturn(clientState); + when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id')); + + final themeData = ThemeData(); + final streamTheme = StreamChatThemeData.fromTheme(themeData); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: StreamChat( + streamChatThemeData: streamTheme, + client: client, + child: SizedBox( + child: StreamChannel( + channel: channel, + child: MessageActionsModal( + showReactionPicker: false, + message: Message( + text: 'test', + user: User( + id: 'user-id', + ), + state: MessageState.sent, + ), + messageWidget: const Text( + 'test', + key: Key('MessageWidget'), + ), + messageTheme: streamTheme.ownMessageTheme, + ), + ), + ), + ), + ), + ); + await tester.pumpAndSettle(); + + expect(find.byType(StreamReactionPicker), findsNothing); + }, + ); + testWidgets( 'it should show some actions', (WidgetTester tester) async { diff --git a/packages/stream_chat_flutter/test/src/mocks.dart b/packages/stream_chat_flutter/test/src/mocks.dart index c8e1a4b4..1f7ddbd9 100644 --- a/packages/stream_chat_flutter/test/src/mocks.dart +++ b/packages/stream_chat_flutter/test/src/mocks.dart @@ -14,6 +14,13 @@ class MockClient extends Mock implements StreamChatClient { class MockClientState extends Mock implements ClientState {} class MockChannel extends Mock implements Channel { + MockChannel({ + this.ownCapabilities = const ['send-message'], + }); + + @override + final List ownCapabilities; + @override Future get initialized async => true; @@ -22,9 +29,6 @@ class MockChannel extends Mock implements Channel { Future keyStroke([String? parentId]) async { return; } - - @override - List get ownCapabilities => ['send-message']; } class MockChannelState extends Mock implements ChannelClientState { From c1b5b2609d15ddf282d6904abb7fe69711620e40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:56:52 +0000 Subject: [PATCH 08/14] chore(deps): bump file_picker in /packages/stream_chat_flutter Bumps [file_picker](https://github.com/miguelpruivo/flutter_file_picker) from 5.5.0 to 6.1.1. - [Release notes](https://github.com/miguelpruivo/flutter_file_picker/releases) - [Changelog](https://github.com/miguelpruivo/flutter_file_picker/blob/master/CHANGELOG.md) - [Commits](https://github.com/miguelpruivo/flutter_file_picker/commits) --- updated-dependencies: - dependency-name: file_picker dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- packages/stream_chat_flutter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 1f4390a4..9dcbb4ff 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: diacritic: ^0.1.4 dio: ^5.3.2 ezanimation: ^0.6.0 - file_picker: ^5.3.3 + file_picker: ">=5.3.3 <7.0.0" file_selector: ^1.0.0 flutter: sdk: flutter From d176ab6713ced3fc93c5357e539e3128cbf1331d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:57:52 +0000 Subject: [PATCH 09/14] chore(deps): bump amannn/action-semantic-pull-request Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/amannn/action-semantic-pull-request/releases) - [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/main/CHANGELOG.md) - [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v5.3.0...v5.4.0) --- updated-dependencies: - dependency-name: amannn/action-semantic-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/pr_title.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_title.yml b/.github/workflows/pr_title.yml index 94f96b8a..28b7f238 100644 --- a/.github/workflows/pr_title.yml +++ b/.github/workflows/pr_title.yml @@ -16,7 +16,7 @@ jobs: conventional_pr_title: runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v5.3.0 + - uses: amannn/action-semantic-pull-request@v5.4.0 with: scopes: | llc From e2f9afe117111ffdb516c47e22e50ea78357cb4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:15:45 +0000 Subject: [PATCH 10/14] chore(deps): bump VeryGoodOpenSource/very_good_coverage Bumps [VeryGoodOpenSource/very_good_coverage](https://github.com/verygoodopensource/very_good_coverage) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/verygoodopensource/very_good_coverage/releases) - [Changelog](https://github.com/VeryGoodOpenSource/very_good_coverage/blob/main/CHANGELOG.md) - [Commits](https://github.com/verygoodopensource/very_good_coverage/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: VeryGoodOpenSource/very_good_coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/stream_flutter_workflow.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/stream_flutter_workflow.yml b/.github/workflows/stream_flutter_workflow.yml index 5665818f..3067cf40 100644 --- a/.github/workflows/stream_flutter_workflow.yml +++ b/.github/workflows/stream_flutter_workflow.yml @@ -106,27 +106,27 @@ jobs: token: ${{secrets.CODECOV_TOKEN}} files: packages/*/coverage/lcov.info - name: "Stream Chat Coverage Check" - uses: VeryGoodOpenSource/very_good_coverage@v2.1.0 + uses: VeryGoodOpenSource/very_good_coverage@v2.2.0 with: path: packages/stream_chat/coverage/lcov.info min_coverage: 79 - name: "Stream Chat Localizations Coverage Check" - uses: VeryGoodOpenSource/very_good_coverage@v2.1.0 + uses: VeryGoodOpenSource/very_good_coverage@v2.2.0 with: path: packages/stream_chat_localizations/coverage/lcov.info min_coverage: 100 - name: "Stream Chat Persistence Coverage Check" - uses: VeryGoodOpenSource/very_good_coverage@v2.1.0 + uses: VeryGoodOpenSource/very_good_coverage@v2.2.0 with: path: packages/stream_chat_persistence/coverage/lcov.info min_coverage: 95 - name: "Stream Chat Flutter Core Coverage Check" - uses: VeryGoodOpenSource/very_good_coverage@v2.1.0 + uses: VeryGoodOpenSource/very_good_coverage@v2.2.0 with: path: packages/stream_chat_flutter_core/coverage/lcov.info min_coverage: 30 - name: "Stream Chat Flutter Coverage Check" - uses: VeryGoodOpenSource/very_good_coverage@v2.1.0 + uses: VeryGoodOpenSource/very_good_coverage@v2.2.0 with: path: packages/stream_chat_flutter/coverage/lcov.info min_coverage: 44 From ac64e223c6133d6b3cba9da420a2216e4b101bb0 Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Fri, 24 Nov 2023 13:16:19 +0200 Subject: [PATCH 11/14] chore(repo): lock the flutter version of pipelines --- .github/workflows/stream_flutter_workflow.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/stream_flutter_workflow.yml b/.github/workflows/stream_flutter_workflow.yml index 5665818f..11e68ec7 100644 --- a/.github/workflows/stream_flutter_workflow.yml +++ b/.github/workflows/stream_flutter_workflow.yml @@ -3,6 +3,7 @@ name: stream_flutter_workflow env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' flutter_channel: "stable" + flutter_version: "3.10.6" on: pull_request: @@ -36,6 +37,7 @@ jobs: - name: "Install Flutter" uses: subosito/flutter-action@v2 with: + flutter-version: ${{ env.flutter_version }} cache: true channel: ${{ env.flutter_channel }} - name: "Install Tools" @@ -63,6 +65,7 @@ jobs: - name: "Install Flutter" uses: subosito/flutter-action@v2 with: + flutter-version: ${{ env.flutter_version }} cache: true channel: ${{ env.flutter_channel }} - name: "Install Tools" @@ -88,6 +91,7 @@ jobs: - name: "Install Flutter" uses: subosito/flutter-action@v2 with: + flutter-version: ${{ env.flutter_version }} cache: true channel: ${{ env.flutter_channel }} - name: "Install Tools" From 3b1be70b107f19499752c462193cde8ed970056b Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Fri, 24 Nov 2023 13:22:29 +0200 Subject: [PATCH 12/14] fix(repo): fix broken test --- .../test/src/core/http/stream_http_client_test.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart index f63e08f1..2ddc84e3 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart @@ -164,7 +164,8 @@ void main() { expect( e.message, "The connection errored: Dio can't establish a new connection" - ' after it was closed.', + ' after it was closed. This indicates an error which most likely' + ' cannot be solved by the library.', ); } }); From 0d7559e3d8d96b78ab6b7618d4ace73c52d23c3d Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Thu, 23 Nov 2023 12:52:34 +0200 Subject: [PATCH 13/14] fix(llc): when removing current user from channel check for null in the callback Closes #1753 --- packages/stream_chat/CHANGELOG.md | 2 + .../stream_chat/lib/src/client/client.dart | 2 +- .../example/lib/debug/actions/add_user.dart | 47 +++++++++++++++++++ .../lib/debug/actions/remove_user.dart | 47 +++++++++++++++++++ .../example/lib/debug/channel_page.dart | 6 +++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 packages/stream_chat_flutter/example/lib/debug/actions/add_user.dart create mode 100644 packages/stream_chat_flutter/example/lib/debug/actions/remove_user.dart diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index c1537e5c..88f3ee19 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -6,6 +6,8 @@ update message with `type: reply`. - [[#1724]](https://github.com/GetStream/stream-chat-flutter/issues/1724) Fixed sendFile error on `AttachmentFile` with `bytes` and no `name`. +- [[#1753]](https://github.com/GetStream/stream-chat-flutter/issues/1753) Fixed Unhandled null + check operator exception when user is removed from a channel. ## 6.8.0 diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 4e4fc5e4..79bf1741 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1658,7 +1658,7 @@ class ClientState { ) .listen((event) async { final isCurrentUser = event.user!.id == currentUser!.id; - if (isCurrentUser) { + if (isCurrentUser && event.channel != null) { final eventChannel = event.channel!; await _client.chatPersistenceClient ?.deleteChannels([eventChannel.cid]); diff --git a/packages/stream_chat_flutter/example/lib/debug/actions/add_user.dart b/packages/stream_chat_flutter/example/lib/debug/actions/add_user.dart new file mode 100644 index 00000000..74fe2624 --- /dev/null +++ b/packages/stream_chat_flutter/example/lib/debug/actions/add_user.dart @@ -0,0 +1,47 @@ +// ignore_for_file: public_member_api_docs + +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import 'package:stream_chat_flutter_example/debug/error_dialog.dart'; + +class DebugAddUser extends StatelessWidget { + const DebugAddUser({ + super.key, + required this.client, + required this.channel, + }); + + final StreamChatClient client; + final Channel channel; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8), + child: TextField( + decoration: const InputDecoration( + labelText: 'Add User', + hintText: 'User Id', + isDense: true, + border: OutlineInputBorder(), + ), + onSubmitted: (value) async { + final userId = value.trim(); + try { + debugPrint('[addUser] userId: $userId'); + final result = await client.addChannelMembers( + channel.id!, + channel.type, + [userId], + ); + debugPrint('[addUser] result: $result'); + } catch (e) { + debugPrint('[addUser] failed: $e'); + showErrorDialog(context, e, 'Add User'); + } + }, + ), + ); + } +} diff --git a/packages/stream_chat_flutter/example/lib/debug/actions/remove_user.dart b/packages/stream_chat_flutter/example/lib/debug/actions/remove_user.dart new file mode 100644 index 00000000..9aee373c --- /dev/null +++ b/packages/stream_chat_flutter/example/lib/debug/actions/remove_user.dart @@ -0,0 +1,47 @@ +// ignore_for_file: public_member_api_docs + +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import 'package:stream_chat_flutter_example/debug/error_dialog.dart'; + +class DebugRemoveUser extends StatelessWidget { + const DebugRemoveUser({ + super.key, + required this.client, + required this.channel, + }); + + final StreamChatClient client; + final Channel channel; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8), + child: TextField( + decoration: const InputDecoration( + labelText: 'Remove User', + hintText: 'User Id', + isDense: true, + border: OutlineInputBorder(), + ), + onSubmitted: (value) async { + final userId = value.trim(); + try { + debugPrint('[removeUser] userId: $userId'); + final result = await client.removeChannelMembers( + channel.id!, + channel.type, + [userId], + ); + debugPrint('[removeUser] result: $result'); + } catch (e) { + debugPrint('[removeUser] failed: $e'); + showErrorDialog(context, e, 'Remove User'); + } + }, + ), + ); + } +} diff --git a/packages/stream_chat_flutter/example/lib/debug/channel_page.dart b/packages/stream_chat_flutter/example/lib/debug/channel_page.dart index b5e93cf5..a1d4b6a4 100644 --- a/packages/stream_chat_flutter/example/lib/debug/channel_page.dart +++ b/packages/stream_chat_flutter/example/lib/debug/channel_page.dart @@ -4,9 +4,11 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; +import 'package:stream_chat_flutter_example/debug/actions/add_user.dart'; import 'package:stream_chat_flutter_example/debug/actions/ban_user.dart'; import 'package:stream_chat_flutter_example/debug/actions/mute_user.dart'; import 'package:stream_chat_flutter_example/debug/actions/remove_shadow_ban.dart'; +import 'package:stream_chat_flutter_example/debug/actions/remove_user.dart'; import 'package:stream_chat_flutter_example/debug/actions/shadow_ban.dart'; import 'package:stream_chat_flutter_example/debug/actions/unban_user.dart'; import 'package:stream_chat_flutter_example/debug/actions/unmute_user.dart'; @@ -82,6 +84,10 @@ class _DebugChannelPageState extends State { DebugShadowBan(client: _channel.client), const SizedBox(height: 8), DebugRemoveShadowBan(client: _channel.client), + const SizedBox(height: 8), + DebugAddUser(client: _channel.client, channel: _channel), + const SizedBox(height: 8), + DebugRemoveUser(client: _channel.client, channel: _channel), ], ), ), From 6d22158b34c659d749ca00d4b6067a23a2ad318c Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Fri, 24 Nov 2023 14:14:34 +0200 Subject: [PATCH 14/14] Release: v6.12.0 --- packages/stream_chat/CHANGELOG.md | 9 +++++++-- packages/stream_chat/lib/version.dart | 2 +- packages/stream_chat/pubspec.yaml | 2 +- packages/stream_chat_flutter/CHANGELOG.md | 2 +- packages/stream_chat_flutter/pubspec.yaml | 4 ++-- packages/stream_chat_flutter_core/CHANGELOG.md | 2 +- packages/stream_chat_flutter_core/pubspec.yaml | 4 ++-- packages/stream_chat_localizations/CHANGELOG.md | 4 ++++ packages/stream_chat_localizations/pubspec.yaml | 4 ++-- packages/stream_chat_persistence/CHANGELOG.md | 4 ++++ packages/stream_chat_persistence/pubspec.yaml | 4 ++-- 11 files changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 88f3ee19..142b5977 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,10 @@ +# 6.10.0 + +🐞 Fixed + +- [[#1753]](https://github.com/GetStream/stream-chat-flutter/issues/1753) Fixed Unhandled null + check operator exception when user is removed from a channel. + ## 6.9.0 🐞 Fixed @@ -6,8 +13,6 @@ update message with `type: reply`. - [[#1724]](https://github.com/GetStream/stream-chat-flutter/issues/1724) Fixed sendFile error on `AttachmentFile` with `bytes` and no `name`. -- [[#1753]](https://github.com/GetStream/stream-chat-flutter/issues/1753) Fixed Unhandled null - check operator exception when user is removed from a channel. ## 6.8.0 diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index 18b77e8d..469f80df 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -3,4 +3,4 @@ import 'package:stream_chat/src/client/client.dart'; /// Current package version /// Used in [StreamChatClient] to build the `x-stream-client` header // ignore: constant_identifier_names -const PACKAGE_VERSION = '6.9.0'; +const PACKAGE_VERSION = '6.10.0'; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 458cbd14..107f5c44 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat homepage: https://getstream.io/ description: The official Dart client for Stream Chat, a service for building chat applications. -version: 6.9.0 +version: 6.10.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index eab50c35..c3a93e66 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -# Upcoming +# 6.12.0 🐞 Fixed diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 1f4390a4..9a9d228e 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter. -version: 6.11.0 +version: 6.12.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -38,7 +38,7 @@ dependencies: rxdart: ^0.27.7 share_plus: ^7.1.0 shimmer: ^3.0.0 - stream_chat_flutter_core: ^6.10.0 + stream_chat_flutter_core: ^6.11.0 synchronized: ^3.1.0 thumblr: ^0.0.4 url_launcher: ^6.1.12 diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 23ad62ef..a68bb7a6 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,4 +1,4 @@ -## UNRELEASED +## 6.11.0 🐞 Fixed diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index f3e1124b..e16ded8f 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_flutter_core homepage: https://github.com/GetStream/stream-chat-flutter description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter. -version: 6.10.0 +version: 6.11.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -17,7 +17,7 @@ dependencies: freezed_annotation: ^2.4.1 meta: ^1.9.1 rxdart: ^0.27.7 - stream_chat: ^6.9.0 + stream_chat: ^6.10.0 dev_dependencies: build_runner: ^2.4.6 diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 35b78698..92519d7f 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.12.0 + +* Updated `stream_chat_flutter` dependency to [`6.12.0`](https://pub.dev/packages/stream_chat_flutter/changelog). + ## 5.11.0 * Updated `stream_chat_flutter` dependency to [`6.11.0`](https://pub.dev/packages/stream_chat_flutter/changelog). diff --git a/packages/stream_chat_localizations/pubspec.yaml b/packages/stream_chat_localizations/pubspec.yaml index 5daf3735..2b415c45 100644 --- a/packages/stream_chat_localizations/pubspec.yaml +++ b/packages/stream_chat_localizations/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_chat_localizations description: The Official localizations for Stream Chat Flutter, a service for building chat applications -version: 5.11.0 +version: 5.12.0 homepage: https://github.com/GetStream/stream-chat-flutter repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -14,7 +14,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - stream_chat_flutter: ^6.11.0 + stream_chat_flutter: ^6.12.0 dev_dependencies: flutter_test: diff --git a/packages/stream_chat_persistence/CHANGELOG.md b/packages/stream_chat_persistence/CHANGELOG.md index 3fe32092..51622650 100644 --- a/packages/stream_chat_persistence/CHANGELOG.md +++ b/packages/stream_chat_persistence/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.10.0 + +- Updated `stream_chat` dependency to [`6.10.0`](https://pub.dev/packages/stream_chat/changelog). + ## 6.9.0 - Updated `stream_chat` dependency to [`6.9.0`](https://pub.dev/packages/stream_chat/changelog). diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index fc4e85eb..38d7537a 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -1,7 +1,7 @@ name: stream_chat_persistence homepage: https://github.com/GetStream/stream-chat-flutter description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter. -version: 6.9.0 +version: 6.10.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -18,7 +18,7 @@ dependencies: path: ^1.8.3 path_provider: ^2.1.0 sqlite3_flutter_libs: ^0.5.15 - stream_chat: ^6.9.0 + stream_chat: ^6.10.0 dev_dependencies: build_runner: ^2.4.6