From ebbf174e57d4f863d3b73f4d3169e6485d946b98 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 3 Aug 2020 15:38:40 +0200 Subject: [PATCH 1/8] add splitview example fixing components --- example/lib/split_view.dart | 139 ++++++++++++++++++++++++++++++ example/pubspec.yaml | 2 +- lib/src/message_widget.dart | 165 +++++++++++++++++------------------- 3 files changed, 218 insertions(+), 88 deletions(-) create mode 100644 example/lib/split_view.dart diff --git a/example/lib/split_view.dart b/example/lib/split_view.dart new file mode 100644 index 00000000..f99e69fc --- /dev/null +++ b/example/lib/split_view.dart @@ -0,0 +1,139 @@ +import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +void main() async { + final client = Client( + 's2dxdhpxd94g', + logLevel: Level.INFO, + ); + + await client.setUser( + User(id: 'super-band-9'), + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A', + ); + + runApp(MyApp(client)); +} + +class MyApp extends StatelessWidget { + final Client client; + + MyApp(this.client); + + @override + Widget build(BuildContext context) { + return MaterialApp( + builder: (context, child) => StreamChat( + child: child, + client: client, + ), + home: SplitView(), + ); + } +} + +class SplitView extends StatefulWidget { + @override + _SplitViewState createState() => _SplitViewState(); +} + +class _SplitViewState extends State { + Channel selectedChannel; + + @override + Widget build(BuildContext context) { + return Flex( + direction: Axis.horizontal, + children: [ + Flexible( + child: ChannelListPage( + onTap: (channel) { + setState(() { + selectedChannel = channel; + }); + }, + ), + flex: 1, + ), + Flexible( + child: Scaffold( + body: selectedChannel != null + ? StreamChannel( + key: ValueKey(selectedChannel.cid), + child: ChannelPage(), + channel: selectedChannel, + ) + : Center( + child: Text( + 'Pick a channel to show the messages 💬', + style: Theme.of(context).textTheme.headline5, + ), + ), + ), + flex: 2, + ), + ], + ); + } +} + +class ChannelListPage extends StatelessWidget { + final void Function(Channel) onTap; + + ChannelListPage({this.onTap}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: ChannelsBloc( + child: ChannelListView( + onChannelTap: onTap != null + ? (channel, _) { + onTap(channel); + } + : null, + filter: { + 'members': { + '\$in': [StreamChat.of(context).user.id], + } + }, + sort: [SortOption('last_message_at')], + pagination: PaginationParams( + limit: 20, + ), + ), + ), + ); + } +} + +class ChannelPage extends StatelessWidget { + const ChannelPage({ + Key key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Navigator( + onGenerateRoute: (settings) { + return MaterialPageRoute( + builder: (context) { + return Scaffold( + appBar: ChannelHeader( + showBackButton: false, + ), + body: Column( + children: [ + Expanded( + child: MessageListView(), + ), + MessageInput(), + ], + ), + ); + }, + ); + }, + ); + } +} diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 266926c8..3f3837b4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,7 +1,7 @@ name: example description: A new Flutter project. -version: 1.0.0+1 +version: 1.0.1+2 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_widget.dart b/lib/src/message_widget.dart index 3294ab17..fc6aecf2 100644 --- a/lib/src/message_widget.dart +++ b/lib/src/message_widget.dart @@ -212,100 +212,91 @@ class _MessageWidgetState extends State { child: Transform( alignment: Alignment.center, transform: Matrix4.rotationY(widget.reverse ? pi : 0), - child: Container( + child: FractionallySizedBox( alignment: Alignment.centerLeft, - child: Container( - constraints: BoxConstraints.loose( - Size.fromWidth(MediaQuery.of(context).size.width * 0.8), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - IntrinsicWidth( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + widthFactor: 0.75, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.showSendingIndicator == - DisplayWidget.show) - _buildSendingIndicator(), - SizedBox( - width: 2, + if (widget.showSendingIndicator == DisplayWidget.show) + _buildSendingIndicator(), + SizedBox( + width: 2, + ), + if (widget.showSendingIndicator == DisplayWidget.hide) + SizedBox( + width: 8, + ), + if (widget.showUserAvatar == DisplayWidget.show) + _buildUserAvatar(), + SizedBox( + width: 6, + ), + if (widget.showUserAvatar == DisplayWidget.hide) + SizedBox( + width: widget.messageTheme.avatarTheme.constraints + .maxWidth + + 8, + ), + Flexible( + child: Padding( + padding: widget.showReactions + ? EdgeInsets.only( + top: _reactionPadding, + ) + : EdgeInsets.zero, + child: PortalEntry( + portalAnchor: Alignment(0, 1), + childAnchor: Alignment.topRight, + portal: _buildReactionIndicator(context), + child: (widget.message.isDeleted && + widget.message.status != + MessageSendingStatus.FAILED_DELETE) + ? Transform( + alignment: Alignment.center, + transform: Matrix4.rotationY( + widget.reverse ? pi : 0), + child: DeletedMessage( + messageTheme: widget.messageTheme, + ), + ) + : Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + ..._parseAttachments(context), + if (widget.message.text + .trim() + .isNotEmpty) + _buildTextBubble(context), + ], + ), ), - if (widget.showSendingIndicator == - DisplayWidget.hide) - SizedBox( - width: 8, - ), - if (widget.showUserAvatar == DisplayWidget.show) - _buildUserAvatar(), - SizedBox( - width: 6, - ), - if (widget.showUserAvatar == DisplayWidget.hide) - SizedBox( - width: widget.messageTheme.avatarTheme - .constraints.maxWidth + - 8, - ), - Flexible( - child: Padding( - padding: widget.showReactions - ? EdgeInsets.only( - top: _reactionPadding, - ) - : EdgeInsets.zero, - child: PortalEntry( - portalAnchor: Alignment(0, 1), - childAnchor: Alignment.topRight, - portal: _buildReactionIndicator(context), - child: (widget.message.isDeleted && - widget.message.status != - MessageSendingStatus - .FAILED_DELETE) - ? Transform( - alignment: Alignment.center, - transform: Matrix4.rotationY( - widget.reverse ? pi : 0), - child: DeletedMessage( - messageTheme: widget.messageTheme, - ), - ) - : Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - ..._parseAttachments(context), - if (widget.message.text - .trim() - .isNotEmpty) - _buildTextBubble(context), - ], - ), - ), - ), - ), - ], + ), ), - if (widget.showReplyIndicator && - widget.message.replyCount > 0) - _buildReplyIndicator(leftPadding), ], ), - ), - if ((widget.message.createdAt != null && - widget.showTimestamp) || - widget.showUsername || - widget.readList?.isNotEmpty == true) - _buildBottomRow(leftPadding), - ], - ), + if (widget.showReplyIndicator && + widget.message.replyCount > 0) + _buildReplyIndicator(leftPadding), + ], + ), + if ((widget.message.createdAt != null && + widget.showTimestamp) || + widget.showUsername || + widget.readList?.isNotEmpty == true) + _buildBottomRow(leftPadding), + ], ), ), ), From 84af372179aa964acd65b9570221c8dc3e537c6d Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 3 Aug 2020 15:53:55 +0200 Subject: [PATCH 2/8] bump version --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db3a916..0e6f08fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.2+1 + +- Fix some components to implement a splitview example + ## 0.2.2 - Add `messageLinks` property to `MessageTheme` to customize links color diff --git a/pubspec.yaml b/pubspec.yaml index 73787a0d..135a7a00 100644 --- a/pubspec.yaml +++ b/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: 0.2.2 +version: 0.2.2+1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues From 40bf12a922f6657ffd4344e98cdf3b15b94a369e Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 5 Aug 2020 09:36:16 +0200 Subject: [PATCH 3/8] add channel to view if new message arrives and the channel is hidden --- lib/src/channel_list_view.dart | 1 + lib/src/channels_bloc.dart | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 782dd772..61b557b6 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -377,6 +377,7 @@ class _ChannelListViewState extends State .on( EventType.connectionRecovered, EventType.notificationAddedToChannel, + EventType.notificationMessageNew, EventType.channelVisible, ) .listen((event) { diff --git a/lib/src/channels_bloc.dart b/lib/src/channels_bloc.dart index b38c6030..6d230faa 100644 --- a/lib/src/channels_bloc.dart +++ b/lib/src/channels_bloc.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:rxdart/rxdart.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/stream_chat.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Widget dedicated to the management of a channel list with pagination class ChannelsBloc extends StatefulWidget { @@ -58,6 +59,8 @@ class ChannelsBlocState extends State Stream get queryChannelsLoading => _queryChannelsLoadingController.stream; + List _hiddenChannels = []; + /// Calls [client.queryChannels] updating [queryChannelsLoading] stream Future queryChannels({ Map filter, @@ -119,6 +122,23 @@ class ChannelsBlocState extends State final channel = newChannels.removeAt(index); newChannels.insert(0, channel); _channelsController.add(newChannels); + } else { + final hiddenIndex = _hiddenChannels.indexWhere((c) => c.cid == e.cid); + if (hiddenIndex > -1) { + newChannels.insert(0, _hiddenChannels[hiddenIndex]); + _hiddenChannels.removeAt(hiddenIndex); + _channelsController.add(newChannels); + } + } + })); + + _subscriptions.add(client.on(EventType.channelHidden).listen((event) async { + final newChannels = List.from(channels); + final channelIndex = newChannels.indexWhere((c) => c.cid == event.cid); + if (channelIndex > -1) { + final channel = newChannels.removeAt(channelIndex); + _hiddenChannels.add(channel); + _channelsController.add(newChannels); } })); From fdaf15a8955c77d6be6dc87c0870ea20cecd755e Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 5 Aug 2020 09:48:10 +0200 Subject: [PATCH 4/8] bump version --- CHANGELOG.md | 6 ++++++ pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e6f08fa..8ed8a878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.2+2 + +- Fix `ChannelListView` channel hidden behaviour + +- Refresh `ChannelListView` on new message from hidden channel + ## 0.2.2+1 - Fix some components to implement a splitview example diff --git a/pubspec.yaml b/pubspec.yaml index 135a7a00..46622bf7 100644 --- a/pubspec.yaml +++ b/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: 0.2.2+1 +version: 0.2.2+2 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues From cdd968f39f0bc4be8d6da8be89c6f73a96377453 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 5 Aug 2020 10:48:43 +0200 Subject: [PATCH 5/8] update dependencies --- CHANGELOG.md | 2 +- pubspec.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ed8a878..2e974cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.2.2+2 +## 0.2.2+3 - Fix `ChannelListView` channel hidden behaviour diff --git a/pubspec.yaml b/pubspec.yaml index 46622bf7..c7ac4ce6 100644 --- a/pubspec.yaml +++ b/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: 0.2.2+2 +version: 0.2.2+3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -23,7 +23,7 @@ dependencies: file_picker: ^1.12.0 image_picker: ^0.6.7+2 flutter_keyboard_visibility: ^3.2.1 - stream_chat: ^0.2.1 + stream_chat: ^0.2.2 mime: ^0.9.6+3 visibility_detector: ^0.1.5 http_parser: ^3.1.4 From 42ed371d484529a778a3b7a21be04ea42315c036 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 7 Aug 2020 15:58:52 +0200 Subject: [PATCH 6/8] add lockChannelsOrder property to channelsBloc --- lib/src/channels_bloc.dart | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/src/channels_bloc.dart b/lib/src/channels_bloc.dart index 6d230faa..e2cf9cd9 100644 --- a/lib/src/channels_bloc.dart +++ b/lib/src/channels_bloc.dart @@ -11,10 +11,14 @@ class ChannelsBloc extends StatefulWidget { /// The widget child final Widget child; + /// Set this to false to prevent channels to be brought to the top of the list when a new message arrives + final bool lockChannelsOrder; + /// Instantiate a new ChannelsBloc const ChannelsBloc({ Key key, this.child, + this.lockChannelsOrder = false, }) : super(key: key); @override @@ -59,7 +63,7 @@ class ChannelsBlocState extends State Stream get queryChannelsLoading => _queryChannelsLoadingController.stream; - List _hiddenChannels = []; + final List _hiddenChannels = []; /// Calls [client.queryChannels] updating [queryChannelsLoading] stream Future queryChannels({ @@ -115,22 +119,24 @@ class ChannelsBlocState extends State final client = StreamChat.of(context).client; - _subscriptions.add(client.on(EventType.messageNew).listen((e) { - final newChannels = List.from(channels ?? []); - final index = newChannels.indexWhere((c) => c.cid == e.cid); - if (index > 0) { - final channel = newChannels.removeAt(index); - newChannels.insert(0, channel); - _channelsController.add(newChannels); - } else { - final hiddenIndex = _hiddenChannels.indexWhere((c) => c.cid == e.cid); - if (hiddenIndex > -1) { - newChannels.insert(0, _hiddenChannels[hiddenIndex]); - _hiddenChannels.removeAt(hiddenIndex); + if (!widget.lockChannelsOrder) { + _subscriptions.add(client.on(EventType.messageNew).listen((e) { + final newChannels = List.from(channels ?? []); + final index = newChannels.indexWhere((c) => c.cid == e.cid); + if (index > 0) { + final channel = newChannels.removeAt(index); + newChannels.insert(0, channel); _channelsController.add(newChannels); + } else { + final hiddenIndex = _hiddenChannels.indexWhere((c) => c.cid == e.cid); + if (hiddenIndex > -1) { + newChannels.insert(0, _hiddenChannels[hiddenIndex]); + _hiddenChannels.removeAt(hiddenIndex); + _channelsController.add(newChannels); + } } - } - })); + })); + } _subscriptions.add(client.on(EventType.channelHidden).listen((event) async { final newChannels = List.from(channels); From 00f22d98bef543503e0a8e23b167137202369060 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 7 Aug 2020 16:02:15 +0200 Subject: [PATCH 7/8] bump version --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e974cf7..911e4ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.3 + +- Add `lockChannelsOrder` parameter to `ChannelsBloc` + ## 0.2.2+3 - Fix `ChannelListView` channel hidden behaviour diff --git a/pubspec.yaml b/pubspec.yaml index c7ac4ce6..46f52748 100644 --- a/pubspec.yaml +++ b/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: 0.2.2+3 +version: 0.2.3 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues From 1fab8a7916d2287147a197c55ee1c881fb1f7e3b Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 21 Aug 2020 15:04:44 +0200 Subject: [PATCH 8/8] bump version --- CHANGELOG.md | 4 ++++ pubspec.yaml | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 911e4ba3..cc19a470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.4 + +- Update llc dependency + ## 0.2.3 - Add `lockChannelsOrder` parameter to `ChannelsBloc` diff --git a/pubspec.yaml b/pubspec.yaml index 46f52748..75f239f3 100644 --- a/pubspec.yaml +++ b/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: 0.2.3 +version: 0.2.4 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues @@ -11,7 +11,7 @@ environment: dependencies: flutter: sdk: flutter - photo_view: ^0.9.2 + photo_view: ^0.10.1 rxdart: ^0.24.1 jiffy: ^3.0.1 flutter_portal: ^0.1.0 @@ -23,7 +23,7 @@ dependencies: file_picker: ^1.12.0 image_picker: ^0.6.7+2 flutter_keyboard_visibility: ^3.2.1 - stream_chat: ^0.2.2 + stream_chat: ^0.2.3 mime: ^0.9.6+3 visibility_detector: ^0.1.5 http_parser: ^3.1.4