diff --git a/CHANGELOG.md b/CHANGELOG.md index d0c72144..eb83c19a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## 0.2.1+2 + +- Update llc dependency + +## 0.2.1+1 + +- Update llc dependency + +## 0.2.1 + +- Better ui components +- Add read indicators +- Add system messages +- Use llc 0.2 +- Add `ChannelsBloc` widget to manage a list of channels with pagination + +## 0.2.1-alpha+11 + +- Update llc dependency + +## 0.2.1-alpha+10 + +- Update llc dependency + ## 0.2.1-alpha+9 - Add read indicators diff --git a/README.md b/README.md index 9049b4c0..d2bd5dd6 100644 --- a/README.md +++ b/README.md @@ -33,19 +33,11 @@ The example is available under the [example](https://github.com/GetStream/stream ```yaml dependencies: - stream_chat_flutter: ^0.1.19 + stream_chat_flutter: ^0.2.1 ``` You should then run `flutter packages get` -### Alpha version - -Use version `^0.2.0-alpha+2` to use the latest available version. - -Note that this is still an alpha version. There may be some bugs, and the API can change in breaking ways. - -Thanks to whoever tries these versions and reports bugs or suggestions. - ### Android All set ✅ @@ -86,6 +78,7 @@ Every widget uses the `StreamChat` or `StreamChannel` widgets to manage the stat - [MessageWidget](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/MessageWidget-class.html) - [StreamChatTheme](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamChatTheme-class.html) - [ThreadHeader](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/ThreadHeader-class.html) +- ... ### Customizing styles @@ -109,14 +102,13 @@ Out of the box, all chat widgets use their default styling, and there are two wa return MaterialApp( theme: theme, - home: Container( - child: StreamChat( - streamChatThemeData: StreamChatThemeData.fromTheme(theme), - client: client, - child: ChannelListPage(), - ), + builder: (context, child) => StreamChat( + child: child, + client: client, + streamChatThemeData: StreamChatThemeData.fromTheme(theme), ), - ); + home: ChannelListPage(), + ); } } ``` @@ -136,24 +128,23 @@ Out of the box, all chat widgets use their default styling, and there are two wa return MaterialApp( theme: theme, - home: Container( - child: StreamChat( - streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith( - ownMessageTheme: MessageTheme( - messageBackgroundColor: Colors.black, - messageText: TextStyle( - color: Colors.white, - ), - avatarTheme: AvatarTheme( - borderRadius: BorderRadius.circular(8), - ), - ), + builder: (context, child) => StreamChat( + child: child, + client: client, + streamChatThemeData: StreamChatThemeData.fromTheme(theme).copyWith( + ownMessageTheme: MessageTheme( + messageBackgroundColor: Colors.black, + messageText: TextStyle( + color: Colors.white, ), - client: client, - child: ChannelListPage(), - ), + avatarTheme: AvatarTheme( + borderRadius: BorderRadius.circular(8), + ), + ), + ), ), - ); + home: ChannelListPage(), + ); } } ``` diff --git a/example/lib/customize_channel_preview.dart b/example/lib/customize_channel_preview.dart index 55da346c..3809f780 100644 --- a/example/lib/customize_channel_preview.dart +++ b/example/lib/customize_channel_preview.dart @@ -59,7 +59,7 @@ class ChannelListPage extends StatelessWidget { filter: { 'members': { '\$in': [StreamChat.of(context).user.id], - }, + } }, channelPreviewBuilder: _channelPreviewBuilder, sort: [SortOption('last_message_at')], @@ -73,17 +73,18 @@ class ChannelListPage extends StatelessWidget { } Widget _channelPreviewBuilder(BuildContext context, Channel channel) { - final lastMessage = channel.state.messages.reversed.firstWhere( - (message) => message.type != 'deleted', - orElse: () => null, - ); + final lastMessage = channel.state.messages.reversed + .firstWhere((message) => !message.isDeleted); - final subtitle = (lastMessage == null ? 'nothing yet' : lastMessage.text); + final subtitle = (lastMessage == null ? "nothing yet" : lastMessage.text); final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5; return ListTile( - leading: ChannelImage(), + leading: ChannelImage( + channel: channel, + ), title: ChannelName( + channel: channel, textStyle: StreamChatTheme.of(context).channelPreviewTheme.title.copyWith( color: Colors.black.withOpacity(opacity), diff --git a/example/lib/customize_message_widget.dart b/example/lib/customize_message_widget.dart index c963f7ba..fc614125 100644 --- a/example/lib/customize_message_widget.dart +++ b/example/lib/customize_message_widget.dart @@ -98,6 +98,9 @@ class ChannelPage extends StatelessWidget { ) { final message = details.message; final color = details.isMyMessage ? Colors.blueGrey : Colors.blue; + if (message.isSystem) { + return SizedBox(); + } return MessageWidget( message: message, messageTheme: details.isMyMessage diff --git a/example/lib/multiple_conversation.dart b/example/lib/multiple_conversation.dart index 17646bd3..647ae7dd 100644 --- a/example/lib/multiple_conversation.dart +++ b/example/lib/multiple_conversation.dart @@ -44,9 +44,7 @@ class MyApp extends StatelessWidget { client: client, child: child, ), - home: Container( - child: ChannelListPage(), - ), + home: ChannelListPage(), ); } } diff --git a/lib/src/channel_header.dart b/lib/src/channel_header.dart index 26668697..5a7a146c 100644 --- a/lib/src/channel_header.dart +++ b/lib/src/channel_header.dart @@ -157,6 +157,9 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget { child: Icon( Icons.arrow_back_ios, size: 15, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, ), ), ); diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index ddf43239..31a986ce 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -172,11 +172,7 @@ class ChannelPreview extends StatelessWidget { stream: channel.state.messagesStream, initialData: channel.state.messages, builder: (context, snapshot) { - final messages = snapshot.data; - final lastMessage = messages?.isNotEmpty == true - ? messages.lastWhere((m) => - !(m.isDeleted && m.status == MessageSendingStatus.FAILED)) - : null; + final lastMessage = channel.state.lastMessage; if (lastMessage == null) { return SizedBox(); } diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 9926aa8e..6358e39e 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -161,6 +161,7 @@ class MessageInputState extends State { final _focusNode = FocusNode(); final List _mentionedUsers = []; + final _imagePicker = ImagePicker(); bool _inputEnabled = true; bool _messageIsPresent = false; bool _typingStarted = false; @@ -721,11 +722,13 @@ class MessageInputState extends State { } if (camera) { + PickedFile pickedFile; if (fileType == DefaultAttachmentTypes.image) { - file = await ImagePicker.pickImage(source: ImageSource.camera); + pickedFile = await _imagePicker.getImage(source: ImageSource.camera); } else if (fileType == DefaultAttachmentTypes.video) { - file = await ImagePicker.pickVideo(source: ImageSource.camera); + pickedFile = await _imagePicker.getVideo(source: ImageSource.camera); } + file = File(pickedFile.path); } else { FileType type; if (fileType == DefaultAttachmentTypes.image) { diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 306e830b..14c8e20b 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -424,14 +424,14 @@ class _MessageListViewState extends State { final isNextUser = index - 1 >= 0 && message.user.id == messages[index - 1]?.user?.id; - var channel = StreamChannel.of(context).channel; - final readList = channel.state.read - .where((element) => element.user.id != userId) - .where((read) => + final channel = StreamChannel.of(context).channel; + final readList = channel.state?.read + ?.where((element) => element.user.id != userId) + ?.where((read) => read.lastRead.isAfter(message.createdAt) && (index == 0 || read.lastRead.isBefore(messages[index - 1].createdAt))) - .toList(); + ?.toList(); final allRead = readList.length == channel.memberCount - 1; @@ -449,7 +449,7 @@ class _MessageListViewState extends State { (index == 0 || message.status != MessageSendingStatus.SENT) ? DisplayWidget.show : DisplayWidget.hide, - showTimestamp: !isNextUser || readList.isNotEmpty, + showTimestamp: !isNextUser || readList?.isNotEmpty == true, showEditMessage: isMyMessage, showDeleteMessage: isMyMessage, borderSide: isMyMessage ? BorderSide.none : null, diff --git a/pubspec.yaml b/pubspec.yaml index dfc3fbcd..50af3113 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,9 @@ 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: 0.2.1-alpha+9 +version: 0.2.1+2 +repository: https://github.com/GetStream/stream-chat-flutter +issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues environment: sdk: ">=2.3.0 <3.0.0" @@ -14,14 +16,14 @@ dependencies: jiffy: ^3.0.1 flutter_portal: ^0.1.0 cached_network_image: ^2.2.0+1 - flutter_markdown: ^0.4.1 - url_launcher: ^5.4.10 + flutter_markdown: ^0.4.2 + url_launcher: ^5.4.11 video_player: ^0.10.11+1 chewie: ^0.9.10 - file_picker: ^1.9.0+1 - image_picker: ^0.6.7 - flutter_keyboard_visibility: ^3.0.0 - stream_chat: ^0.2.0-alpha+20 + file_picker: ^1.12.0 + image_picker: ^0.6.7+2 + flutter_keyboard_visibility: ^3.2.1 + stream_chat: ^0.2.0+2 mime: ^0.9.6+3 visibility_detector: ^0.1.5 line_awesome_icons: ^1.0.4+2