diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/channels_bloc.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/channels_bloc.mdx deleted file mode 100644 index 3cb1728a..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/channels_bloc.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: channels_bloc -sidebar_position: 7 -title: ChannelsBloc ---- - -A Widget Dedicated To The Management Of A Channel List With Pagination. - -### Background - -Most widgets in the Core SDK are focused on fetching a particular type of object from Stream Chat - channels, -messages, users, etc. The BLoC widgets bundle up the base functions used to fetch data as well as the current -data fetched by the respective functions. Furthermore, the Core widgets use this BLoC to fetch new or -existing data and build UI based on it. - -All Core and UI widgets which focus on fetching a list of objects need to have their respective functions -above them in the widget tree. The ChannelListCore and ChannelListView require the ChannelsBloc -above them in the widget hierarchy without which they will fail. - -### Understanding The Widget - -`ChannelsBloc` is used together with `ChannelListCore` to manage a list of -Channels with pagination, re-ordering, querying and other operations -associated with Channels. - -`ChannelsBloc` can be accessed at anytime by using the static `.of` method -using Flutter's `BuildContext`. - -```dart -var _channelsBloc = ChannelsBloc.of(context); -``` - -The `ChannelsBloc` widget encapsulates common functionality related to channel lists such as fetching -the existing channels and querying new channels and also supplies them down the widget tree. - -The widget is required for the respective core widget (`ChannelListCore`) to fetch channels and hence -must be above the core widget in the tree. - -Here is a basic implementation of `ChannelsBloc`: - -```dart -ChannelsBloc( - child: // Further Widget Tree -), -``` - -The `ChannelsBloc` widget allows three customisations: - -#### Lock Channels Order - -ChannelsBloc may change the order of channels when new messages arrive. To lock this order, we can -set the `lockChannelsOrder` property to true. - -```dart -ChannelsBloc( - lockChannelsOrder: true, - child: // Further Widget Tree -), -``` - -#### Set custom channel order - -We can decide the order of the channels in the list by supplying a comparator to the `channelsComparator` -parameter: - -```dart -ChannelsBloc( - channelsComparator: (a, b) { - return a.createdAt!.millisecondsSinceEpoch > - b.createdAt!.millisecondsSinceEpoch - ? 1 - : -1; - }, - child: // Further Widget Tree -), -``` - -#### Decide if channel should be added on new message event - -When a new message arrives, a `message.new` event is received. We can decide if we want to add the channel -to the list using the `shouldAddChannel` parameter which is a callback supplying the event data: - -```dart -ChannelsBloc( - shouldAddChannel: (event) { - return event.message!.extraData['priority'] == '1'; - }, - child: // Further Widget Tree -), -``` \ No newline at end of file diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_bloc.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_bloc.mdx deleted file mode 100644 index 15f5a6d6..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_bloc.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: message_search_list_block -sidebar_position: 8 -title: MessageSearchListBloc ---- - -A Widget Used To Manage A List Of Messages With Pagination. - -### Background - -Most widgets in the Core SDK are focused on fetching a particular type of object from Stream Chat - channels, -messages, users etc. The BLoC widgets bundle up the base functions used to fetch data as well as the current -data fetched by the respective functions. Furthermore, the Core widgets use this BLoC to fetch new or -existing data and build UI based on it. - -All Core and UI widgets which focus on fetching a list of objects need to have their respective functions -above them in the widget tree. The MessageSearchListCore and MessageSearchListView require the -MessageSearchListCore above them in the widget hierarchy without which they will fail. - -### Understanding The Widget - -This class can be used to load messages, perform queries, etc. - -`MessageSearchBloc` can be accessed at anytime by using the static `.of` method -using Flutter's BuildContext. - -```dart -var _searchBloc = MessageSearchBloc.of(context); -``` - -The `MessageSearchBloc` widget encapsulates common functionality related to searching for messages -across channels and also supplies them down the widget tree. - -Here is a basic implementation of `ChannelsBloc`: - -```dart -MessageSearchBloc( - child: // Further Widget Tree -), -``` \ No newline at end of file diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_list_core.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_list_core.mdx deleted file mode 100644 index f3be5e85..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/message_search_list_core.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -id: message_search_list_core -sidebar_position: 6 -title: MessageSearchListCore ---- - -A Widget For Displaying Message Searches - -### Background - -The UI SDK of Stream Chat supplies a `MessageSearchListView` class that builds a list of channels fetching -according to the filters and sort order given. However, in some cases, implementing novel UI is necessary -that cannot be done using the customization approaches given in the widget. - -To do this, we extracted the logic required for fetching channels into a 'Core' widget - a widget that -fetches channels in the expected way via the usual params but does not supply any UI and instead -exposes builders to build the UI in situations such as loading, empty data, errors, and on data received. - -### Basic Example - -`MessageSearchListCore` is a simplified class that allows searching for - messages across channels while exposing UI builders. - A `MessageSearchListController` is used to load and paginate data. - -```dart -class MessageSearchPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: MessageSearchListCore( - messageQuery: _messageFilter, - filters: _channelsFilter, - limit: 20, - ), - ); - } -} -``` - -Make sure to have a `MessageSearchBloc` ancestor in order to provide the -information about the messages. \ No newline at end of file diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_input_controller.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_input_controller.mdx new file mode 100644 index 00000000..4da94fbe --- /dev/null +++ b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_input_controller.mdx @@ -0,0 +1,87 @@ +--- +id: stream_message_input_controller +sidebar_position: 4 +title: StreamMessageInputController +--- + +A Widget For Controlling A Message Input + +### Background + +The `StreamMessageInputController` is a controller class that embed the business logic to compose a message. +`StreamMessageInputController` is a parameter of the `StreamMessageInput` widget. +Check the [`StreamMessageInput` documentation](../stream_chat_flutter/stream_message_input.mdx) to read more about that. + +### Basic Example + +Building a custom message input is a common task. Here is an example of how to use the `StreamMessageInputController` to build a simple custom message input widget. + +First of all we should create an instance of the `StreamMessageInputController`. + +```dart +class MessageScreenState extends State { + final StreamMessageInputController messageInputController = StreamMessageInputController(); +``` + +Make sure you call `messageInputController.dispose()` when the controller is no longer required. + +```dart +@override +void dispose() { + messageInputController.dispose(); + super.dispose(); +} +``` + +The `StreamMessageInputController` is basically a `ValueNotifier` that notifies you when the message being composed has changed. +You can use a `ValueListenableBuilder` to build your UI depending on the latest message. +For a very simple message input you could even pass the `messageInputController.textEditingController` to your `TextField` and set the `onChanged` callback. + +```dart +... +Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + Expanded( + child: TextField( + controller: messageInputController.textEditingController, + onChanged: (s) => messageInputController.text = s, + decoration: const InputDecoration( + hintText: 'Enter your message', + ), + ), + ), + Material( + type: MaterialType.circle, + color: Colors.blue, + clipBehavior: Clip.hardEdge, + child: InkWell( + onTap: () async { + if (messageInputController.message.text?.isNotEmpty == + true) { + await channel.sendMessage( + messageInputController.message, + ); + messageInputController.clear(); + if (mounted) { + _updateList(); + } + } + }, + child: const Padding( + padding: EdgeInsets.all(8), + child: Center( + child: Icon( + Icons.send, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), +), +... +``` diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_search_list_controller.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_search_list_controller.mdx index 1caf4504..c854808b 100644 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_search_list_controller.mdx +++ b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_message_search_list_controller.mdx @@ -1,6 +1,6 @@ --- id: stream_message_search_list_controller -sidebar_position: 5 +sidebar_position: 6 title: StreamMessageSearchListController --- @@ -20,7 +20,7 @@ First of all we should create an instance of the `StreamMessageSearchListControl You can also add a `Filter`, a list of `SortOption`s and other pagination-related parameters. ```dart -class SearchListPage extends State { +class SearchListPageState extends State { /// Controller used for loading more data and controlling pagination in /// [StreamMessageSearchListController]. late final messageSearchListController = StreamMessageSearchListController( diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_user_list_controller.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_user_list_controller.mdx index dc394416..6a035540 100644 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_user_list_controller.mdx +++ b/docusaurus/docs/Flutter/stream_chat_flutter_core/stream_user_list_controller.mdx @@ -20,7 +20,7 @@ First of all we should create an instance of the `StreamUserListController` and You can also add a `Filter`, a list of `SortOption`s and other pagination-related parameters. ```dart -class UserListPageState extends State { +class UserListPageState extends State { /// Controller used for loading more data and controlling pagination in /// [StreamUserListController]. late final userListController = StreamUserListController( diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/user_list_core.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/user_list_core.mdx deleted file mode 100644 index 622d0025..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/user_list_core.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -id: user_list_core -sidebar_position: 10 -title: UserListCore ---- - -A Widget For Building A List Of Users - -### Background - -The UI SDK of Stream Chat supplies a `UserListView` class that builds a list of channels fetching -according to the filters and sort order given. However, in some cases, implementing novel UI is necessary -that cannot be done using the customization approaches given in the widget. - -To do this, we extracted the logic required for fetching channels into a 'Core' widget - a widget that -fetches channels in the expected way via the usual params but does not supply any UI and instead -exposes builders to build the UI in situations such as loading, empty data, errors, and on data received. - -### Basic Example - -`UserListCore` is a simplified class that allows fetching users while -exposing UI builders. -A `UserListController` is used to load and paginate data. - -```dart -class UsersListPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: UsersListCore( - sort: [SortOption('last_active')], - pagination: PaginationParams( - limit: 20, - ), - errorBuilder: (err) { - return Center( - child: Text('An error has occured'), - ); - }, - emptyBuilder: (context) { - return Center( - child: Text('Nothing here...'), - ); - }, - emptyBuilder: (context) { - return Center( - child: CircularProgressIndicator(), - ); - }, - listBuilder: (context, list) { - return UsersPage(list); - } - ), - ); - } -} -``` - -`UsersBloc` must be the ancestor of this widget. This is necessary since -`UserListCore` depends on functionality contained within `UsersBloc`. - -The parameters `listBuilder`, `loadingBuilder`, `emptyBuilder` and -`errorBuilder` must all be supplied and not null. - diff --git a/docusaurus/docs/Flutter/stream_chat_flutter_core/users_bloc.mdx b/docusaurus/docs/Flutter/stream_chat_flutter_core/users_bloc.mdx deleted file mode 100644 index 61463599..00000000 --- a/docusaurus/docs/Flutter/stream_chat_flutter_core/users_bloc.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -id: users_bloc -sidebar_position: 9 -title: UsersBloc ---- - -A Widget Dedicated To The Management Of A Users List With Pagination. - -### Background - -Most widgets in the Core SDK are focused on fetching a particular type of object from Stream Chat - channels, -messages, users, etc. The BLoC widgets bundle up the base functions used to fetch data as well as the current -data fetched by the respective functions. Furthermore, the Core widgets use this BLoC to fetch new or -existing data and build UI based on it. - -All Core and UI widgets which focus on fetching a list of objects need to have their respective functions -above them in the widget tree. The UserListCore and UserListView require the UserListCore -above them in the widget hierarchy without which they will fail. - -### Understanding The Widget - -`UsersBloc` can be accessed at anytime by using the static `.of` method -using Flutter's `BuildContext`. - -```dart -var _userBloc_ = UsersBloc.of(context); -``` - -The `UsersBloc` widget encapsulates common functionality related to user lists and also supplies them down the widget tree. - -Here is a basic implementation of `UsersBloc`: - -```dart -UsersBloc( - child: // Further Widget Tree -), -``` \ No newline at end of file diff --git a/packages/stream_chat_flutter_core/example/ios/Flutter/AppFrameworkInfo.plist b/packages/stream_chat_flutter_core/example/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f78..f2872cf4 100644 --- a/packages/stream_chat_flutter_core/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/stream_chat_flutter_core/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 9.0 diff --git a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.pbxproj b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.pbxproj index 26de6f3b..b55c0437 100644 --- a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.pbxproj @@ -139,6 +139,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + EDC4CAB19281E65D2B18E888 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -155,7 +156,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -247,6 +248,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + EDC4CAB19281E65D2B18E888 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16..919434a6 100644 --- a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140cf..3db53b6e 100644 --- a/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/stream_chat_flutter_core/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ { - late final TextEditingController _controller; + final StreamMessageInputController messageInputController = + StreamMessageInputController(); late final ScrollController _scrollController; final messageListController = MessageListController(); @override void initState() { super.initState(); - _controller = TextEditingController(); _scrollController = ScrollController(); } @override void dispose() { - _controller.dispose(); + messageInputController.dispose(); _scrollController.dispose(); super.dispose(); } @@ -319,7 +319,8 @@ class _MessageScreenState extends State { children: [ Expanded( child: TextField( - controller: _controller, + controller: messageInputController.textEditingController, + onChanged: (s) => messageInputController.text = s, decoration: const InputDecoration( hintText: 'Enter your message', ), @@ -331,12 +332,13 @@ class _MessageScreenState extends State { clipBehavior: Clip.hardEdge, child: InkWell( onTap: () async { - if (_controller.value.text.isNotEmpty) { + if (messageInputController.message.text?.isNotEmpty == + true) { await channel.sendMessage( - Message(text: _controller.value.text), + messageInputController.message, ); + messageInputController.clear(); if (mounted) { - _controller.clear(); _updateList(); } }